diff --git a/.betterer.eslint.config.js b/.betterer.eslint.config.js index 1be44601a3c..349ee612837 100644 --- a/.betterer.eslint.config.js +++ b/.betterer.eslint.config.js @@ -113,6 +113,7 @@ module.exports = [ ignores: ['public/app/plugins/**', '**/*.story.tsx', '**/*.{test,spec}.{ts,tsx}', '**/__mocks__/', 'public/test'], rules: { '@grafana/no-untranslated-strings': 'error', + '@grafana/no-translation-top-level': 'error', }, }, ]; diff --git a/.betterer.results b/.betterer.results index fc5e3c214fe..b03dac144aa 100644 --- a/.betterer.results +++ b/.betterer.results @@ -5,6 +5,12 @@ // exports[`better eslint`] = { value: `{ + "apps/dashboard/tshack/v0alpha1_spec_gen.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], + "apps/dashboard/tshack/v1alpha1_spec_gen.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"] + ], "e2e/old-arch/utils/support/types.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], @@ -142,6 +148,14 @@ exports[`better eslint`] = { "packages/grafana-data/src/transformations/standardTransformersRegistry.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], + "packages/grafana-data/src/transformations/transformDataFrame.ts:5381": [ + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"], + [0, 0, 0, "Unexpected any. Specify a different type.", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"] + ], "packages/grafana-data/src/transformations/transformers/nulls/nullInsertThreshold.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -285,6 +299,9 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], + "packages/grafana-data/src/types/scopes.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "packages/grafana-data/src/types/select.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -491,6 +508,9 @@ exports[`better eslint`] = { "packages/grafana-runtime/src/services/pluginExtensions/usePluginExtensions.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], + "packages/grafana-runtime/src/services/pluginExtensions/usePluginFunctions.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "packages/grafana-runtime/src/utils/DataSourceWithBackend.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -515,46 +535,15 @@ exports[`better eslint`] = { "packages/grafana-sql/src/components/visual-query-builder/AwesomeQueryBuilder.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "packages/grafana-ui/src/components/Alert/Alert.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/Card/Card.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "packages/grafana-ui/src/components/Cascader/Cascader.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], "packages/grafana-ui/src/components/ColorPicker/ColorPicker.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "packages/grafana-ui/src/components/ColorPicker/NamedColorsPalette.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/ColorPicker/SeriesColorPickerPopover.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/Combobox/Combobox.tsx:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] - ], "packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "packages/grafana-ui/src/components/Combobox/ValuePill.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "packages/grafana-ui/src/components/ConfirmModal/ConfirmContent.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "packages/grafana-ui/src/components/DataLinks/DataLinkEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] + "packages/grafana-ui/src/components/Combobox/useOptions.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] ], "packages/grafana-ui/src/components/DataLinks/DataLinkInput.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] @@ -562,81 +551,19 @@ exports[`better eslint`] = { "packages/grafana-ui/src/components/DataLinks/DataLinkSuggestions.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksInlineEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "packages/grafana-ui/src/components/DataLinks/DataLinksInlineEditor/DataLinksListItem.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/DataSourceSettings/AlertingSettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/DataSourceSettings/BasicAuthSettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], "packages/grafana-ui/src/components/DataSourceSettings/CustomHeadersSettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"] + [0, 0, 0, "Unexpected any. Specify a different type.", "0"], + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "packages/grafana-ui/src/components/DataSourceSettings/DataSourceHttpSettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "11"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "12"] - ], - "packages/grafana-ui/src/components/DataSourceSettings/HttpProxySettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"] - ], - "packages/grafana-ui/src/components/DataSourceSettings/SecureSocksProxySettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/DataSourceSettings/TLSAuthSettings.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"] + [0, 0, 0, "Do not use the t() function outside of a component or function", "0"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "1"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "2"] ], "packages/grafana-ui/src/components/DataSourceSettings/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], - "packages/grafana-ui/src/components/DateTimePickers/DateTimePicker/DateTimePicker.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "packages/grafana-ui/src/components/DateTimePickers/RelativeTimeRangePicker/RelativeTimeRangePicker.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] - ], "packages/grafana-ui/src/components/FileDropzone/FileDropzone.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -694,16 +621,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], - "packages/grafana-ui/src/components/PageLayout/PageToolbar.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] - ], - "packages/grafana-ui/src/components/Pagination/Pagination.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], "packages/grafana-ui/src/components/PanelChrome/PanelContext.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"] @@ -1003,9 +920,8 @@ exports[`better eslint`] = { "public/app/core/components/AppChrome/MegaMenu/MegaMenuItem.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "public/app/core/components/AppChrome/News/NewsContainer.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] + "public/app/core/components/AppChrome/News/NewsDrawer.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], "public/app/core/components/AppChrome/News/NewsWrapper.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] @@ -1016,10 +932,12 @@ exports[`better eslint`] = { "public/app/core/components/AppChrome/QuickAdd/QuickAdd.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], + "public/app/core/components/AppChrome/TopBar/ProfileButton.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] + ], "public/app/core/components/AppChrome/TopBar/SingleTopBar.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], "public/app/core/components/AppChrome/TopBar/TopSearchBarCommandPaletteTrigger.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/themes/mixins\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] @@ -1194,9 +1112,6 @@ exports[`better eslint`] = { "public/app/core/components/TagFilter/TagOption.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "public/app/core/components/TimePicker/TimePickerWithHistory.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/core/components/TimeSeries/TimeSeries.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/uPlot/PlotLegend\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], [0, 0, 0, "\'@grafana/ui/src/components/uPlot/config/UPlotConfigBuilder\' import is restricted from being used by a pattern. Import from the public export instead.", "1"], @@ -1325,8 +1240,10 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"] + [0, 0, 0, "Do not use any type assertions.", "3"], + [0, 0, 0, "Unexpected any. Specify a different type.", "4"], + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"] ], "public/app/core/utils/richHistory.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -1348,32 +1265,15 @@ exports[`better eslint`] = { [0, 0, 0, "\'@grafana/ui/src/components/Forms/RadioButtonGroup/RadioButtonGroup\' import is restricted from being used by a pattern. Import from the public export instead.", "3"], [0, 0, 0, "\'@grafana/ui/src/components/JSONFormatter/JSONFormatter\' import is restricted from being used by a pattern. Import from the public export instead.", "4"], [0, 0, 0, "\'@grafana/ui/src/themes\' import is restricted from being used by a pattern. Import from the public export instead.", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"], + [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "6"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "11"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "12"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "13"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"] ], "public/app/features/actions/ActionEditorModalContent.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/Button\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], [0, 0, 0, "\'@grafana/ui/src/components/Modal/Modal\' import is restricted from being used by a pattern. Import from the public export instead.", "1"] ], - "public/app/features/actions/ActionsInlineEditor.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Button\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "\'@grafana/ui/src/components/Modal/Modal\' import is restricted from being used by a pattern. Import from the public export instead.", "1"], - [0, 0, 0, "\'@grafana/ui/src/themes\' import is restricted from being used by a pattern. Import from the public export instead.", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] - ], - "public/app/features/actions/ActionsListItem.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Icon/Icon\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "\'@grafana/ui/src/components/IconButton/IconButton\' import is restricted from being used by a pattern. Import from the public export instead.", "1"], - [0, 0, 0, "\'@grafana/ui/src/themes\' import is restricted from being used by a pattern. Import from the public export instead.", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"] - ], "public/app/features/actions/ParamsEditor.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/IconButton/IconButton\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], [0, 0, 0, "\'@grafana/ui/src/components/Input/Input\' import is restricted from being used by a pattern. Import from the public export instead.", "1"], @@ -1558,23 +1458,10 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], [0, 0, 0, "No untranslated strings. Wrap text with ", "4"] ], - "public/app/features/alerting/unified/CloneRuleEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] - ], - "public/app/features/alerting/unified/ExistingRuleEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] - ], "public/app/features/alerting/unified/GrafanaRuleQueryViewer.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/datetime/rangeutil\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], [0, 0, 0, "No untranslated strings. Wrap text with ", "5"], @@ -1587,7 +1474,8 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "12"], [0, 0, 0, "No untranslated strings. Wrap text with ", "13"], [0, 0, 0, "No untranslated strings. Wrap text with ", "14"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "15"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "15"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "16"] ], "public/app/features/alerting/unified/NotificationPoliciesPage.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -1597,9 +1485,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], "public/app/features/alerting/unified/RedirectToRuleViewer.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -1611,24 +1497,12 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], [0, 0, 0, "No untranslated strings. Wrap text with ", "7"] ], - "public/app/features/alerting/unified/RuleEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] - ], - "public/app/features/alerting/unified/RuleViewer.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], "public/app/features/alerting/unified/Settings.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], - "public/app/features/alerting/unified/Templates.test.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Monaco/types\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/alerting/unified/components/AlertLabel.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -1658,10 +1532,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] ], - "public/app/features/alerting/unified/components/InfoPausedRule.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] - ], "public/app/features/alerting/unified/components/InvalidIntervalWarning.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], @@ -1867,9 +1737,6 @@ exports[`better eslint`] = { "public/app/features/alerting/unified/components/extensions/AlertInstanceExtensionPoint.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "public/app/features/alerting/unified/components/extensions/AlertInstanceExtensionPointMenu.tsx:5381": [ - [0, 0, 0, "Do not re-export imported variable (\`app/features/explore/extensions/ToolbarExtensionPointMenu\`)", "0"] - ], "public/app/features/alerting/unified/components/mute-timings/MuteTimingActionsButtons.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] @@ -2040,9 +1907,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "11"], [0, 0, 0, "No untranslated strings. Wrap text with ", "12"] ], - "public/app/features/alerting/unified/components/receivers/TemplateEditor.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Monaco/types\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/alerting/unified/components/receivers/TemplateForm.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], @@ -2127,10 +1991,8 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "6"] ], "public/app/features/alerting/unified/components/receivers/form/fields/KeyValueMapInput.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] ], "public/app/features/alerting/unified/components/receivers/form/fields/OptionField.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], @@ -2161,9 +2023,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], - "public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.test.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Monaco/types\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/alerting/unified/components/receivers/form/fields/TemplateSelector.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], @@ -2258,10 +2117,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "11"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "12"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "13"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "10"] ], "public/app/features/alerting/unified/components/rule-editor/GrafanaFolderAndLabelsStep.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] @@ -2383,6 +2239,9 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "10"], [0, 0, 0, "No untranslated strings. Wrap text with ", "11"] ], + "public/app/features/alerting/unified/components/rule-editor/dag.test.ts:5381": [ + [0, 0, 0, "\'@grafana/runtime/src/utils/DataSourceWithBackend\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] + ], "public/app/features/alerting/unified/components/rule-editor/labels/LabelsButtons.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] @@ -2437,14 +2296,13 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "8"] ], "public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/QueryAndExpressionsStep.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Text/Text\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], [0, 0, 0, "No untranslated strings. Wrap text with ", "5"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "7"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "6"] ], "public/app/features/alerting/unified/components/rule-editor/query-and-alert-condition/SimpleCondition.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] @@ -2501,39 +2359,15 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], "public/app/features/alerting/unified/components/rule-viewer/RuleViewer.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] - ], - "public/app/features/alerting/unified/components/rule-viewer/tabs/Details.tsx:5381": [ - [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "7"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "8"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "9"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "10"] - ], - "public/app/features/alerting/unified/components/rule-viewer/tabs/Query.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "4"] ], "public/app/features/alerting/unified/components/rule-viewer/tabs/Routing.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], - "public/app/features/alerting/unified/components/rules/ActionButton.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Button\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], - "public/app/features/alerting/unified/components/rules/ActionIcon.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Tooltip\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/alerting/unified/components/rules/AlertInstanceDetails.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -2923,14 +2757,30 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Do not use any type assertions.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"], - [0, 0, 0, "Unexpected any. Specify a different type.", "7"], - [0, 0, 0, "Unexpected any. Specify a different type.", "8"] + [0, 0, 0, "Unexpected any. Specify a different type.", "5"] ], "public/app/features/alerting/unified/plugins/PluginOriginBadge.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/Icon/utils\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] ], + "public/app/features/alerting/unified/rule-editor/CloneRuleEditor.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] + ], + "public/app/features/alerting/unified/rule-editor/ExistingRuleEditor.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] + ], + "public/app/features/alerting/unified/rule-editor/RuleEditor.tsx:5381": [ + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] + ], "public/app/features/alerting/unified/rule-list/FilterView.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -2955,11 +2805,8 @@ exports[`better eslint`] = { "public/app/features/alerting/unified/rule-list/components/RuleGroup.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "public/app/features/alerting/unified/rule-list/components/RuleListIcon.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Text/Text\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], - "public/app/features/alerting/unified/state/actions.ts:5381": [ - [0, 0, 0, "\'@grafana/runtime/src/utils/logging\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] + "public/app/features/alerting/unified/state/AlertingQueryRunner.test.ts:5381": [ + [0, 0, 0, "\'@grafana/runtime/src/utils/DataSourceWithBackend\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] ], "public/app/features/alerting/unified/types/receiver-form.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -3183,8 +3030,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"] ], "public/app/features/connections/tabs/ConnectData/ConnectData.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/connections/tabs/ConnectData/NoAccessModal/NoAccessModal.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -3199,7 +3045,8 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"] ], "public/app/features/connections/tabs/ConnectData/Search/Search.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] + [0, 0, 0, "Do not use the t() function outside of a component or function", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], "public/app/features/connections/tabs/ConnectData/Search/index.tsx:5381": [ [0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"] @@ -3234,13 +3081,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], [0, 0, 0, "No untranslated strings. Wrap text with ", "7"] ], - "public/app/features/dashboard-scene/edit-pane/DashboardEditPane.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] - ], - "public/app/features/dashboard-scene/embedding/EmbeddedDashboard.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], "public/app/features/dashboard-scene/embedding/EmbeddedDashboardTestPage.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], @@ -3283,8 +3123,7 @@ exports[`better eslint`] = { "public/app/features/dashboard-scene/pages/DashboardScenePage.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "Unexpected any. Specify a different type.", "3"] + [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/features/dashboard-scene/panel-edit/LibraryVizPanelInfo.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] @@ -3301,7 +3140,7 @@ exports[`better eslint`] = { "public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataAlertingTab.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], "public/app/features/dashboard-scene/panel-edit/PanelDataPane/PanelDataPane.tsx:5381": [ @@ -3415,40 +3254,6 @@ exports[`better eslint`] = { "public/app/features/dashboard-scene/scene/DashboardLinksControls.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/text/sanitize\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] ], - "public/app/features/dashboard-scene/scene/NavToolbarActions.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "7"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "10"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "11"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "12"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "13"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "14"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "15"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "16"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "17"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "18"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "19"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "20"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "21"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "22"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "23"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "24"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "25"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "26"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "27"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "28"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "29"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "30"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "31"] - ], "public/app/features/dashboard-scene/scene/PanelLinks.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -3461,28 +3266,6 @@ exports[`better eslint`] = { "public/app/features/dashboard-scene/scene/UnlinkModal.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], - "public/app/features/dashboard-scene/scene/row-actions/RowActions.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] - ], - "public/app/features/dashboard-scene/scene/row-actions/RowOptionsButton.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "public/app/features/dashboard-scene/scene/row-actions/RowOptionsForm.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] - ], - "public/app/features/dashboard-scene/scene/row-actions/RowOptionsModal.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], - "public/app/features/dashboard-scene/scene/types.ts:5381": [ - [0, 0, 0, "Unexpected any. Specify a different type.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] - ], "public/app/features/dashboard-scene/serialization/angularMigration.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -3503,14 +3286,6 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "7"], [0, 0, 0, "Unexpected any. Specify a different type.", "8"] ], - "public/app/features/dashboard-scene/serialization/transformSceneToSaveModelSchemaV2.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"], - [0, 0, 0, "Do not use any type assertions.", "2"], - [0, 0, 0, "Do not use any type assertions.", "3"], - [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] - ], "public/app/features/dashboard-scene/serialization/transformToV1TypesUtils.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -3742,8 +3517,7 @@ exports[`better eslint`] = { ], "public/app/features/dashboard-scene/sharing/ShareButton/share-snapshot/UpsertSnapshot.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/Input/Input\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], "public/app/features/dashboard-scene/sharing/ShareDrawer/ShareDrawerConfirmAction.tsx:5381": [ [0, 0, 0, "\'@grafana/ui/src/components/ConfirmModal/ConfirmContent\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] @@ -3775,9 +3549,10 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "2"], [0, 0, 0, "Do not use any type assertions.", "3"], [0, 0, 0, "Unexpected any. Specify a different type.", "4"], - [0, 0, 0, "Unexpected any. Specify a different type.", "5"] + [0, 0, 0, "Unexpected any. Specify a different type.", "5"], + [0, 0, 0, "Unexpected any. Specify a different type.", "6"] ], - "public/app/features/dashboard/api/v0.ts:5381": [ + "public/app/features/dashboard/api/v1.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/dashboard/components/AddLibraryPanelWidget/AddLibraryPanelWidget.tsx:5381": [ @@ -4222,6 +3997,9 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] ], + "public/app/features/dashboard/containers/PublicDashboardPage.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/features/dashboard/containers/SoloPanelPage.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] @@ -4240,9 +4018,6 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "1"], [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], - "public/app/features/dashboard/services/TimeSrv.ts:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/dashboard/state/DashboardMigrator.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], [0, 0, 0, "Unexpected any. Specify a different type.", "1"], @@ -4660,13 +4435,9 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "8"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "9"] ], - "public/app/features/explore/ExplorePage.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] - ], "public/app/features/explore/ExploreRunQueryButton.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], "public/app/features/explore/ExploreToolbar.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -4724,10 +4495,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "3"], [0, 0, 0, "No untranslated strings. Wrap text with ", "4"] ], - "public/app/features/explore/Logs/LogsNavigation.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] - ], "public/app/features/explore/Logs/LogsSamplePanel.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], @@ -4803,30 +4570,18 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], - "public/app/features/explore/QueryLibrary/QueryLibraryExpmInfo.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] - ], - "public/app/features/explore/QueryLibrary/QueryTemplateForm.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/components/Input/Input\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], - "public/app/features/explore/QueryLibrary/QueryTemplatesList.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"] - ], - "public/app/features/explore/QueryLibrary/QueryTemplatesTable/QueryDescriptionCell.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] + "public/app/features/explore/RichHistory/RichHistorySettingsTab.tsx:5381": [ + [0, 0, 0, "Do not use the t() function outside of a component or function", "0"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "1"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "2"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "3"] ], "public/app/features/explore/RichHistory/RichHistoryStarredTab.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], + "public/app/features/explore/ShortLinkButtonMenu.tsx:5381": [ + [0, 0, 0, "Do not use the t() function outside of a component or function", "0"] + ], "public/app/features/explore/SupplementaryResultError.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], @@ -5042,9 +4797,7 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use any type assertions.", "1"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"] ], "public/app/features/explore/extensions/ConfirmNavigationModal.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], @@ -5073,9 +4826,6 @@ exports[`better eslint`] = { "public/app/features/explore/state/time.test.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], - "public/app/features/explore/state/time.ts:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/explore/state/utils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -5136,12 +4886,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"] ], "public/app/features/expressions/components/Threshold.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], "public/app/features/expressions/guards.ts:5381": [ [0, 0, 0, "\'@grafana/runtime/src/utils/DataSourceWithBackend\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], @@ -5195,8 +4940,14 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "4"] ], "public/app/features/inspector/InspectJSONTab.tsx:5381": [ - [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] + [0, 0, 0, "Do not use the t() function outside of a component or function", "0"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "1"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "2"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "3"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "4"], + [0, 0, 0, "Do not use the t() function outside of a component or function", "5"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "6"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "7"] ], "public/app/features/inspector/InspectStatsTab.tsx:5381": [ [0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"] @@ -5387,9 +5138,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], - "public/app/features/manage-dashboards/components/PublicDashboardListTable/PublicDashboardListTable.tsx:5381": [ - [0, 0, 0, "\'HorizontalGroup\' import from \'@grafana/ui\' is restricted from being used by a pattern. Use Stack component instead.", "0"] - ], "public/app/features/manage-dashboards/components/SnapshotListTable.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -5581,12 +5329,6 @@ exports[`better eslint`] = { "public/app/features/plugins/admin/components/GetStartedWithPlugin/index.ts:5381": [ [0, 0, 0, "Do not re-export imported variable (\`./GetStartedWithPlugin\`)", "0"] ], - "public/app/features/plugins/admin/components/InstallControls/ExternallyManagedButton.tsx:5381": [ - [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] - ], "public/app/features/plugins/admin/components/InstallControls/InstallControlsButton.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], @@ -5650,7 +5392,8 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] ], "public/app/features/plugins/admin/components/PluginDetailsPanel.tsx:5381": [ - [0, 0, 0, "\'@grafana/runtime/src/components/PluginPage\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] + [0, 0, 0, "\'@grafana/runtime/src/components/PluginPage\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], + [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] ], "public/app/features/plugins/admin/components/PluginDetailsSignature.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], @@ -5751,11 +5494,10 @@ exports[`better eslint`] = { [0, 0, 0, "\'@grafana/data/src/types/pluginExtensions\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] ], "public/app/features/plugins/extensions/usePluginComponents.tsx:5381": [ - [0, 0, 0, "\'@grafana/runtime/src/services/pluginExtensions/getPluginExtensions\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "Do not use any type assertions.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/plugins/extensions/usePluginLinks.tsx:5381": [ - [0, 0, 0, "\'@grafana/runtime/src/services/pluginExtensions/getPluginExtensions\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] + "public/app/features/plugins/extensions/usePluginFunctions.tsx:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/features/plugins/extensions/validators.ts:5381": [ [0, 0, 0, "\'@grafana/data/src/types/pluginExtensions\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] @@ -5806,9 +5548,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], [0, 0, 0, "No untranslated strings. Wrap text with ", "5"] ], - "public/app/features/query-library/api/query.ts:5381": [ - [0, 0, 0, "\'@grafana/runtime/src/services/backendSrv\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/query/components/QueryEditorRow.tsx:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"], [0, 0, 0, "Do not use any type assertions.", "1"], @@ -5943,10 +5682,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], [0, 0, 0, "No untranslated strings. Wrap text with ", "3"] ], - "public/app/features/scopes/index.ts:5381": [ - [0, 0, 0, "Do not re-export imported variable (\`./ScopesDashboards\`)", "0"], - [0, 0, 0, "Do not re-export imported variable (\`./instance\`)", "1"] - ], "public/app/features/search/page/components/ActionRow.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], @@ -5983,9 +5718,6 @@ exports[`better eslint`] = { "public/app/features/search/utils.ts:5381": [ [0, 0, 0, "Do not use any type assertions.", "0"] ], - "public/app/features/serviceaccounts/ServiceAccountCreatePage.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/serviceaccounts/ServiceAccountPage.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], @@ -6186,8 +5918,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] ], "public/app/features/trails/DataTrailSettings.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "0"] ], "public/app/features/trails/DataTrailsHistory.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/datetime/rangeutil\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], @@ -6214,9 +5945,6 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "7"], [0, 0, 0, "No untranslated strings. Wrap text with ", "8"] ], - "public/app/features/trails/MetricSelect/NativeHistogramBadge.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"] - ], "public/app/features/trails/MetricsHeader.tsx:5381": [ [0, 0, 0, "No untranslated strings. Wrap text with ", "0"], [0, 0, 0, "No untranslated strings. Wrap text with ", "1"] @@ -6230,8 +5958,7 @@ exports[`better eslint`] = { [0, 0, 0, "No untranslated strings. Wrap text with ", "2"] ], "public/app/features/trails/banners/NativeHistogramBanner.tsx:5381": [ - [0, 0, 0, "\'@grafana/ui/src/utils/i18n\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], "public/app/features/transformers/FilterByValueTransformer/FilterByValueFilterEditor.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/transformations/transformers/filterByValue\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], @@ -6252,8 +5979,7 @@ exports[`better eslint`] = { ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/BasicMatcherEditor.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "Unexpected any. Specify a different type.", "2"] + [0, 0, 0, "Unexpected any. Specify a different type.", "1"] ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/NoopMatcherEditor.tsx:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] @@ -6261,15 +5987,11 @@ exports[`better eslint`] = { "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RangeMatcherEditor.tsx:5381": [ [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "4"], - [0, 0, 0, "No untranslated strings. Wrap text with ", "5"], - [0, 0, 0, "Unexpected any. Specify a different type.", "6"] + [0, 0, 0, "No untranslated strings. Wrap text with ", "2"], + [0, 0, 0, "Unexpected any. Specify a different type.", "3"] ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/RegexMatcherEditor.tsx:5381": [ - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "0"] ], "public/app/features/transformers/FilterByValueTransformer/ValueMatchers/types.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"], @@ -6452,10 +6174,7 @@ exports[`better eslint`] = { [0, 0, 0, "\'@grafana/data/src/transformations/transformers/histogram\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "4"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "5"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "6"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] ], "public/app/features/transformers/editors/JoinByFieldTransformerEditor.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/transformations/transformers/joinByField\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], @@ -6474,9 +6193,7 @@ exports[`better eslint`] = { ], "public/app/features/transformers/editors/LimitTransformerEditor.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/transformations/transformers/limit\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "2"], - [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "3"] + [0, 0, 0, "No untranslated strings in text props. Wrap text with or use t()", "1"] ], "public/app/features/transformers/editors/MergeTransformerEditor.tsx:5381": [ [0, 0, 0, "\'@grafana/data/src/transformations/transformers/merge\' import is restricted from being used by a pattern. Import from the public export instead.", "0"], @@ -6968,9 +6685,6 @@ exports[`better eslint`] = { [0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"], [0, 0, 0, "Do not use export all (\`export * from ...\`)", "1"] ], - "public/app/plugins/datasource/azuremonitor/azure_monitor/azure_monitor_datasource.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"] - ], "public/app/plugins/datasource/azuremonitor/components/ArgQueryEditor/index.tsx:5381": [ [0, 0, 0, "Do not re-export imported variable (\`./ArgQueryEditor\`)", "0"] ], @@ -7020,6 +6734,9 @@ exports[`better eslint`] = { "public/app/plugins/datasource/azuremonitor/types/templateVariables.ts:5381": [ [0, 0, 0, "Do not re-export imported variable (\`../dataquery.gen\`)", "0"] ], + "public/app/plugins/datasource/azuremonitor/utils/common.ts:5381": [ + [0, 0, 0, "Do not use any type assertions.", "0"] + ], "public/app/plugins/datasource/azuremonitor/utils/messageFromError.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] ], @@ -7582,8 +7299,7 @@ exports[`better eslint`] = { [0, 0, 0, "Unexpected any. Specify a different type.", "2"] ], "public/app/plugins/datasource/zipkin/datasource.ts:5381": [ - [0, 0, 0, "Do not use any type assertions.", "0"], - [0, 0, 0, "Unexpected any. Specify a different type.", "1"] + [0, 0, 0, "Do not use any type assertions.", "0"] ], "public/app/plugins/datasource/zipkin/utils/transforms.ts:5381": [ [0, 0, 0, "Unexpected any. Specify a different type.", "0"] diff --git a/.bingo/Variables.mk b/.bingo/Variables.mk index 56a916a0d25..80b5946b497 100644 --- a/.bingo/Variables.mk +++ b/.bingo/Variables.mk @@ -5,6 +5,10 @@ GOPATH ?= $(shell go env GOPATH) GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin GO ?= $(shell which go) +# Add this near the top of the file, after the initial variable definitions +ifndef VARIABLES_MK +VARIABLES_MK := 1 + # Below generated variables ensure that every time a tool under each variable is invoked, the correct version # will be used; reinstalling only if needed. # For example for bra variable: @@ -65,3 +69,4 @@ $(SWAGGER): $(BINGO_DIR)/swagger.mod @echo "(re)installing $(GOBIN)/swagger-v0.30.6-0.20240310114303-db51e79a0e37" @cd $(BINGO_DIR) && GOWORK=off $(GO) build -mod=mod -modfile=swagger.mod -o=$(GOBIN)/swagger-v0.30.6-0.20240310114303-db51e79a0e37 "github.com/go-swagger/go-swagger/cmd/swagger" +endif diff --git a/.drone.yml b/.drone.yml index f81d8bbbc69..dbcc1662f84 100644 --- a/.drone.yml +++ b/.drone.yml @@ -18,14 +18,14 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - ./bin/build verify-drone @@ -69,13 +69,13 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - go install github.com/bazelbuild/buildtools/buildifier@latest - buildifier --lint=warn -mode=check -r . depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: lint-starlark trigger: event: @@ -112,7 +112,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -170,7 +170,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -179,7 +179,7 @@ steps: name: yarn-install - commands: - apk add --update git bash - - yarn betterer ci + - yarn betterer:ci depends_on: - yarn-install image: node:22.11.0-alpine @@ -309,7 +309,7 @@ steps: path: /github-app - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -339,6 +339,16 @@ steps: - yarn-install image: node:22-bookworm name: verify-i18n +- commands: + - yarn generate-apis + - "\n file_diff=$(git diff ':!conf')\n if [ -n \"$file_diff\" + ]; then\n echo $file_diff\n echo \"\nAPI client + generation has not been committed. Please run 'yarn generate-apis', commit the + changes and push again.\"\n exit 1\n fi\n " + depends_on: + - yarn-install + image: node:22-bookworm + name: verify-api-clients trigger: event: - pull_request @@ -417,7 +427,7 @@ steps: path: /github-app - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -427,7 +437,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -436,21 +446,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend - commands: - apk add --update build-base @@ -459,7 +469,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend-integration trigger: event: @@ -479,6 +489,7 @@ trigger: - public/app/plugins/**/plugin.json - docs/sources/setup-grafana/configure-grafana/feature-toggles/** - devenv/** + - apps/** type: docker volumes: - host: @@ -506,14 +517,14 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - echo $(/usr/bin/github-app-external-token) > /github-app/token @@ -558,16 +569,16 @@ steps: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-openapi-spec trigger: event: @@ -588,6 +599,7 @@ trigger: - public/app/plugins/**/plugin.json - devenv/** - .bingo/** + - apps/** type: docker volumes: - host: @@ -630,11 +642,11 @@ steps: path: /github-app - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -643,7 +655,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -653,7 +665,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -662,7 +674,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - yarn install --immutable || yarn install --immutable @@ -694,12 +706,14 @@ steps: token: from_secret: drone_token - commands: - - docker run --privileged --rm tonistiigi/binfmt --install all + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --version + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu-*' + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 -a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7 - -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.5 --yarn-cache=$$YARN_CACHE_FOLDER - --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.20.3 + -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER + --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3 --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD > packages.txt @@ -756,7 +770,7 @@ steps: GF_APP_MODE: development GF_SERVER_HTTP_PORT: "3001" GF_SERVER_ROUTER_LOGGING: "1" - image: alpine:3.20.3 + image: alpine:3.21.3 name: grafana-server - commands: - ./bin/build e2e-tests --port 3001 --suite dashboards-suite @@ -1087,7 +1101,7 @@ steps: path: /github-app - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -1096,11 +1110,11 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1110,7 +1124,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1119,14 +1133,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -1147,7 +1161,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -1168,7 +1182,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -1184,7 +1198,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -1200,7 +1214,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -1216,7 +1230,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -1266,7 +1280,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -1298,7 +1312,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue trigger: event: @@ -1419,7 +1433,7 @@ steps: && return 1; fi depends_on: - clone-enterprise - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: swagger-gen trigger: event: @@ -1524,7 +1538,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1535,7 +1549,7 @@ steps: - CODEGEN_VERIFY=1 make gen-cue depends_on: - clone-enterprise - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1545,14 +1559,14 @@ steps: - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: - clone-enterprise - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - apk add --update build-base @@ -1560,7 +1574,7 @@ steps: - go test -v -run=^$ -benchmem -timeout=1h -count=8 -bench=. ${GO_PACKAGES} depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: sqlite-benchmark-integration-tests - commands: - apk add --update build-base @@ -1572,7 +1586,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: postgres-benchmark-integration-tests - commands: - apk add --update build-base @@ -1583,7 +1597,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: mysql-8.0-benchmark-integration-tests trigger: event: @@ -1623,7 +1637,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -1655,7 +1669,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue trigger: branch: main @@ -1694,7 +1708,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -1703,7 +1717,7 @@ steps: name: yarn-install - commands: - apk add --update git bash - - yarn betterer ci + - yarn betterer:ci depends_on: - yarn-install image: node:22.11.0-alpine @@ -1752,7 +1766,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -1782,6 +1796,16 @@ steps: - yarn-install image: node:22-bookworm name: verify-i18n +- commands: + - yarn generate-apis + - "\n file_diff=$(git diff ':!conf')\n if [ -n \"$file_diff\" + ]; then\n echo $file_diff\n echo \"\nAPI client + generation has not been committed. Please run 'yarn generate-apis', commit the + changes and push again.\"\n exit 1\n fi\n " + depends_on: + - yarn-install + image: node:22-bookworm + name: verify-api-clients trigger: branch: main event: @@ -1818,7 +1842,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -1828,7 +1852,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -1837,21 +1861,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend - commands: - apk add --update build-base @@ -1860,7 +1884,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend-integration trigger: branch: main @@ -1898,29 +1922,29 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-openapi-spec - commands: - ./bin/build verify-drone @@ -1964,7 +1988,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -2039,11 +2063,11 @@ steps: path: /github-app - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2052,7 +2076,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -2062,7 +2086,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2071,7 +2095,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - yarn install --immutable || yarn install --immutable @@ -2102,12 +2126,14 @@ steps: image: node:22.11.0-alpine name: build-frontend-packages - commands: - - docker run --privileged --rm tonistiigi/binfmt --install all + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --version + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --uninstall 'qemu-*' + - docker run --privileged --rm tonistiigi/binfmt:qemu-v7.0.0-28 --install all - /src/grafana-build artifacts -a targz:grafana:linux/amd64 -a targz:grafana:linux/arm64 -a targz:grafana:linux/arm/v7 -a docker:grafana:linux/amd64 -a docker:grafana:linux/amd64:ubuntu -a docker:grafana:linux/arm64 -a docker:grafana:linux/arm64:ubuntu -a docker:grafana:linux/arm/v7 - -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.5 --yarn-cache=$$YARN_CACHE_FOLDER - --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.20.3 + -a docker:grafana:linux/arm/v7:ubuntu --go-version=1.23.7 --yarn-cache=$$YARN_CACHE_FOLDER + --build-id=$$DRONE_BUILD_NUMBER --ubuntu-base=ubuntu:22.04 --alpine-base=alpine:3.21.3 --tag-format='{{ .version_base }}-{{ .buildID }}-{{ .arch }}' --ubuntu-tag-format='{{ .version_base }}-{{ .buildID }}-ubuntu-{{ .arch }}' --verify='false' --grafana-dir=$$PWD > packages.txt @@ -2168,7 +2194,7 @@ steps: GF_APP_MODE: development GF_SERVER_HTTP_PORT: "3001" GF_SERVER_ROUTER_LOGGING: "1" - image: alpine:3.20.3 + image: alpine:3.21.3 name: grafana-server - commands: - ./bin/build e2e-tests --port 3001 --suite dashboards-suite @@ -2572,7 +2598,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -2581,11 +2607,11 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -2595,7 +2621,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2604,14 +2630,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -2632,7 +2658,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -2653,7 +2679,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -2669,7 +2695,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -2685,7 +2711,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -2701,7 +2727,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: remote-alertmanager-integration-tests trigger: branch: main @@ -2830,7 +2856,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -2839,7 +2865,7 @@ steps: name: yarn-install - commands: - apk add --update git bash - - yarn betterer ci + - yarn betterer:ci depends_on: - yarn-install image: node:22.11.0-alpine @@ -2886,7 +2912,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -2916,6 +2942,16 @@ steps: - yarn-install image: node:22-bookworm name: verify-i18n +- commands: + - yarn generate-apis + - "\n file_diff=$(git diff ':!conf')\n if [ -n \"$file_diff\" + ]; then\n echo $file_diff\n echo \"\nAPI client + generation has not been committed. Please run 'yarn generate-apis', commit the + changes and push again.\"\n exit 1\n fi\n " + depends_on: + - yarn-install + image: node:22-bookworm + name: verify-api-clients trigger: branch: - instant @@ -2950,7 +2986,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -2960,7 +2996,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -2969,21 +3005,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend - commands: - apk add --update build-base @@ -2992,7 +3028,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend-integration trigger: branch: @@ -3028,29 +3064,29 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - apk add --update make - make gen-go depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - go run scripts/modowners/modowners.go check go.mod - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-modfile - commands: - apk add --update make - make swagger-validate - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: validate-openapi-spec trigger: branch: @@ -3120,7 +3156,7 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3129,11 +3165,11 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -3143,7 +3179,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -3152,14 +3188,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -3180,7 +3216,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -3201,7 +3237,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -3217,7 +3253,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -3233,7 +3269,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -3249,7 +3285,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: remote-alertmanager-integration-tests trigger: branch: @@ -3336,11 +3372,11 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3349,7 +3385,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - ./bin/build artifacts docker fetch --edition oss @@ -3468,11 +3504,11 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl @@ -3481,7 +3517,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - ./bin/build artifacts docker fetch --edition oss @@ -3622,7 +3658,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - ./bin/build artifacts packages --artifacts-editions=oss --tag $${DRONE_TAG} --src-bucket @@ -3714,7 +3750,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - yarn install --immutable || yarn install --immutable @@ -3814,7 +3850,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - depends_on: - compile-build-cmd @@ -3911,7 +3947,7 @@ steps: depends_on: [] environment: CGO_ENABLED: 0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: compile-build-cmd - commands: - ./bin/build publish grafana-com --edition oss ${DRONE_TAG} @@ -3958,7 +3994,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -3973,7 +4009,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4033,7 +4069,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -4048,7 +4084,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4083,51 +4119,6 @@ volumes: path: /var/run/docker.sock name: docker --- -clone: - retries: 3 -depends_on: [] -environment: - EDITION: oss -image_pull_secrets: -- gcr -- gar -kind: pipeline -name: release-whatsnew-checker -node: - type: no-parallel -platform: - arch: amd64 - os: linux -services: [] -steps: -- commands: - - go build -o ./bin/build -ldflags '-extldflags -static' ./pkg/build/cmd - depends_on: [] - environment: - CGO_ENABLED: 0 - image: golang:1.23.5-alpine - name: compile-build-cmd -- commands: - - ./bin/build whatsnew-checker - depends_on: - - compile-build-cmd - image: golang:1.23.5-alpine - name: whats-new-checker -trigger: - event: - exclude: - - promote - ref: - exclude: - - refs/tags/*-cloud* - include: - - refs/tags/v* -type: docker -volumes: -- host: - path: /var/run/docker.sock - name: docker ---- clone: retries: 3 depends_on: @@ -4195,7 +4186,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -4210,7 +4201,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4297,7 +4288,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - yarn install --immutable || yarn install --immutable @@ -4306,7 +4297,7 @@ steps: name: yarn-install - commands: - apk add --update git bash - - yarn betterer ci + - yarn betterer:ci depends_on: - yarn-install image: node:22.11.0-alpine @@ -4351,7 +4342,7 @@ services: [] steps: - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -4361,7 +4352,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -4370,21 +4361,21 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - apk add --update build-base shared-mime-info shared-mime-info-lang - go list -f '{{.Dir}}/...' -m | xargs go test -short -covermode=atomic -timeout=5m depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend - commands: - apk add --update build-base @@ -4393,7 +4384,7 @@ steps: | grep -o '\(.*\)/' | sort -u) depends_on: - wire-install - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: test-backend-integration trigger: cron: @@ -4432,7 +4423,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -4447,7 +4438,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4576,7 +4567,7 @@ steps: environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -4591,7 +4582,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4696,15 +4687,15 @@ steps: path: /github-app - commands: - export GITHUB_TOKEN=$(cat /github-app/token) - - 'dagger run --silent /src/grafana-build artifacts -a $${ARTIFACTS} --grafana-ref=$${GRAFANA_REF} - --enterprise-ref=$${ENTERPRISE_REF} --grafana-repo=$${GRAFANA_REPO} --version=$${VERSION} ' - - --go-version=1.23.5 + - dagger run --silent /src/grafana-build artifacts -a $${ARTIFACTS} --grafana-ref=$${GRAFANA_REF} + --enterprise-ref=$${ENTERPRISE_REF} --grafana-repo=$${GRAFANA_REPO} --version=$${VERSION} + --go-version=1.23.7 depends_on: - github-app-generate-token environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token - ALPINE_BASE: alpine:3.20.3 + ALPINE_BASE: alpine:3.21.3 CDN_DESTINATION: from_secret: rgm_cdn_destination DESTINATION: @@ -4719,7 +4710,7 @@ steps: from_secret: grafana_api_key GCP_KEY_BASE64: from_secret: gcp_key_base64 - GO_VERSION: 1.23.5 + GO_VERSION: 1.23.7 GPG_PASSPHRASE: from_secret: packages_gpg_passphrase GPG_PRIVATE_KEY: @@ -4743,6 +4734,8 @@ steps: - printenv GCP_KEY_BASE64 | base64 -d > /tmp/key.json - gcloud auth activate-service-account --key-file=/tmp/key.json - gcloud storage cp -r dist/* $${UPLOAD_TO} + depends_on: + - rgm-build environment: _EXPERIMENTAL_DAGGER_CLOUD_TOKEN: from_secret: dagger_token @@ -4783,6 +4776,8 @@ volumes: name: docker - name: github-app path: /github-app +- name: github-app + temp: {} --- clone: retries: 3 @@ -4837,13 +4832,13 @@ services: steps: - commands: - mkdir -p bin - - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.1/grabpl + - curl -fL -o bin/grabpl https://grafana-downloads.storage.googleapis.com/grafana-build-pipeline/v3.1.2/grabpl - chmod +x bin/grabpl image: byrnedo/alpine-curl:0.1.8 name: grabpl - commands: - echo $DRONE_RUNNER_NAME - image: alpine:3.20.3 + image: alpine:3.21.3 name: identify-runner - commands: - '# It is required that code generated from Thema/CUE be committed and in sync @@ -4853,7 +4848,7 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-cue depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-cue - commands: - '# It is required that generated jsonnet is committed and in sync with its inputs.' @@ -4862,14 +4857,14 @@ steps: - apk add --update make - CODEGEN_VERIFY=1 make gen-jsonnet depends_on: [] - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: verify-gen-jsonnet - commands: - apk add --update make - make gen-go depends_on: - verify-gen-cue - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: wire-install - commands: - dockerize -wait tcp://postgres:5432 -timeout 120s @@ -4890,7 +4885,7 @@ steps: GRAFANA_TEST_DB: postgres PGPASSWORD: grafanatest POSTGRES_HOST: postgres - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: postgres-integration-tests - commands: - dockerize -wait tcp://mysql80:3306 -timeout 120s @@ -4911,7 +4906,7 @@ steps: environment: GRAFANA_TEST_DB: mysql MYSQL_HOST: mysql80 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: mysql-8.0-integration-tests - commands: - dockerize -wait tcp://redis:6379 -timeout 120s @@ -4927,7 +4922,7 @@ steps: - wait-for-redis environment: REDIS_URL: redis://redis:6379/0 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: redis-integration-tests - commands: - dockerize -wait tcp://memcached:11211 -timeout 120s @@ -4943,7 +4938,7 @@ steps: - wait-for-memcached environment: MEMCACHED_HOSTS: memcached:11211 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: memcached-integration-tests - commands: - dockerize -wait tcp://mimir_backend:8080 -timeout 120s @@ -4959,7 +4954,7 @@ steps: environment: AM_TENANT_ID: test AM_URL: http://mimir_backend:8080 - image: golang:1.23.5-alpine + image: golang:1.23.7-alpine name: remote-alertmanager-integration-tests trigger: event: @@ -5262,12 +5257,12 @@ steps: - commands: - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM docker:27-cli - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine/git:2.40.1 - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.5-alpine + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM golang:1.23.7-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22.11.0-alpine - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM node:22-bookworm - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM google/cloud-sdk:431.0.0 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM grafana/grafana-ci-deploy:1.3.3 - - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.20.3 + - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM alpine:3.21.3 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM ubuntu:22.04 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM byrnedo/alpine-curl:0.1.8 - trivy --exit-code 0 --severity UNKNOWN,LOW,MEDIUM plugins/slack @@ -5300,12 +5295,12 @@ steps: - commands: - trivy --exit-code 1 --severity HIGH,CRITICAL docker:27-cli - trivy --exit-code 1 --severity HIGH,CRITICAL alpine/git:2.40.1 - - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.5-alpine + - trivy --exit-code 1 --severity HIGH,CRITICAL golang:1.23.7-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL node:22.11.0-alpine - trivy --exit-code 1 --severity HIGH,CRITICAL node:22-bookworm - trivy --exit-code 1 --severity HIGH,CRITICAL google/cloud-sdk:431.0.0 - trivy --exit-code 1 --severity HIGH,CRITICAL grafana/grafana-ci-deploy:1.3.3 - - trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.20.3 + - trivy --exit-code 1 --severity HIGH,CRITICAL alpine:3.21.3 - trivy --exit-code 1 --severity HIGH,CRITICAL ubuntu:22.04 - trivy --exit-code 1 --severity HIGH,CRITICAL byrnedo/alpine-curl:0.1.8 - trivy --exit-code 1 --severity HIGH,CRITICAL plugins/slack @@ -5569,6 +5564,6 @@ kind: secret name: gcr_credentials --- kind: signature -hmac: 154c1f072294cef09ba4f579eed30b1e29bc5c263897c862f4574432d321502c +hmac: 33f2e5615dfd7889899f9f8f16f7716190fa637fe98f1efd7e29607f8946be7d ... diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bb3c9871f91..7ff10207c35 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -38,7 +38,7 @@ /docs/sources/ @irenerl24 -/docs/sources/alerting/ @brendamuir +/docs/sources/alerting/ @JohnnyK-Grafana /docs/sources/dashboards/ @imatwawana /docs/sources/datasources/ @lwandz13 /docs/sources/panels-visualizations/ @imatwawana @@ -66,9 +66,14 @@ /scripts/go-workspace @grafana/grafana-app-platform-squad /hack/ @grafana/grafana-app-platform-squad +/pkg/apis/provisioning @grafana/grafana-git-ui-sync-team +/public/app/features/provisioning @grafana/grafana-git-ui-sync-team +/pkg/registry/apis/provisioning @grafana/grafana-git-ui-sync-team + /apps/alerting/ @grafana/alerting-backend +/apps/dashboard/ @grafana/grafana-app-platform-squad @grafana/dashboards-squad /apps/playlist/ @grafana/grafana-app-platform-squad -/apps/investigation/ @fcjack @matryer +/apps/investigations/ @fcjack @matryer @svennergr /apps/advisor/ @grafana/plugins-platform-backend /pkg/api/ @grafana/grafana-backend-group /pkg/apis/ @grafana/grafana-app-platform-squad @@ -238,6 +243,7 @@ /devenv/dev-dashboards/extensions/ @grafana/plugins-platform-frontend /devenv/docker/blocks/alert_webhook_listener/ @grafana/alerting-backend +/devenv/docker/blocks/stateful_webhook/ @grafana/alerting-backend /devenv/docker/blocks/caddy_tls/ @grafana/alerting-backend /devenv/docker/blocks/clickhouse/ @grafana/partner-datasources /devenv/docker/blocks/collectd/ @grafana/observability-metrics @@ -377,6 +383,11 @@ /crowdin.yml @grafana/grafana-frontend-platform /public/locales/ @grafana/grafana-frontend-platform +/public/locales/de-DE @grafanabot +/public/locales/es-ES @grafanabot +/public/locales/fr-FR @grafanabot +/public/locales/pt-BR @grafanabot +/public/locales/zh-Hans @grafanabot /public/app/core/internationalization/ @grafana/grafana-frontend-platform /e2e/ @grafana/grafana-frontend-platform /e2e/cloud-plugins-suite/ @grafana/partner-datasources @@ -402,7 +413,7 @@ /packages/grafana-schema/src/**/*canvas* @grafana/dataviz-squad /packages/grafana-schema/src/**/*tempo* @grafana/observability-traces-and-profiling /packages/grafana-sql/ @grafana/partner-datasources @grafana/oss-big-tent -/packages/grafana-ui/.storybook/ @grafana/plugins-platform-frontend +/packages/grafana-ui/.storybook/ @grafana/grafana-frontend-platform /packages/grafana-ui/src/components/ @grafana/grafana-frontend-platform /packages/grafana-ui/src/components/BarGauge/ @grafana/dataviz-squad /packages/grafana-ui/src/components/DataLinks/ @grafana/dataviz-squad @@ -421,7 +432,7 @@ /packages/grafana-ui/src/graveyard/Graph/ @grafana/dataviz-squad /packages/grafana-ui/src/graveyard/GraphNG/ @grafana/dataviz-squad /packages/grafana-ui/src/graveyard/TimeSeries/ @grafana/dataviz-squad -/packages/grafana-ui/src/utils/storybook/ @grafana/plugins-platform-frontend +/packages/grafana-ui/src/utils/storybook/ @grafana/grafana-frontend-platform # root files, mostly frontend /.browserslistrc @grafana/frontend-ops @@ -435,6 +446,7 @@ /.betterer.eslint.config.js @grafana/frontend-ops /.gitattributes @grafana/frontend-ops /.gitignore @grafana/frontend-ops +/.ignore @grafana/frontend-ops /.nvmrc @grafana/frontend-ops /.prettierignore @grafana/frontend-ops /.yarn @grafana/frontend-ops @@ -455,6 +467,7 @@ playwright.config.ts @grafana/plugins-platform-frontend # public folder +/public/app/api/ @grafana/grafana-frontend-platform /public/app/core/ @grafana/grafana-frontend-platform /public/app/core/components/TimePicker/ @grafana/grafana-frontend-platform /public/app/core/components/Layers/ @grafana/dataviz-squad @@ -489,8 +502,9 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/features/dimensions/ @grafana/dataviz-squad /public/app/features/dataframe-import/ @grafana/dataviz-squad /public/app/features/explore/ @grafana/observability-traces-and-profiling -/public/app/features/expressions/ @grafana/observability-metrics +/public/app/features/expressions/ @grafana/grafana-datasources-core-services /public/app/features/folders/ @grafana/grafana-frontend-platform +/public/app/features/iam/ @grafana/grafana-frontend-platform /public/app/features/inspector/ @grafana/dashboards-squad /public/app/features/invites/ @grafana/grafana-frontend-platform /public/app/features/library-panels/ @grafana/dashboards-squad @@ -504,7 +518,6 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/features/playlist/ @grafana/dashboards-squad /public/app/features/plugins/ @grafana/plugins-platform-frontend /public/app/features/profile/ @grafana/grafana-frontend-platform -/public/app/features/query-library/ @grafana/grafana-frontend-platform /public/app/features/runtime/ @ryantxu /public/app/features/query/ @grafana/dashboards-squad /public/app/features/sandbox/ @grafana/grafana-frontend-platform @@ -533,6 +546,7 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/plugins/panel/heatmap/ @grafana/dataviz-squad /public/app/plugins/panel/histogram/ @grafana/dataviz-squad /public/app/plugins/panel/logs/ @grafana/observability-logs +/public/app/plugins/panel/logs-new/ @grafana/observability-logs /public/app/plugins/panel/nodeGraph/ @grafana/observability-traces-and-profiling @grafana/app-o11y-visualizations /public/app/plugins/panel/traces/ @grafana/observability-traces-and-profiling /public/app/plugins/panel/flamegraph/ @grafana/observability-traces-and-profiling @@ -581,6 +595,7 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/features/explore/NodeGraph/ @grafana/observability-traces-and-profiling /public/app/features/explore/FlameGraph/ @grafana/observability-traces-and-profiling /public/app/features/explore/TraceView/ @grafana/observability-traces-and-profiling +/public/app/features/explore/QueryLibrary/ @grafana/grafana-frontend-platform /public/api-merged.json @grafana/grafana-backend-group /public/api-enterprise-spec.json @grafana/grafana-backend-group @@ -593,9 +608,6 @@ playwright.config.ts @grafana/plugins-platform-frontend /public/app/AppWrapper.tsx @grafana/frontend-ops /public/app/partials/ @grafana/grafana-frontend-platform - - - /scripts/benchmark-access-control.sh @grafana/access-squad /scripts/check-breaking-changes.sh @grafana/plugins-platform-frontend /scripts/ci-* @grafana/grafana-developer-enablement-squad @@ -610,7 +622,7 @@ playwright.config.ts @grafana/plugins-platform-frontend /scripts/import_many_dashboards.sh @torkelo /scripts/mixin-check.sh @bergquist /scripts/openapi3/ @grafana/grafana-operator-experience-squad -/scripts/prepare-packagejson.js @grafana/frontend-ops +/scripts/prepare-npm-package.js @grafana/frontend-ops /scripts/protobuf-check.sh @grafana/plugins-platform-backend /scripts/stripnulls.sh @grafana/grafana-as-code /scripts/tag_release.sh @grafana/grafana-developer-enablement-squad @@ -620,6 +632,7 @@ playwright.config.ts @grafana/plugins-platform-frontend /scripts/cleanup-husky.sh @grafana/frontend-ops /scripts/verify-repo-update/ @grafana/grafana-developer-enablement-squad /scripts/generate-rtk-apis.ts @grafana/grafana-frontend-platform +/scripts/process-specs.ts @grafana/grafana-frontend-platform /scripts/generate-alerting-rtk-apis.ts @grafana/alerting-frontend /scripts/levitate-parse-json-report.js @grafana/plugins-platform-frontend /scripts/levitate-show-affected-plugins.js @grafana/plugins-platform-frontend @@ -633,9 +646,6 @@ playwright.config.ts @grafana/plugins-platform-frontend .betterer.results @grafanabot .betterer.ts @grafana/grafana-frontend-platform -# @grafana/ui component documentation -*.mdx @grafana/plugins-platform-frontend - # Design system /public/img/icons/unicons/ @grafana/design-system @@ -746,14 +756,20 @@ embed.go @grafana/grafana-as-code /.github/pr-checks.json @tolzhabayev /.github/pr-commands.json @tolzhabayev /.github/renovate.json5 @grafana/frontend-ops +/.github/actions/test-coverage-processor/action.yml @grafana/grafana-backend-group +/.github/actions/setup-grafana-bench/ @Proximyst +/.github/workflows/add-to-whats-new.yml @grafana/docs-tooling /.github/workflows/auto-triager/ @grafana/plugins-platform-frontend /.github/workflows/alerting-swagger-gen.yml @grafana/alerting-backend +/.github/workflows/alerting-update-module.yml @grafana/alerting-backend /.github/workflows/auto-milestone.yml @grafana/grafana-developer-enablement-squad /.github/workflows/backport.yml @grafana/grafana-developer-enablement-squad /.github/workflows/bump-version.yml @grafana/grafana-developer-enablement-squad /.github/workflows/close-milestone.yml @grafana/grafana-developer-enablement-squad /.github/workflows/release-pr.yml @grafana/grafana-developer-enablement-squad /.github/workflows/release-comms.yml @grafana/grafana-developer-enablement-squad +/.github/workflows/migrate-prs.yml @grafana/grafana-developer-enablement-squad +/.github/workflows/create-next-release-branch.yml @grafana/grafana-developer-enablement-squad /.github/workflows/codeowners-validator.yml @tolzhabayev /.github/workflows/codeql-analysis.yml @DanCech /.github/workflows/commands.yml @torkelo @@ -763,21 +779,23 @@ embed.go @grafana/grafana-as-code /.github/workflows/doc-validator.yml @grafana/docs-tooling /.github/workflows/deploy-pr-preview.yml @grafana/docs-tooling /.github/workflows/epic-add-to-platform-ux-parent-project.yml @meanmina +/.github/workflows/feature-toggles-ci.yml @grafana/docs-tooling /.github/workflows/github-release.yml @grafana/grafana-developer-enablement-squad /.github/workflows/issue-opened.yml @grafana/grafana-community-support /.github/workflows/metrics-collector.yml @torkelo /.github/workflows/milestone.yml @tolzhabayev +/.github/workflows/pr-backend-code-checks.yml @grafana/grafana-backend-group /.github/workflows/pr-checks.yml @tolzhabayev /.github/workflows/pr-codeql-analysis-go.yml @DanCech /.github/workflows/pr-codeql-analysis-javascript.yml @DanCech /.github/workflows/pr-codeql-analysis-python.yml @DanCech /.github/workflows/pr-commands.yml @tolzhabayev /.github/workflows/pr-patch-check.yml @grafana/grafana-developer-enablement-squad +/.github/workflows/pr-backend-unit-tests.yml @grafana/grafana-backend-group /.github/workflows/sync-mirror.yml @grafana/grafana-developer-enablement-squad /.github/workflows/publish-technical-documentation-next.yml @grafana/docs-tooling /.github/workflows/publish-technical-documentation-release.yml @grafana/docs-tooling /.github/workflows/remove-milestone.yml @grafana/grafana-developer-enablement-squad -/.github/workflows/sbom-report.yml @grafana/security-team /.github/workflows/scripts/json-file-to-job-output.js @grafana/plugins-platform-frontend /.github/workflows/stale.yml @grafana/grafana-developer-enablement-squad /.github/workflows/update-changelog.yml @grafana/grafana-developer-enablement-squad @@ -787,6 +805,7 @@ embed.go @grafana/grafana-as-code /.github/workflows/publish-kinds-release.yml @grafana/platform-monitoring /.github/workflows/verify-kinds.yml @grafana/platform-monitoring /.github/workflows/dashboards-issue-add-label.yml @grafana/dashboards-squad +/.github/workflows/run-schema-v2-e2e.yml @grafana/dashboards-squad /.github/workflows/ephemeral-instances-pr-comment.yml @grafana/grafana-backend-services-squad /.github/workflows/create-security-patch-from-security-mirror.yml @grafana/grafana-developer-enablement-squad /.github/workflows/core-plugins-build-and-release.yml @grafana/plugins-platform-frontend @grafana/plugins-platform-backend @@ -799,6 +818,9 @@ embed.go @grafana/grafana-as-code /.github/workflows/trivy-scan.yml @grafana/grafana-backend-services-squad /.github/workflows/changelog.yml @zserge /.github/workflows/actions/changelog @zserge +/.github/workflows/frontend-unit-tests.yml @grafana/grafana-frontend-platform +/.github/workflows/frontend-lint.yml @grafana/grafana-frontend-platform +/.github/workflows/analytics-events-report.yml @grafana/grafana-frontend-platform # Generated files not requiring owner approval /packages/grafana-data/src/types/featureToggles.gen.ts @grafanabot diff --git a/.github/actions/setup-grafana-bench/action.yml b/.github/actions/setup-grafana-bench/action.yml new file mode 100644 index 00000000000..624ad243b7b --- /dev/null +++ b/.github/actions/setup-grafana-bench/action.yml @@ -0,0 +1,44 @@ +name: 'Setup Grafana Bench' +description: 'Sets up and installs Grafana Bench' + +inputs: + github-app-name: + description: 'Name of the GitHub App in Vault' + required: false + default: 'grafana-ci-bot' + branch: + description: 'The branch to install from' + required: false + default: 'main' + +runs: + using: "composite" + steps: + - name: Retrieve GitHub App secrets + id: get-secrets + uses: grafana/shared-workflows/actions/get-vault-secrets@get-vault-secrets-v1.0.1 + with: + repo_secrets: | + APP_ID=${{ inputs.github-app-name }}:app-id + APP_INSTALLATION_ID=${{ inputs.github-app-name }}:app-installation-id + PRIVATE_KEY=${{ inputs.github-app-name }}:private-key + + - name: Generate GitHub App token + id: generate_token + uses: actions/create-github-app-token@v1 + with: + app-id: ${{ env.APP_ID }} + private-key: ${{ env.PRIVATE_KEY }} + repositories: "grafana-bench" + owner: "grafana" + + - name: Setup Bench + shell: bash + env: + GH_TOKEN: ${{ steps.generate_token.outputs.token }} + run: | + git clone https://x-access-token:${GH_TOKEN}@github.com/grafana/grafana-bench.git ../grafana-bench + + cd ../grafana-bench + git switch ${{ inputs.branch }} + go install . diff --git a/.github/actions/test-coverage-processor/action.yml b/.github/actions/test-coverage-processor/action.yml new file mode 100644 index 00000000000..7560031e846 --- /dev/null +++ b/.github/actions/test-coverage-processor/action.yml @@ -0,0 +1,48 @@ +name: 'Go Coverage Processor' +description: 'Process Go test coverage files and generate reports' + +inputs: + test-type: + description: 'Type of test (e.g., be-unit, be-integration)' + required: true + type: string + coverage-file: + description: 'Path to the Go coverage file (.cov)' + required: true + type: string + codecov-token: + description: 'Token for CodeCov (required for CodeCov reporting)' + required: false + default: '' + codecov-flag: + description: 'Flag to categorize the upload to CodeCov' + required: false + default: '' + codecov-name: + description: 'Custom name for the upload to CodeCov' + required: false + default: '' + +runs: + using: 'composite' + steps: + - name: Process Go coverage output + shell: bash + run: | + # Ensure valid coverage file even if empty + if [ ! -s ${{ inputs.coverage-file }} ]; then + echo "Coverage file is empty, creating a minimal valid file" + echo "mode: set" > ${{ inputs.coverage-file }} + fi + + - name: Report coverage to CodeCov + uses: codecov/codecov-action@v5 + if: inputs.codecov-token != '' + with: + files: ${{ inputs.coverage-file }} + flags: ${{ inputs.codecov-flag || inputs.test-type }} + name: ${{ inputs.codecov-name || inputs.test-type }} + slug: grafana/grafana + # This URL doesn't use the Google auth, but is much more locked down. As such, it requires OIDC or a CodeCov-provided token to do anything. + url: https://codecov-webhook.grafana-dev.net + token: ${{ inputs.codecov-token }} diff --git a/.github/commands.json b/.github/commands.json index fb10220fb21..e6c2036d7cf 100644 --- a/.github/commands.json +++ b/.github/commands.json @@ -640,7 +640,7 @@ "name": "area/configuration", "action": "addToProject", "addToProject": { - "url": "https://github.com/orgs/grafana/projects/96" + "url": "https://github.com/orgs/grafana/projects/665" } }, { @@ -744,7 +744,7 @@ "name": "area/backend/db/postgres", "action": "addToProject", "addToProject": { - "url": "https://github.com/orgs/grafana/projects/96" + "url": "https://github.com/orgs/grafana/projects/835" } }, { @@ -1115,14 +1115,6 @@ "url": "https://github.com/orgs/grafana/projects/202" } }, - { - "type": "label", - "name": "area/editor", - "action": "addToProject", - "addToProject": { - "url": "https://github.com/grafana/grafana/projects/21" - } - }, { "type": "label", "name": "area/data/export", diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f37f7a732f6..0de94ce207d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -8,7 +8,7 @@ updates: directories: - "/" - "/apps/playlist" - - "/apps/investigation" + - "/apps/investigations" - "/pkg/aggregator" - "/pkg/apimachinery" - "/pkg/apiserver" diff --git a/.github/pr-commands.json b/.github/pr-commands.json index 1803aa29a8a..d211b5cce3a 100644 --- a/.github/pr-commands.json +++ b/.github/pr-commands.json @@ -247,7 +247,8 @@ "/pkg/services/sqlstore/migrations/ualert/**/*", "/pkg/services/alerting/**/*", "/public/app/features/alerting/**/*", - "/pkg/tests/api/alerting/**/*" + "/pkg/tests/api/alerting/**/*", + "/pkg/tests/alertmanager/**/*" ], "action": "updateLabel", "addLabel": "area/alerting" diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 6cc2ac80423..43a537f2fa1 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -13,7 +13,6 @@ "slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate "@types/slate-react", // we don't want to continue using this on the long run, use Monaco editor instead of Slate "@types/slate", // we don't want to continue using this on the long run, use Monaco editor instead of Slate - "storybook-dark-mode", // 4.0.2 causes storybook 8.4 to break with react hooks errors // Temporarily pause updating lerna and nx until we resolve build issues "lerna", "nx" @@ -33,6 +32,7 @@ extends: ["schedule:monthly"], groupName: "Storybook updates", matchPackageNames: ["/^@?storybook/"], + rangeStrategy: "bump", }, { groupName: "React Aria", diff --git a/.github/workflows/actions/changelog/index.js b/.github/workflows/actions/changelog/index.js index 48da9dcf33a..b658caf349c 100644 --- a/.github/workflows/actions/changelog/index.js +++ b/.github/workflows/actions/changelog/index.js @@ -69,8 +69,17 @@ const graphql = async (ghtoken, query, variables) => { }, body: JSON.stringify({ query, variables }), }); - const { data } = await results.json(); - return data; + + const res = await results.json(); + + LOG( + JSON.stringify({ + status: results.status, + text: results.statusText, + }) + ); + + return res.data; }; // Using Github GraphQL API find the timestamp for the given tag/commit hash. @@ -99,20 +108,20 @@ const getCommitishDate = async (name, owner, target) => { // Using Github GraphQL API get a list of PRs between the two "commitish" items. // This resoves the "since" item's timestamp first and iterates over all PRs // till "target" using naïve pagination. -const getHistory = async (name, owner, target, sinceDate) => { - LOG(`Fetching ${owner}/${name} PRs since ${sinceDate} till ${target}`); +const getHistory = async (name, owner, from, to) => { + LOG(`Fetching ${owner}/${name} PRs between ${from} and ${to}`); const query = ` query findCommitsWithAssociatedPullRequests( $name: String! $owner: String! - $target: String! - $sinceDate: GitTimestamp + $from: String! + $to: String! $cursor: String ) { repository(name: $name, owner: $owner) { - object(expression: $target) { - ... on Commit { - history(first: 50, since: $sinceDate, after: $cursor) { + ref(qualifiedName: $from) { + compare(headRef: $to) { + commits(first: 25, after: $cursor) { totalCount pageInfo { hasNextPage @@ -155,13 +164,13 @@ const getHistory = async (name, owner, target, sinceDate) => { const result = await graphql(ghtoken, query, { name, owner, - target, - sinceDate, + from, + to, cursor, }); LOG(`GraphQL: ${JSON.stringify(result)}`); - nodes = [...nodes, ...result.repository.object.history.nodes]; - const { hasNextPage, endCursor } = result.repository.object.history.pageInfo; + nodes = [...nodes, ...result.repository.ref.compare.commits.nodes]; + const { hasNextPage, endCursor } = result.repository.ref.compare.commits.pageInfo; if (!hasNextPage) { break; } @@ -175,11 +184,11 @@ const getHistory = async (name, owner, target, sinceDate) => { // feature, deprecation, breaking change and plugin fixes/enhancements). // // PR grouping relies on Github labels only, not on the PR contents. -const getChangeLogItems = async (name, owner, sinceDate, to) => { +const getChangeLogItems = async (name, owner, from, to) => { // check if a node contains a certain label const hasLabel = ({ labels }, label) => labels.nodes.some(({ name }) => name === label); // get all the PRs between the two "commitish" items - const history = await getHistory(name, owner, to, sinceDate); + const history = await getHistory(name, owner, from, to); const items = history.flatMap((node) => { // discard PRs without a "changelog" label @@ -231,13 +240,10 @@ const previous = process.argv[3] || process.env.INPUT_PREVIOUS || (await getPrev LOG(`Previous tag/commit: ${previous}`); -const sinceDate = await getCommitishDate('grafana', 'grafana', previous); -LOG(`Previous tag/commit timestamp: ${sinceDate}`); - // Get all changelog items from Grafana OSS -const oss = await getChangeLogItems('grafana', 'grafana', sinceDate, target); +const oss = await getChangeLogItems('grafana', 'grafana', previous, target); // Get all changelog items from Grafana Enterprise -const entr = await getChangeLogItems('grafana-enterprise', 'grafana', sinceDate, target); +const entr = await getChangeLogItems('grafana-enterprise', 'grafana', previous, target); LOG(`Found OSS PRs: ${oss.length}`); LOG(`Found Enterprise PRs: ${entr.length}`); diff --git a/.github/workflows/add-to-whats-new.yml b/.github/workflows/add-to-whats-new.yml new file mode 100644 index 00000000000..900ab9615bd --- /dev/null +++ b/.github/workflows/add-to-whats-new.yml @@ -0,0 +1,16 @@ +name: Add comment about adding a What's new note +on: + pull_request: + types: [labeled] + +jobs: + add-comment: + if: ${{ ! github.event.pull_request.head.repo.fork && contains(github.event.pull_request.labels.*.name, 'add to what''s new') }} + runs-on: ubuntu-latest + permissions: + pull-requests: write + steps: + - uses: marocchino/sticky-pull-request-comment@52423e01640425a022ef5fd42c6fb5f633a02728 # v2.9.1 + with: + message: | + Since you've added the `Add to what's new` label, consider drafting a [What's new note](https://admin.grafana.com/content-admin/#/collections/whats-new/new) for this feature. diff --git a/.github/workflows/alerting-update-module.yml b/.github/workflows/alerting-update-module.yml new file mode 100644 index 00000000000..213b243f9b1 --- /dev/null +++ b/.github/workflows/alerting-update-module.yml @@ -0,0 +1,136 @@ +name: Update Alerting Module + +on: + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + update-grafana: + runs-on: ubuntu-latest + permissions: + contents: write + pull-requests: write + id-token: write + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # 4.2.2 + + - name: Check if update branch exists + run: | + if git ls-remote --heads origin update-alerting-module | grep -q 'update-alerting-module'; then + echo "Branch 'update-alerting-module' already exists. There might be an open PR with Grafana updates." + echo "Please review and merge/close the existing PR before running this workflow again." + exit 1 + fi + + - name: Setup Go + uses: actions/setup-go@f111f3307d8850f501ac008e886eec1fd1932a34 # 5.3.0 + with: + "go-version-file": "go.mod" + + - name: Extract current commit hash of alerting module + id: current-commit + run: | + FROM_COMMIT=$(go list -m -json github.com/grafana/alerting | jq -r '.Version' | grep -oP '(?<=-)[a-f0-9]+$') + echo "from_commit=$FROM_COMMIT" >> $GITHUB_OUTPUT + + - name: Get current branch name + id: current-branch-name + run: echo "name=${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}}" >> "$GITHUB_OUTPUT" + + - name: Get latest commit + id: latest-commit + env: + GH_TOKEN: ${{ github.token }} + run: | + BRANCH="${{ steps.current-branch-name.outputs.name }}" + TO_COMMIT=$(gh api repos/grafana/alerting/commits/$BRANCH --jq '.sha') + if [ -z "$TO_COMMIT" ]; then + echo "Branch $BRANCH not found in alerting repo, falling back to main branch" + exit 1 + fi + echo "to_commit=$TO_COMMIT" >> $GITHUB_OUTPUT + + - name: Compare commit hashes + run: | + FROM_COMMIT="${{ steps.current-commit.outputs.from_commit }}" + TO_COMMIT="${{ steps.latest-commit.outputs.to_commit }}" + + # Compare just the length of the shorter hash + SHORT_TO_COMMIT="${TO_COMMIT:0:${#FROM_COMMIT}}" + + if [ "$FROM_COMMIT" = "$SHORT_TO_COMMIT" ]; then + echo "Current version ($FROM_COMMIT) is already at latest ($SHORT_TO_COMMIT). No update needed." + exit 0 + fi + echo "Updates available: $FROM_COMMIT -> $TO_COMMIT" + + - name: Check for commit history + id: check-commits + env: + GH_TOKEN: ${{ github.token }} + run: | + # get all commits that contains 'Alerting:' in the message + ALERTING_COMMITS=$(gh api repos/grafana/alerting/compare/${{ steps.current-commit.outputs.from_commit }}...${{ steps.latest-commit.outputs.to_commit }} \ + --jq '.commits[].commit.message | split("\n")[0]') || true + + # Use printf instead of echo -e for better multiline handling + printf "%s\n" "$ALERTING_COMMITS" + + # make the list for markdown and replace PR numbers with links + ALERTING_COMMITS_FORMATTED=$(echo "$ALERTING_COMMITS" | while read -r line; do echo "- $line" | sed -E 's/\(#([0-9]+)\)/[#\1](https:\/\/github.com\/grafana\/grafana\/pull\/\1)/g'; done) + + echo "alerting_commits<> $GITHUB_OUTPUT + echo "$ALERTING_COMMITS_FORMATTED" >> $GITHUB_OUTPUT + echo "EOF" >> $GITHUB_OUTPUT + + - name: Update alerting module + env: + GOSUMDB: off + run: | + go get github.com/grafana/alerting@${{ steps.latest-commit.outputs.to_commit }} + make update-workspace + + - id: get-secrets + uses: grafana/shared-workflows/actions/get-vault-secrets@28361cdb22223e5f1e34358c86c20908e7248760 # 1.1.0 + with: + repo_secrets: | + GITHUB_APP_ID=alerting-team:app-id + GITHUB_APP_PRIVATE_KEY=alerting-team:private-key + + - name: "Generate token" + id: generate_token + uses: actions/create-github-app-token@0d564482f06ca65fa9e77e2510873638c82206f2 # 1.11.5 + with: + app-id: ${{ env.GITHUB_APP_ID }} + private-key: ${{ env.GITHUB_APP_PRIVATE_KEY }} + + - name: Create Pull Request + uses: peter-evans/create-pull-request@67ccf781d68cd99b580ae25a5c18a1cc84ffff1f # 7.0.6 + id: create-pr + with: + token: '${{ steps.generate_token.outputs.token }}' + title: 'Alerting: Update alerting module to ${{ steps.latest-commit.outputs.to_commit }}' + branch: alerting/update-alerting-module + delete-branch: true + body: | + Updates Grafana Alerting module to latest version. + + Compare changes: https://github.com/grafana/alerting/compare/${{ steps.current-commit.outputs.from_commit }}...${{ steps.latest-commit.outputs.to_commit }} +
+ Commits + + ${{ steps.check-commits.outputs.alerting_commits }} + +
+ + Created by: [GitHub Action Job](https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}) + - name: Add PR URL to Summary + if: steps.create-pr.outputs.pull-request-url != '' + run: | + echo "## Pull Request Created" >> $GITHUB_STEP_SUMMARY + echo "🔗 [View Pull Request](${{ steps.create-pr.outputs.pull-request-url }})" >> $GITHUB_STEP_SUMMARY diff --git a/.github/workflows/analytics-events-report.yml b/.github/workflows/analytics-events-report.yml new file mode 100644 index 00000000000..9d4d6907256 --- /dev/null +++ b/.github/workflows/analytics-events-report.yml @@ -0,0 +1,23 @@ +name: Analytics Events Report + +on: + workflow_dispatch: + +jobs: + generate-report: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + + - name: Install dependencies + run: yarn install --frozen-lockfile + + - name: Generate analytics report + run: yarn analytics-report diff --git a/.github/workflows/auto-triager/labels.txt b/.github/workflows/auto-triager/labels.txt index 6b7b9e37f8b..1a33cf676dc 100644 --- a/.github/workflows/auto-triager/labels.txt +++ b/.github/workflows/auto-triager/labels.txt @@ -32,7 +32,6 @@ area/dashboard/tv area/dashboard/variable area/dashboards/panel area/data/export -area/editor area/explore area/exploremetrics area/expressions diff --git a/.github/workflows/backport.yml b/.github/workflows/backport.yml index 18407b67f76..5f21ab276ee 100644 --- a/.github/workflows/backport.yml +++ b/.github/workflows/backport.yml @@ -10,24 +10,18 @@ jobs: if: github.repository == 'grafana/grafana' runs-on: ubuntu-latest steps: - - name: Checkout Actions + - name: Checkout uses: actions/checkout@v4 - with: - repository: "grafana/grafana-github-actions" - path: ./actions - ref: main - - name: Install Actions - run: npm install --production --prefix ./actions - name: "Generate token" id: generate_token uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 with: app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - run: git config --global user.email '132647405+grafana-delivery-bot[bot]@users.noreply.github.com' + - run: git config --global user.name 'grafana-delivery-bot[bot]' + - run: git remote set-url origin "https://grafana-delivery-bot:${{ steps.generate_token.outputs.token }}@github.com/grafana/grafana.git" - name: Run backport - uses: ./actions/backport + uses: grafana/grafana-github-actions-go/backport@main with: - metricsWriteAPIKey: ${{secrets.GRAFANA_MISC_STATS_API_KEY}} token: ${{ steps.generate_token.outputs.token }} - labelsToAdd: "backport" - title: "[{{base}}] {{originalTitle}}" diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 14981389deb..c1f90ceb831 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -52,7 +52,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v2 + uses: github/codeql-action/init@v3 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -67,4 +67,4 @@ jobs: make build-go - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v2 + uses: github/codeql-action/analyze@v3 diff --git a/.github/workflows/create-next-release-branch.yml b/.github/workflows/create-next-release-branch.yml new file mode 100644 index 00000000000..8fc01cd442d --- /dev/null +++ b/.github/workflows/create-next-release-branch.yml @@ -0,0 +1,53 @@ +name: Create next release branch +on: + workflow_call: + inputs: + ownerRepo: + type: string + description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana') + required: true + source: + description: The release branch to increment (eg providing `release-11.2.3` will result in `release-11.2.4` being created) + type: string + required: true + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: + required: true + GRAFANA_DELIVERY_BOT_APP_PEM: + required: true + outputs: + branch: + description: The new branch that was created + value: ${{ jobs.main.outputs.branch }} + workflow_dispatch: + inputs: + ownerRepo: + description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana') + source: + description: The release branch to increment (eg providing `release-11.2.3` will result in `release-11.2.4` being created) + type: string + required: true + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: + required: true + GRAFANA_DELIVERY_BOT_APP_PEM: + required: true +jobs: + main: + runs-on: ubuntu-latest + outputs: + branch: ${{ steps.branch.outputs.branch }} + steps: + - name: "Generate token" + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - name: Create release branch + id: branch + uses: grafana/grafana-github-actions-go/bump-release@main + with: + ownerRepo: ${{ inputs.ownerRepo }} + source: ${{ inputs.source }} + token: ${{ steps.generate_token.outputs.token }} diff --git a/.github/workflows/create-security-patch-from-security-mirror.yml b/.github/workflows/create-security-patch-from-security-mirror.yml index e187149b8b4..f85239241ad 100644 --- a/.github/workflows/create-security-patch-from-security-mirror.yml +++ b/.github/workflows/create-security-patch-from-security-mirror.yml @@ -11,6 +11,7 @@ on: branches: - "main" - "v*.*.*" + - "release-*.*.*" # This is run before the pull request has been merged, so we'll run against the src branch jobs: diff --git a/.github/workflows/deploy-pr-preview.yml b/.github/workflows/deploy-pr-preview.yml index dcb8fcd1c2a..bfad92ebf73 100644 --- a/.github/workflows/deploy-pr-preview.yml +++ b/.github/workflows/deploy-pr-preview.yml @@ -11,14 +11,21 @@ on: jobs: deploy-pr-preview: - if: ${{ ! github.event.pull_request.head.repo.fork }} + if: "!github.event.pull_request.head.repo.fork" uses: grafana/writers-toolkit/.github/workflows/deploy-preview.yml@main with: - sha: ${{ github.event.pull_request.head.sha }} branch: ${{ github.head_ref }} event_number: ${{ github.event.number }} - title: ${{ github.event.pull_request.title }} repo: grafana - website_directory: content/docs/grafana/latest - relative_prefix: /docs/grafana/latest/ - index_file: true + sha: ${{ github.event.pull_request.head.sha }} + sources: | + [ + { + "index_file": "content/docs/grafana/_index.md", + "relative_prefix": "/docs/grafana/latest/", + "repo": "grafana", + "source_directory": "docs/sources", + "website_directory": "content/docs/grafana/latest" + } + ] + title: ${{ github.event.pull_request.title }} diff --git a/.github/workflows/documentation-ci.yml b/.github/workflows/documentation-ci.yml index 0f041220ec9..4c688968a09 100644 --- a/.github/workflows/documentation-ci.yml +++ b/.github/workflows/documentation-ci.yml @@ -10,10 +10,10 @@ jobs: container: image: grafana/vale:latest steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/checkout@v4 with: persist-credentials: false - - uses: grafana/writers-toolkit/vale-action@13205961f20ad13843505a9b84fdf032f911a3f4 # vale-action/v1.1.0 + - uses: grafana/writers-toolkit/vale-action@vale-action/v1 with: filter: '.Name in ["Grafana.WordList", "Grafana.Spelling", "Grafana.ProductPossessives"]' token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/feature-toggles-ci.yml b/.github/workflows/feature-toggles-ci.yml new file mode 100644 index 00000000000..a6c9f5c52dc --- /dev/null +++ b/.github/workflows/feature-toggles-ci.yml @@ -0,0 +1,25 @@ +name: Feature toggles CI + +on: + pull_request: + paths: + - 'pkg/services/featuremgmt/toggles_gen_test.go' + - 'pkg/services/featuremgmt/registry.go' + - 'docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md' + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + persist-credentials: false + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + cache: true + + - name: Run feature toggle tests + run: go test -v -run TestFeatureToggleFiles ./pkg/services/featuremgmt/ diff --git a/.github/workflows/frontend-lint.yml b/.github/workflows/frontend-lint.yml new file mode 100644 index 00000000000..a9b65b247fb --- /dev/null +++ b/.github/workflows/frontend-lint.yml @@ -0,0 +1,55 @@ +name: Lint Frontend +on: + pull_request: + push: + branches: + - main + - release-*.*.* + +jobs: + verify-i18n: + name: Verify i18n + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + - run: yarn install --immutable --check-cache + - run: | + extract_error_message='::error::Extraction failed. Make sure that you have no dynamic translation phrases, such as "t(`preferences.theme.{themeID}`, themeName)" and that no translation key is used twice. Search the output for '[warning]' to find the offending file.' + make i18n-extract || (echo "${extract_error_message}" && false) + - run: | + uncommited_error_message="::error::Translation extraction has not been committed. Please run 'make i18n-extract', commit the changes and push again." + file_diff=$(git diff --dirstat public/locales) + if [ -n "$file_diff" ]; then + echo $file_diff + echo "${uncommited_error_message}" + exit 1 + fi + prettier: + name: Prettier + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + - run: yarn install --immutable --check-cache + - run: yarn run prettier:check + typecheck: + name: Typecheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + - run: yarn install --immutable --check-cache + - run: yarn run typecheck diff --git a/.github/workflows/frontend-unit-tests.yml b/.github/workflows/frontend-unit-tests.yml new file mode 100644 index 00000000000..495bb647233 --- /dev/null +++ b/.github/workflows/frontend-unit-tests.yml @@ -0,0 +1,29 @@ +name: Frontend tests +on: + pull_request: + push: + branches: + - main + - release-*.*.* + +jobs: + test-frontend: + runs-on: ubuntu-latest-8-cores + name: "Unit tests (${{ matrix.chunk }} / 8)" + strategy: + fail-fast: true + matrix: + chunk: [1, 2, 3, 4, 5, 6, 7, 8] + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + cache: 'yarn' + cache-dependency-path: 'yarn.lock' + - run: yarn install --immutable --check-cache + - run: yarn run test:ci + env: + TEST_MAX_WORKERS: 2 + TEST_SHARD: ${{ matrix.chunk }} + TEST_SHARD_TOTAL: 8 diff --git a/.github/workflows/i18n-crowdin-download.yml b/.github/workflows/i18n-crowdin-download.yml index cba14abe43b..e0c3c50b9bb 100644 --- a/.github/workflows/i18n-crowdin-download.yml +++ b/.github/workflows/i18n-crowdin-download.yml @@ -3,7 +3,7 @@ name: Crowdin Download Action on: workflow_dispatch: schedule: - - cron: "0 * * * *" + - cron: "0 0 * * *" jobs: download-sources-from-crowdin: @@ -12,6 +12,7 @@ jobs: permissions: contents: write # needed to commit changes into the PR pull-requests: write # needed to update PR description, labels, etc + id-token: write # needed to get vault secrets steps: - name: Generate token @@ -41,17 +42,11 @@ jobs: pull_request_body: | :robot: Automatic download of translations from Crowdin. - Steps for merging: - 1. A quick sanity check of the changes and approve. Things to look out for: - - No changes in the English file. The source of truth is in the main branch, NOT in Crowdin. - - Translations maybe be removed if the English phrase was removed, but there should not be many of these - - Anything else that looks 'funky'. Ask if you're not sure. - 2. Approve & (Auto-)merge. :tada: + This runs once per day and will merge automatically if all the required checks pass. - If there's a conflict, close the pull request and **delete the branch**. A GH action will recreate the pull request. - Remember, the longer this pull request is open, the more likely it is that it'll get conflicts. + If there's a conflict, close the pull request and **delete the branch**. + You can then either wait for the schedule to trigger a new PR, or rerun the action manually. pull_request_labels: 'area/frontend, area/internationalization, no-changelog, no-backport' - pull_request_reviewers: 'grafana-frontend-platform' pull_request_base_branch_name: 'main' base_url: 'https://grafana.api.crowdin.com' config: 'crowdin.yml' @@ -119,3 +114,45 @@ jobs: with: pr: ${{ steps.crowdin-download.outputs.pull_request_number }} token: ${{ steps.generate_token.outputs.token }} + + - name: Get vault secrets + id: vault-secrets + uses: grafana/shared-workflows/actions/get-vault-secrets@main + with: + # Secrets placed in ci/repo/grafana/grafana/grafana-pr-approver + repo_secrets: | + GRAFANA_PR_APPROVER_APP_ID=grafana-pr-approver:app-id + GRAFANA_PR_APPROVER_APP_PEM=grafana-pr-approver:private-key + + - name: Generate approver token + if: steps.crowdin-download.outputs.pull_request_url + id: generate_approver_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ env.GRAFANA_PR_APPROVER_APP_ID }} + private_key: ${{ env.GRAFANA_PR_APPROVER_APP_PEM }} + + - name: Approve and automerge PR + if: steps.crowdin-download.outputs.pull_request_url + shell: bash + # Only approve if: + # - the PR does not modify files other than json files under the public/locales/ directory + # - the PR does not modify the en-US locale + run: | + filesChanged=$(gh pr diff --name-only ${{ steps.crowdin-download.outputs.pull_request_url }}) + + if [[ $(echo $filesChanged | grep -v 'public/locales/[a-zA-Z\-]*/grafana.json' | wc -l) -ne 0 ]]; then + echo "Non-i18n changes detected, not approving" + exit 1 + fi + + if [[ $(echo $filesChanged | grep "public/locales/en-US" | wc -l) -ne 0 ]]; then + echo "public/locales/en-US changes detected, not approving" + exit 1 + fi + + echo "Approving and enabling automerge" + gh pr review ${{ steps.crowdin-download.outputs.pull_request_url }} --approve + gh pr merge --auto --squash ${{ steps.crowdin-download.outputs.pull_request_url }} + env: + GITHUB_TOKEN: ${{ steps.generate_approver_token.outputs.token }} diff --git a/.github/workflows/migrate-prs.yml b/.github/workflows/migrate-prs.yml new file mode 100644 index 00000000000..31bb8f9f9da --- /dev/null +++ b/.github/workflows/migrate-prs.yml @@ -0,0 +1,60 @@ +name: Migrate open PRs +# Migrate open PRs from a superseded release branch to the current release branch and notify authors +on: + workflow_call: + inputs: + from: + description: 'The base branch to check for open PRs' + required: true + type: string + to: + description: 'The base branch to migrate open PRs to' + required: true + type: string + ownerRepo: + description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana') + required: true + type: string + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: + required: true + GRAFANA_DELIVERY_BOT_APP_PEM: + required: true + workflow_dispatch: + inputs: + from: + description: 'The base branch to check for open PRs' + required: true + type: string + to: + description: 'The base branch to migrate open PRs to' + required: true + type: string + ownerRepo: + description: Owner/repo of the repository where the branch is created (e.g. 'grafana/grafana') + required: true + type: string + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: + required: true + GRAFANA_DELIVERY_BOT_APP_PEM: + required: true + +jobs: + main: + runs-on: ubuntu-latest + steps: + - name: "Generate token" + id: generate_token + uses: tibdex/github-app-token@b62528385c34dbc9f38e5f4225ac829252d1ea92 + with: + app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - name: Migrate PRs + uses: grafana/grafana-github-actions-go/migrate-open-prs@main + with: + token: ${{ steps.generate_token.outputs.token }} + ownerRepo: ${{ inputs.ownerRepo }} + from: ${{ inputs.from }} + to: ${{ inputs.to }} + binary_release_tag: 'dev' diff --git a/.github/workflows/pr-backend-code-checks.yml b/.github/workflows/pr-backend-code-checks.yml new file mode 100644 index 00000000000..37073dc28c4 --- /dev/null +++ b/.github/workflows/pr-backend-code-checks.yml @@ -0,0 +1,37 @@ +name: Backend Code Checks +description: Validate go.mod and OpenAPI specifications + +on: + pull_request: + paths-ignore: + - '*.md' + - 'docs/**' + - 'latest.json' + +permissions: + contents: read + +jobs: + validate-configs: + name: Validate Backend Configs + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Verify code generation + run: | + CODEGEN_VERIFY=1 make gen-cue + CODEGEN_VERIFY=1 make gen-jsonnet + + - name: Validate go.mod + run: go run scripts/modowners/modowners.go check go.mod + + - name: Generate and Validate OpenAPI Specs + run: | + make swagger-gen diff --git a/.github/workflows/pr-backend-unit-tests.yml b/.github/workflows/pr-backend-unit-tests.yml new file mode 100644 index 00000000000..99ec9b0ea49 --- /dev/null +++ b/.github/workflows/pr-backend-unit-tests.yml @@ -0,0 +1,78 @@ +name: Backend Unit Tests + +on: + workflow_dispatch: + push: + branches: + - main + paths-ignore: + - 'docs/**' + - '**/*.md' + pull_request: + paths-ignore: + - 'docs/**' + - '**/*.md' + +permissions: + contents: read + id-token: write + +env: + EDITION: 'oss' + WIRE_TAGS: 'oss' + +jobs: + backend-testing-coverage: + name: Backend Testing & Coverage + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: go.mod + cache: true + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y build-essential shared-mime-info + go install github.com/mfridman/tparse@c1754a1f484ac5cd422697b0fec635177ddc8507 # v0.17.0 + + - name: Generate Go code + run: make gen-go + + - name: Run unit tests + run: COVER_OPTS="-coverprofile=be-unit.cov -coverpkg=github.com/grafana/grafana/..." GO_TEST_OUTPUT="/tmp/unit.log" make test-go-unit + + - name: Process and upload coverage + uses: ./.github/actions/test-coverage-processor + with: + test-type: 'be-unit' + # Needs to be named 'unit.cov' based on the Makefile command `make test-go-unit` + coverage-file: 'unit.cov' + codecov-token: ${{ secrets.CODECOV_TOKEN }} + codecov-flag: 'be-unit' + codecov-name: 'be-unit' + + - name: Install Grafana Bench + # We can't allow forks here, as we need secret access. + if: ${{ github.event_name != 'pull_request' }} + uses: ./.github/actions/setup-grafana-bench + + - name: Process output for Bench + if: ${{ github.event_name != 'pull_request' }} + run: | + grafana-bench report \ + --trigger pr-backend-unit-tests-oss \ + --report-input go \ + --report-output log \ + --grafana-version "$(git rev-parse HEAD)" \ + --suite-name grafana-oss-unit-tests \ + /tmp/unit.log + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true diff --git a/.github/workflows/publish-technical-documentation-release.yml b/.github/workflows/publish-technical-documentation-release.yml index b36eb48885a..57d779660c5 100644 --- a/.github/workflows/publish-technical-documentation-release.yml +++ b/.github/workflows/publish-technical-documentation-release.yml @@ -3,7 +3,7 @@ name: publish-technical-documentation-release on: push: branches: - - v[0-9]+.[0-9]+.x + - release-[0-9]+.[0-9]+.[0-9]+ tags: - v[0-9]+.[0-9]+.[0-9]+ paths: @@ -23,7 +23,7 @@ jobs: - uses: grafana/writers-toolkit/publish-technical-documentation-release@publish-technical-documentation-release/v2 with: release_tag_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" - release_branch_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.x$" - release_branch_with_patch_regexp: "^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" + release_branch_regexp: "^release-(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" + release_branch_with_patch_regexp: "^release-(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)$" website_directory: content/docs/grafana version_suffix: "" diff --git a/.github/workflows/release-comms.yml b/.github/workflows/release-comms.yml index 02d53057184..720948e659b 100644 --- a/.github/workflows/release-comms.yml +++ b/.github/workflows/release-comms.yml @@ -19,7 +19,7 @@ on: - closed branches: - 'main' - - 'v*.*.*' + - 'release-*.*.*' jobs: setup: @@ -27,6 +27,7 @@ jobs: name: Setup and establish latest outputs: version: ${{ steps.output.outputs.version }} + release_branch: ${{ steps.output.outputs.release_branch }} dry_run: ${{ steps.output.outputs.dry_run }} latest: ${{ steps.output.outputs.latest }} runs-on: ubuntu-latest @@ -49,9 +50,54 @@ jobs: echo "latest: $LATEST" echo "version: $VERSION" + echo "release_branch=$(echo $VERSION | sed -s 's/^v/release-/g')" >> "$GITHUB_OUTPUT" echo "dry_run=$DRY_RUN" >> "$GITHUB_OUTPUT" echo "latest=$LATEST" >> "$GITHUB_OUTPUT" echo "version=$VERSION" >> "$GITHUB_OUTPUT" + create_next_release_branch_grafana: + name: Create next release branch (Grafana) + needs: setup + uses: ./.github/workflows/create-next-release-branch.yml + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + GRAFANA_DELIVERY_BOT_APP_PEM: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + with: + ownerRepo: 'grafana/grafana' + source: ${{ needs.setup.outputs.release_branch }} + create_next_release_branch_enterprise: + name: Create next release branch (Grafana Enterprise) + needs: setup + uses: ./.github/workflows/create-next-release-branch.yml + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + GRAFANA_DELIVERY_BOT_APP_PEM: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + with: + ownerRepo: 'grafana/grafana-enterprise' + source: ${{ needs.setup.outputs.release_branch }} + migrate_prs_grafana: + needs: + - setup + - create_next_release_branch_grafana + uses: ./.github/workflows/migrate-prs.yml + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + GRAFANA_DELIVERY_BOT_APP_PEM: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + with: + ownerRepo: 'grafana/grafana' + from: ${{ needs.setup.outputs.release_branch }} + to: ${{ needs.create_next_release_branch_grafana.outputs.branch }} + migrate_prs_enterprise: + needs: + - setup + - create_next_release_branch_enterprise + uses: ./.github/workflows/migrate-prs.yml + secrets: + GRAFANA_DELIVERY_BOT_APP_ID: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} + GRAFANA_DELIVERY_BOT_APP_PEM: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + with: + ownerRepo: 'grafana/grafana-enterprise' + from: ${{ needs.setup.outputs.release_branch }} + to: ${{ needs.create_next_release_branch_enterprise.outputs.branch }} post_changelog_on_forum: needs: setup uses: ./.github/workflows/community-release.yml diff --git a/.github/workflows/release-pr.yml b/.github/workflows/release-pr.yml index d6bcd7d5446..1234cdc75ef 100644 --- a/.github/workflows/release-pr.yml +++ b/.github/workflows/release-pr.yml @@ -4,7 +4,7 @@ # Please refrain from including any processes that do not result in code changes in this workflow. Instead, they should # either be triggered in the release promotion process or in the release comms process (that is triggered by merging # this PR). -name: Complete a Grafana release +name: Grafana Release PR on: workflow_dispatch: inputs: @@ -19,7 +19,7 @@ on: target: required: true type: string - description: The base branch that these changes are being merged into + description: The release branch pattern (eg v9.5.x) that these changes are being merged into backport: required: false type: string @@ -61,12 +61,20 @@ jobs: with: app_id: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_ID }} private_key: ${{ secrets.GRAFANA_DELIVERY_BOT_APP_PEM }} + - name: Get release branch + id: branch + uses: grafana/grafana-github-actions-go/latest-release-branch@main + with: + token: ${{ steps.generate_token.outputs.token }} + ownerRepo: 'grafana/grafana' + pattern: ${{ inputs.target }} - name: Checkout Grafana uses: actions/checkout@v4 with: - ref: ${{ inputs.target }} + ref: ${{ steps.branch.outputs.branch }} fetch-depth: 0 fetch-tags: true + token: ${{ steps.generate_token.outputs.token }} - name: Checkout Grafana (main) uses: actions/checkout@v4 with: @@ -74,6 +82,7 @@ jobs: fetch-depth: '0' fetch-tags: 'false' path: .grafana-main + token: ${{ steps.generate_token.outputs.token }} - name: Setup nodejs environment uses: actions/setup-node@v4 with: @@ -124,7 +133,6 @@ jobs: rm -f CHANGELOG.part changelog_items.md git diff CHANGELOG.md - - name: "Prettify CHANGELOG.md" run: npx prettier --write CHANGELOG.md - name: Commit CHANGELOG.md changes @@ -138,6 +146,7 @@ jobs: - name: Add package.json changes run: | git add package.json lerna.json yarn.lock packages public + test -e e2e/test-plugins && git add e2e/test-plugins git commit -m "Update version to ${{ inputs.version }}" - name: Git push @@ -151,7 +160,7 @@ jobs: $( [ "x${{ inputs.latest }}" == "xtrue" ] && printf %s '-l "release/latest"') \ -l "no-changelog" \ --dry-run=${{ inputs.dry_run }} \ - -B "${{ inputs.target }}" \ + -B "${{ steps.branch.outputs.branch }}" \ --title "Release: ${{ inputs.version }}" \ --body "These code changes must be merged after a release is complete" env: @@ -165,7 +174,7 @@ jobs: -l "product-approved" \ -l "no-changelog" \ --dry-run=${{ inputs.dry_run }} \ - -B "${{ inputs.target }}" \ + -B "${{ steps.branch.outputs.branch }}" \ --title "Release: ${{ inputs.version }}" \ --body "These code changes must be merged after a release is complete" env: diff --git a/.github/workflows/run-schema-v2-e2e.yml b/.github/workflows/run-schema-v2-e2e.yml new file mode 100644 index 00000000000..8b55aa4c430 --- /dev/null +++ b/.github/workflows/run-schema-v2-e2e.yml @@ -0,0 +1,44 @@ +name: Run dashboard schema v2 e2e + +on: + push: + branches: + - main + pull_request: + branches: + - '**' + +env: + ARCH: linux-amd64 + +jobs: + dashboard-schema-v2-e2e: + runs-on: ubuntu-latest + continue-on-error: true + if: github.event.pull_request.draft == false + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Pin Go version to mod file + uses: actions/setup-go@v5 + with: + go-version-file: 'go.mod' + - run: go version + - uses: actions/setup-node@v4 + with: + node-version: 20 + cache: 'yarn' + - name: Install dependencies + run: yarn install --immutable + - name: Build grafana + run: make build + - name: Install Cypress dependencies + uses: cypress-io/github-action@v6 + with: + runTests: false + - name: Run dashboard scenes e2e + run: yarn e2e:schema-v2 || echo "Test failed but marking as success since schema V2 is behind a feature flag and should not block PRs" + + - name: Always succeed # This is a workaround to make the job pass even if the previous step fails + if: failure() + run: exit 0 \ No newline at end of file diff --git a/.github/workflows/sbom-report.yml b/.github/workflows/sbom-report.yml deleted file mode 100644 index efd188da331..00000000000 --- a/.github/workflows/sbom-report.yml +++ /dev/null @@ -1,15 +0,0 @@ -name: syft-sbom-ci -on: - release: - types: [ published ] - workflow_dispatch: -jobs: - syft-sbom: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Anchore SBOM Action - uses: grafana/shared-workflows/actions@syft-sbom-v0.0.1 - with: - artifact-name: ${{ github.event.repository.name }}-spdx.json diff --git a/.github/workflows/trivy-scan.yml b/.github/workflows/trivy-scan.yml index b1346236770..25104af8f29 100644 --- a/.github/workflows/trivy-scan.yml +++ b/.github/workflows/trivy-scan.yml @@ -27,11 +27,14 @@ jobs: trivy fs --no-progress --download-db-only --db-repository public.ecr.aws/aquasecurity/trivy-db - name: Run Trivy vulnerability scanner (table output) # Use the trivy binary rather than the aquasecurity/trivy-action action - # to avoid a few bugs - # scan the filesystem, rather than building a Docker image prior - the - # downside is we won't catch dependencies that are only installed in the - # image, but the upside is we'll only catch vulnerabilities that are - # explicitly in the our dependencies + # to avoid a few bugs. + # + # We scan the file system rather than building the Docker image to only scan + # our direct dependencies. The Docker images are still scanned by + # Vulnerability Observability: + # - OSS: https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/projects/sources/1 + # - Enterprise: https://ops.grafana-ops.net/a/grafana-vulnerabilityobs-app/projects/sources/12 + # (If these links are outdated, just go to the list and find the images manually.) run: | trivy fs \ --scanners vuln \ diff --git a/.gitignore b/.gitignore index ac5ad6f5f7d..1a8be100668 100644 --- a/.gitignore +++ b/.gitignore @@ -16,6 +16,7 @@ vendor/ /requests tsconfig.tsbuildinfo __debug_bin* +*.cov # yarn .yarn/cache @@ -40,6 +41,7 @@ __debug_bin* # This is the new place of the block, but I leave the previous here for a while /devenv/docker/blocks/auth/saml-enterprise /devenv/docker/blocks/auth/signer +/devenv/docker/blocks/spanner_tests /tmp tools/phantomjs/phantomjs @@ -103,14 +105,19 @@ profile.cov /pkg/cmd/grafana-cli/grafana-cli /pkg/cmd/grafana-server/grafana-server /pkg/cmd/grafana-server/debug -/pkg/extensions/* -/pkg/build/cmd/artifactspage.go -/pkg/build/cmd/artifactspage.tmpl.html -/pkg/build/cmd/exportversion.go -/pkg/server/wireexts_enterprise.go + +# Extensions /pkg/cmd/grafana-cli/runner/wireexts_enterprise.go +/pkg/server/wireexts_enterprise.go +/pkg/build/cmd/enterprise.go +/pkg/extensions/* +!/pkg/extensions/.keep !/pkg/extensions/main.go +!/pkg/extensions/enterprise_imports.go /public/app/extensions +!/public/app/extensions/.keep + + debug.test /examples/*/dist /packaging/**/*.rpm @@ -141,6 +148,7 @@ pkg/services/quota/quotaimpl/storage/storage.json # Ignoring frontend packages specifics /packages/grafana-ui/.yarn/.cache /packages/grafana-ui/.storybook/static +/packages/grafana-ui/unstable /packages/**/dist /packages/**/compiled /packages/**/.rpt2_cache @@ -170,13 +178,13 @@ compilation-stats.json /e2e/benchmarks/**/results /e2e/build_results.zip /e2e/extensions +!/e2e/extensions/.keep /e2e/extensions-suite /test-results/ /playwright-report/ /blob-report/ /playwright/.cache/ /playwright/.auth/ - # grafana server /scripts/grafana-server/server.log diff --git a/.golangci.yml b/.golangci.yml index 9a49288fb2b..35b9bd1d4ec 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,5 +1,5 @@ run: - timeout: 10m + timeout: 15m concurrency: 10 allow-parallel-runners: true linters-settings: @@ -191,10 +191,10 @@ linters-settings: allow: [] deny: - pkg: github.com/grafana/grafana/pkg - desc: apps/investigation is not allowed to import grafana core + desc: apps/investigations is not allowed to import grafana core files: - - ./apps/investigation/* - - ./apps/investigation/**/* + - ./apps/investigations/* + - ./apps/investigations/**/* gocritic: enabled-checks: - ruleguard diff --git a/.ignore b/.ignore new file mode 100644 index 00000000000..01e1bb8d6e2 --- /dev/null +++ b/.ignore @@ -0,0 +1,22 @@ +# This is a trick to ignore files only by git but not by other tools +!/public/app/extensions +!/pkg/extensions/* +!/pkg/cmd/grafana-cli/runner/wireexts_enterprise.go +!/pkg/server/wireexts_enterprise.go +!/pkg/build/cmd/enterprise.go +!/pkg/extensions/* + +# Enterprise emails +!/emails/templates/enterprise_* +!/public/emails/enterprise_* + +# Enterprise reporting fonts +!/public/fonts/dejavu + +# Enterprise devenv +!/devenv/docker/blocks/grafana-enterprise +!/devenv/docker/blocks/saml-enterprise +# This is the new place of the block, but I leave the previous here for a while +!/devenv/docker/blocks/auth/saml-enterprise +!/devenv/docker/blocks/auth/signer +!/devenv/docker/blocks/spanner_tests \ No newline at end of file diff --git a/.prettierignore b/.prettierignore index 8bf9dc13276..23d9231bc49 100644 --- a/.prettierignore +++ b/.prettierignore @@ -19,6 +19,9 @@ vendor # TS generate from cue by cuetsy **/*.gen.ts +# TS generated by grafana-app-sdk +**/*_gen.ts + # Auto-generated theme files theme.light.generated.json theme.dark.generated.json diff --git a/.vale.ini b/.vale.ini index cf4c71392dc..37e764e6d0f 100644 --- a/.vale.ini +++ b/.vale.ini @@ -1,5 +1,5 @@ MinAlertLevel = warning -[*] +[*.md] BasedOnStyles = Grafana TokenIgnores = (+?), \*\*[^\n]+\*\* diff --git a/.vscode/launch.json b/.vscode/launch.json index 80bafb80307..67c4f82699b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -96,6 +96,15 @@ "NODE_ENV": "test" } }, + { + "name": "Debug ESLint", + "type": "node", + "request": "launch", + "runtimeExecutable": "yarn", + "runtimeArgs": ["run", "eslint", "${file}"], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen" + }, { "name": "Debug Go test", "type": "go", diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bb3ea46a8e..5b7107fc70a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,407 @@ + + +# 11.5.2 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99918](https://github.com/grafana/grafana/pull/99918), [@DanCech](https://github.com/DanCech) +- **TransformationFilter:** Include transformation outputs in transformation filtering options [#99878](https://github.com/grafana/grafana/pull/99878), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) +- **grafana-ui:** Update InlineField error prop type to React.ReactNode [#100373](https://github.com/grafana/grafana/pull/100373), [@Clarity-89](https://github.com/Clarity-89) + +### Bug fixes + +- **Alerting:** Allow specifying uid for new rules added to groups [#100450](https://github.com/grafana/grafana/pull/100450), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Alerting:** Allow specifying uid for new rules added to groups [#100450](https://github.com/grafana/grafana/pull/100450), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Alerting:** Call RLock() before reading sendAlertsTo map [#99880](https://github.com/grafana/grafana/pull/99880), [@santihernandezc](https://github.com/santihernandezc) +- **Auth:** Fix redirect with JWT auth URL login [#100355](https://github.com/grafana/grafana/pull/100355), [@mgyongyosi](https://github.com/mgyongyosi) +- **AuthN:** Refetch user on "ErrUserAlreadyExists" [#100582](https://github.com/grafana/grafana/pull/100582), [@kalleep](https://github.com/kalleep) +- **Azure:** Correctly set application insights resource values [#99599](https://github.com/grafana/grafana/pull/99599), [@aangelisc](https://github.com/aangelisc) +- **CodeEditor:** Fix cursor alignment [#99863](https://github.com/grafana/grafana/pull/99863), [@ashharrison90](https://github.com/ashharrison90) +- **DashboardList:** Throttle the re-renders [#100046](https://github.com/grafana/grafana/pull/100046), [@bfmatei](https://github.com/bfmatei) +- **Dashboards:** Bring back scripted dashboards [#100633](https://github.com/grafana/grafana/pull/100633), [@dprokop](https://github.com/dprokop) +- **Plugin Metrics:** Eliminate data race in plugin metrics middleware [#100078](https://github.com/grafana/grafana/pull/100078), [@clord](https://github.com/clord) +- **RBAC:** Don't check folder access if `annotationPermissionUpdate` FT is enabled [#100117](https://github.com/grafana/grafana/pull/100117), [@IevaVasiljeva](https://github.com/IevaVasiljeva) + + + + +# 11.4.2 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99924](https://github.com/grafana/grafana/pull/99924), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Auth:** Fix redirect with JWT auth URL login [#100494](https://github.com/grafana/grafana/pull/100494), [@mgyongyosi](https://github.com/mgyongyosi) +- **AuthN:** Refetch user on "ErrUserAlreadyExists" [#100585](https://github.com/grafana/grafana/pull/100585), [@kalleep](https://github.com/kalleep) +- **Azure:** Correctly set application insights resource values [#99598](https://github.com/grafana/grafana/pull/99598), [@aangelisc](https://github.com/aangelisc) +- **Dashboards:** Bring back scripted dashboards [#100629](https://github.com/grafana/grafana/pull/100629), [@dprokop](https://github.com/dprokop) +- **Plugin Metrics:** Eliminate data race in plugin metrics middleware [#100077](https://github.com/grafana/grafana/pull/100077), [@clord](https://github.com/clord) +- **RBAC:** Don't check folder access if `annotationPermissionUpdate` FT is enabled [#100116](https://github.com/grafana/grafana/pull/100116), [@IevaVasiljeva](https://github.com/IevaVasiljeva) + + + + +# 11.3.4 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99923](https://github.com/grafana/grafana/pull/99923), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Auth:** Fix redirect with JWT auth URL login [#100495](https://github.com/grafana/grafana/pull/100495), [@mgyongyosi](https://github.com/mgyongyosi) +- **Azure:** Correctly set application insights resource values [#99597](https://github.com/grafana/grafana/pull/99597), [@aangelisc](https://github.com/aangelisc) +- **Dashboards:** Bring back scripted dashboards [#100627](https://github.com/grafana/grafana/pull/100627), [@dprokop](https://github.com/dprokop) +- **Plugin Metrics:** Eliminate data race in plugin metrics middleware [#100076](https://github.com/grafana/grafana/pull/100076), [@clord](https://github.com/clord) + + + + +# 11.2.7 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99922](https://github.com/grafana/grafana/pull/99922), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Azure:** Correctly set application insights resource values [#99596](https://github.com/grafana/grafana/pull/99596), [@aangelisc](https://github.com/aangelisc) + + + + +# 11.1.12 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99917](https://github.com/grafana/grafana/pull/99917), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Azure:** Correctly set application insights resource values [#99595](https://github.com/grafana/grafana/pull/99595), [@aangelisc](https://github.com/aangelisc) + + + + +# 11.0.11 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#100730](https://github.com/grafana/grafana/pull/100730), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Azure:** Correctly set application insights resource values [#99594](https://github.com/grafana/grafana/pull/99594), [@aangelisc](https://github.com/aangelisc) + + + + +# 10.4.16 (2025-02-18) + +### Features and enhancements + +- **Docker:** Use our own glibc 2.40 binaries [#99920](https://github.com/grafana/grafana/pull/99920), [@DanCech](https://github.com/DanCech) + +### Bug fixes + +- **Dashboard:** Fix for overwriting an edited dashboard in the old architecture [#100288](https://github.com/grafana/grafana/pull/100288), [@bfmatei](https://github.com/bfmatei) + + + + +# 11.5.1 (2025-02-03) + +### Bug fixes + +- **CodeEditor:** Fix cursor alignment [#99090](https://github.com/grafana/grafana/pull/99090), [@ashharrison90](https://github.com/ashharrison90) +- **TransformationFilter**: Include transformation outputs in transformation filtering options: Include transformation outputs in transformation filtering options [#98323](https://github.com/grafana/grafana/pull/98323), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) + + + + +# 11.5.0 (2025-01-28) + +### Features and enhancements + +- ** CloudMigration:** Create authapi service [#96581](https://github.com/grafana/grafana/pull/96581), [@leandro-deveikis](https://github.com/leandro-deveikis) +- **Alerting:** Add new button for exporting new alert rule in HCL format [#96785](https://github.com/grafana/grafana/pull/96785), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Add option to show inactive alerts in alert list panel [#96888](https://github.com/grafana/grafana/pull/96888), [@bradleypettit](https://github.com/bradleypettit) +- **Alerting:** Add state_periodic_save_batch_size config option [#98019](https://github.com/grafana/grafana/pull/98019), [@alexander-akhmetov](https://github.com/alexander-akhmetov) +- **Alerting:** Change default for max_attempts to 3. [#97461](https://github.com/grafana/grafana/pull/97461), [@stevesg](https://github.com/stevesg) +- **Alerting:** Consume k8s API for notification policies tree [#96147](https://github.com/grafana/grafana/pull/96147), [@konrad147](https://github.com/konrad147) +- **Alerting:** Enable flag alertingApiServer by default [#98282](https://github.com/grafana/grafana/pull/98282), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Alerting:** Explore button in Insights view [#96496](https://github.com/grafana/grafana/pull/96496), [@ppcano](https://github.com/ppcano) +- **Alerting:** Improve performance ash page [#97619](https://github.com/grafana/grafana/pull/97619), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Make alert rule policies preview use k8s API [#97070](https://github.com/grafana/grafana/pull/97070), [@tomratcliffe](https://github.com/tomratcliffe) +- **Alerting:** Return default builtin templates in k8s templategroup API and UI [#96330](https://github.com/grafana/grafana/pull/96330), [@JacobsonMT](https://github.com/JacobsonMT) +- **Alerting:** Simplify notification step [#96430](https://github.com/grafana/grafana/pull/96430), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Update state manager to take image only once per rule evaluation [#98289](https://github.com/grafana/grafana/pull/98289), [@yuri-tceretian](https://github.com/yuri-tceretian) +- **Analytics Views:** Deprecate :dashboardID endpoints in favor of uid/:dashboardUID (Enterprise) +- **Analytics:** Summaries: Deprecate dashboard_id endpoints in favor of dashboard_uid (Enterprise) +- **Announcement Banners:** Enable feature for all cloud tiers (Enterprise) +- **Announcement banner:** Remove feature toggle [#98782](https://github.com/grafana/grafana/pull/98782), [@Clarity-89](https://github.com/Clarity-89) +- **Announcement banner:** Remove feature toggle (Enterprise) +- **Announcement banner:** Sort by last updated (Enterprise) +- **Auth:** Return error when retries have been exhausted for OAuth token refresh [#98034](https://github.com/grafana/grafana/pull/98034), [@mgyongyosi](https://github.com/mgyongyosi) +- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#96858](https://github.com/grafana/grafana/pull/96858), [@adamyeats](https://github.com/adamyeats) +- **Azure:** Improve Azure Prometheus exemplars UI/UX [#97198](https://github.com/grafana/grafana/pull/97198), [@aangelisc](https://github.com/aangelisc) +- **Azure:** Unify credentials in frontend for Prometheus [#96568](https://github.com/grafana/grafana/pull/96568), [@yjsong11](https://github.com/yjsong11) +- **Chore:** Bump Go to 1.23.4 [#98853](https://github.com/grafana/grafana/pull/98853), [@Proximyst](https://github.com/Proximyst) +- **Chore:** Bump Go to 1.23.4 (Enterprise) +- **Chore:** Remove experimental Storage UI [#96887](https://github.com/grafana/grafana/pull/96887), [@ryantxu](https://github.com/ryantxu) +- **Chore:** Update to node 22 [#97779](https://github.com/grafana/grafana/pull/97779), [@ashharrison90](https://github.com/ashharrison90) +- **CloudMigrations:** Enable feature toggle by default in 11.5 [#98686](https://github.com/grafana/grafana/pull/98686), [@mmandrus](https://github.com/mmandrus) +- **CloudMigrations:** Introduce RBAC role for migration assistant [#98588](https://github.com/grafana/grafana/pull/98588), [@macabu](https://github.com/macabu) +- **CloudWatch:** Add OpenSearch PPL and SQL support in Logs Insights [#97508](https://github.com/grafana/grafana/pull/97508), [@idastambuk](https://github.com/idastambuk) +- **CloudWatch:** Batch different time ranges separately [#98230](https://github.com/grafana/grafana/pull/98230), [@iwysiu](https://github.com/iwysiu) +- **Cloudwatch:** Accept empty string for logstimeout and mark errors downstream [#96947](https://github.com/grafana/grafana/pull/96947), [@iwysiu](https://github.com/iwysiu) +- **Cloudwatch:** Update grafana-aws-sdk for AWS/AmplifyHosting metrics [#97799](https://github.com/grafana/grafana/pull/97799), [@iwysiu](https://github.com/iwysiu) +- **Dashboard Scene:** Shows usages in variables list [#96000](https://github.com/grafana/grafana/pull/96000), [@harisrozajac](https://github.com/harisrozajac) +- **Dashboards:** Add option to specify explicit percent change text size for stat panels [#96952](https://github.com/grafana/grafana/pull/96952), [@XZCendence](https://github.com/XZCendence) +- **Dashboards:** Allow DashboardDS subqueries in MixedDS [#97116](https://github.com/grafana/grafana/pull/97116), [@mdvictor](https://github.com/mdvictor) +- **Dashboards:** Update docs of the `overwrite` param in Save Dashboard API Call [#97011](https://github.com/grafana/grafana/pull/97011), [@ArturWierzbicki](https://github.com/ArturWierzbicki) +- **Datasources:** Add toggle to control default behaviour of 'Manage alerts via Alerts UI' toggle [#98441](https://github.com/grafana/grafana/pull/98441), [@macabu](https://github.com/macabu) +- **Datasources:** Allow clearing trace to logs, metrics and profiles datasource pickers [#96554](https://github.com/grafana/grafana/pull/96554), [@adrapereira](https://github.com/adrapereira) +- **Docker:** Don't use legacy ENV syntax [#93218](https://github.com/grafana/grafana/pull/93218), [@simPod](https://github.com/simPod) +- **Elasticsearch:** Health endpoint should handle http errors [#96803](https://github.com/grafana/grafana/pull/96803), [@iwysiu](https://github.com/iwysiu) +- **Elasticsearch:** Use \_field_caps instead of \_mapping to get fields [#97607](https://github.com/grafana/grafana/pull/97607), [@iwysiu](https://github.com/iwysiu) +- **Explore Profiles:** Preinstall for onprem Grafana instances [#97775](https://github.com/grafana/grafana/pull/97775), [@ifrost](https://github.com/ifrost) +- **Explore metrics:** Consolidate filters with the OTel experience [#98371](https://github.com/grafana/grafana/pull/98371), [@bohandley](https://github.com/bohandley) +- **Explore:** Show links to queryless apps [#96625](https://github.com/grafana/grafana/pull/96625), [@ifrost](https://github.com/ifrost) +- **Expressions:** Add notification for Strict Mode behavior in Reduce component [#97224](https://github.com/grafana/grafana/pull/97224), [@shubhankarunhale](https://github.com/shubhankarunhale) +- **Faro:** Improve performance of TRACKING_URLS regex [#98022](https://github.com/grafana/grafana/pull/98022), [@kpelelis](https://github.com/kpelelis) +- **FeatureToggles:** Make newFiltersUI feature toggle generally available [#97460](https://github.com/grafana/grafana/pull/97460), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) +- **Features:** Remove cloudwatchMetricInsightsCrossAccount feature toggle [#98826](https://github.com/grafana/grafana/pull/98826), [@idastambuk](https://github.com/idastambuk) +- **Frontend Sandbox:** Add switch to toggle plugins frontend sandbox via catalog UI (Enterprise) +- **Graphite:** Set `maxDataPoints` based on user value in alerting [#97178](https://github.com/grafana/grafana/pull/97178), [@aangelisc](https://github.com/aangelisc) +- **Licensing:** Tidy up license token database code (Enterprise) +- **LoginAttempt:** Add setting to control max number of attempts before user login gets locked [#97091](https://github.com/grafana/grafana/pull/97091), [@kalleep](https://github.com/kalleep) +- **Logs Panel:** Add infinite scrolling support for Dashboards and Apps [#97095](https://github.com/grafana/grafana/pull/97095), [@matyax](https://github.com/matyax) +- **Logs Panel:** Allow text selection without changing Log Details state [#96995](https://github.com/grafana/grafana/pull/96995), [@matyax](https://github.com/matyax) +- **Logs Panel:** Limit displayed characters to MAX_CHARACTERS [#96997](https://github.com/grafana/grafana/pull/96997), [@matyax](https://github.com/matyax) +- **Logs:** Added option to show the log line body when displayed fields are used [#97209](https://github.com/grafana/grafana/pull/97209), [@matyax](https://github.com/matyax) +- **Logs:** Added support to disable and re-enable the popover menu [#98254](https://github.com/grafana/grafana/pull/98254), [@matyax](https://github.com/matyax) +- **Logs:** Allow scroll to reach the bottom of the log list before loading more [#96668](https://github.com/grafana/grafana/pull/96668), [@matyax](https://github.com/matyax) +- **Loki:** Added support for disabled operations in Query Builder [#96751](https://github.com/grafana/grafana/pull/96751), [@matyax](https://github.com/matyax) +- **Loki:** Added support to show label types in Log Details [#97284](https://github.com/grafana/grafana/pull/97284), [@matyax](https://github.com/matyax) +- **Loki:** Allow regex in `label` derived field [#96609](https://github.com/grafana/grafana/pull/96609), [@svennergr](https://github.com/svennergr) +- **Loki:** Hide internal labels [#97323](https://github.com/grafana/grafana/pull/97323), [@svennergr](https://github.com/svennergr) +- **Loki:** Sync query direction with sort order in Explore and Dashboards [#98722](https://github.com/grafana/grafana/pull/98722), [@matyax](https://github.com/matyax) +- **OAuth:** Support client_secret_jwt for oauth providers when doing token exchange [#95455](https://github.com/grafana/grafana/pull/95455), [@naizerjohn-ms](https://github.com/naizerjohn-ms) +- **OAuth:** Use the attached external session data in OAuthToken and OAuthTokenSync [#96655](https://github.com/grafana/grafana/pull/96655), [@mgyongyosi](https://github.com/mgyongyosi) +- **Org Selection:** Show correct selected org when select is open [#96601](https://github.com/grafana/grafana/pull/96601), [@yincongcyincong](https://github.com/yincongcyincong) +- **PDF:** Add new zoom options (Enterprise) +- **Plugin Extensions:** Only load app plugins when necessary [#86624](https://github.com/grafana/grafana/pull/86624), [@leventebalogh](https://github.com/leventebalogh) +- **Plugins:** Add token to gcom requests [#96261](https://github.com/grafana/grafana/pull/96261), [@oshirohugo](https://github.com/oshirohugo) +- **Plugins:** Add token to gcom requests (Enterprise) +- **Plugins:** Disable version install when angular version is not supported [#97189](https://github.com/grafana/grafana/pull/97189), [@oshirohugo](https://github.com/oshirohugo) +- **Plugins:** Disable version installation for specific plugin types [#98597](https://github.com/grafana/grafana/pull/98597), [@oshirohugo](https://github.com/oshirohugo) +- **Plugins:** Update to latest go plugin SDK (v0.260.3) w/ arrow v18 [#97561](https://github.com/grafana/grafana/pull/97561), [@ryantxu](https://github.com/ryantxu) +- **Plugins:** Use grafana-com sso_api_token [#97096](https://github.com/grafana/grafana/pull/97096), [@oshirohugo](https://github.com/oshirohugo) +- **Plugins:** Use grafana-com sso_api_token (Enterprise) +- **Prometheus datasource:** Show info annotations in the UI [#97978](https://github.com/grafana/grafana/pull/97978), [@zenador](https://github.com/zenador) +- **Prometheus:** Improve handling of special chars in label values [#96067](https://github.com/grafana/grafana/pull/96067), [@NWRichmond](https://github.com/NWRichmond) +- **PublicDashboards:** Remove publicDashboards FF [#96578](https://github.com/grafana/grafana/pull/96578), [@juanicabanas](https://github.com/juanicabanas) +- **Reporting:** Add allow list email domain configuration (Enterprise) +- **Reporting:** Include the apiserver by default and deprecated internal ids (Enterprise) +- **RuntimeDataSource:** Support in core for runtime registered data sources [#93956](https://github.com/grafana/grafana/pull/93956), [@torkelo](https://github.com/torkelo) +- **SAML:** Add the ability to specify EntityID (Enterprise) +- **SAML:** Implement correct SLO with NameID and SessionIndex handling (Enterprise) +- **Security:** Update to Go 1.23.5 - Backport to v11.5.x [#99122](https://github.com/grafana/grafana/pull/99122), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.23.5 - Backport to v11.5.x (Enterprise) +- **Snapshots:** Add RBAC roles for creating and deleting [#96126](https://github.com/grafana/grafana/pull/96126), [@evictorero](https://github.com/evictorero) +- **Storage:** Removes integration tests for MySQL 5.7 since it is EOL [#98013](https://github.com/grafana/grafana/pull/98013), [@inf0rmer](https://github.com/inf0rmer) +- **Tempo:** Add support for TraceQL Metrics exemplars [#96859](https://github.com/grafana/grafana/pull/96859), [@adrapereira](https://github.com/adrapereira) +- **Tempo:** Honor datasource TLS settings for gRPC requests [#97484](https://github.com/grafana/grafana/pull/97484), [@mdisibio](https://github.com/mdisibio) +- **Tempo:** Improve handling of multiple values in the Search tab query generation [#98427](https://github.com/grafana/grafana/pull/98427), [@adrapereira](https://github.com/adrapereira) +- **ToolbarButton:** Auto width on smaller screen sizes [#96023](https://github.com/grafana/grafana/pull/96023), [@yincongcyincong](https://github.com/yincongcyincong) +- **Trace View:** Set span filters as panel options [#98328](https://github.com/grafana/grafana/pull/98328), [@adrapereira](https://github.com/adrapereira) +- **TransformationFilter:** Implement RefID multi picker [#96841](https://github.com/grafana/grafana/pull/96841), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) +- **Transformations:** Add Delimiter format option to Extract fields [#97340](https://github.com/grafana/grafana/pull/97340), [@tskarhed](https://github.com/tskarhed) +- **Transformations:** Add RegExp option to Extract fields transformer [#96593](https://github.com/grafana/grafana/pull/96593), [@leeoniya](https://github.com/leeoniya) +- **Transformations:** GroupToMatrix add 0 as special value [#97642](https://github.com/grafana/grafana/pull/97642), [@tskarhed](https://github.com/tskarhed) +- **Zipkin:** Run queries through backend [#97754](https://github.com/grafana/grafana/pull/97754), [@ivanahuckova](https://github.com/ivanahuckova) + +### Bug fixes + +- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97528](https://github.com/grafana/grafana/pull/97528), [@gillesdemey](https://github.com/gillesdemey) +- **Alerting:** Allow notification policy filters to match quoted matchers [#98525](https://github.com/grafana/grafana/pull/98525), [@gillesdemey](https://github.com/gillesdemey) +- **Alerting:** Fix alert rule list view summaries [#98433](https://github.com/grafana/grafana/pull/98433), [@yincongcyincong](https://github.com/yincongcyincong) +- **Alerting:** Fix alert rules unpausing after moving rule to different folder [#97580](https://github.com/grafana/grafana/pull/97580), [@santihernandezc](https://github.com/santihernandezc) +- **Alerting:** Fix ash not showing history graph in firefox [#98128](https://github.com/grafana/grafana/pull/98128), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix bug when saving a rule more than once [#96658](https://github.com/grafana/grafana/pull/96658), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix data-testid in RuleEditorSection [#97473](https://github.com/grafana/grafana/pull/97473), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix filtering rule group permissions based on their full path (Enterprise) +- **Alerting:** Fix go template parsing [#97145](https://github.com/grafana/grafana/pull/97145), [@konrad147](https://github.com/konrad147) +- **Alerting:** Fix label escaping in rule export [#97985](https://github.com/grafana/grafana/pull/97985), [@moustafab](https://github.com/moustafab) +- **Alerting:** Fix missing instances and history when Grafana rule is stored in folder with / [#97956](https://github.com/grafana/grafana/pull/97956), [@gillesdemey](https://github.com/gillesdemey) +- **Alerting:** Fix navigating to URLs with "%25" [#96992](https://github.com/grafana/grafana/pull/96992), [@gillesdemey](https://github.com/gillesdemey) +- **Alerting:** Fix no-change scenario in provisioning rule update API [#98389](https://github.com/grafana/grafana/pull/98389), [@alexander-akhmetov](https://github.com/alexander-akhmetov) +- **Alerting:** Fix not being able to remove a reducer when using range query [#97757](https://github.com/grafana/grafana/pull/97757), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix recording rules rendering simplified condition [#97497](https://github.com/grafana/grafana/pull/97497), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix removing reducer when inital value is instant [#97054](https://github.com/grafana/grafana/pull/97054), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix simplified query step [#97046](https://github.com/grafana/grafana/pull/97046), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix slack image uploading to use new api [#97817](https://github.com/grafana/grafana/pull/97817), [@moustafab](https://github.com/moustafab) +- **Alerting:** Fix terraform export of notification policy [#98429](https://github.com/grafana/grafana/pull/98429), [@moustafab](https://github.com/moustafab) +- **Alerting:** Fix updating condition when refId changes [#97753](https://github.com/grafana/grafana/pull/97753), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Alerting:** Fix using stacks- prefix instead of stack- for checking the namespace in boot data [#97492](https://github.com/grafana/grafana/pull/97492), [@soniaAguilarPeiron](https://github.com/soniaAguilarPeiron) +- **Anonymous User:** Adds validator service for anonymous users (Enterprise) +- **Auth:** Fix SAML user IsExternallySynced not being set correctly [#98487](https://github.com/grafana/grafana/pull/98487), [@volcanonoodle](https://github.com/volcanonoodle) +- **Azure Monitor:** Add safety around usage of frame.Meta.Custom struct [#97766](https://github.com/grafana/grafana/pull/97766), [@adamyeats](https://github.com/adamyeats) +- **Azure/GCM:** Improve error display [#96921](https://github.com/grafana/grafana/pull/96921), [@aangelisc](https://github.com/aangelisc) +- **CloudWatch:** Fix conditions for fetching wildcards [#98648](https://github.com/grafana/grafana/pull/98648), [@iwysiu](https://github.com/iwysiu) +- **CloudWatch:** Fix interpolation of log groups when fetching fields [#98054](https://github.com/grafana/grafana/pull/98054), [@idastambuk](https://github.com/idastambuk) +- **Dashboard:** Fixes issue with compatability of old DashboardModel.annotations [#97328](https://github.com/grafana/grafana/pull/97328), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98718](https://github.com/grafana/grafana/pull/98718), [@oscarkilhed](https://github.com/oscarkilhed) +- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98167](https://github.com/grafana/grafana/pull/98167), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Panel react for `timeFrom` and `timeShift` changes using variables [#98510](https://github.com/grafana/grafana/pull/98510), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) +- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97888](https://github.com/grafana/grafana/pull/97888), [@torkelo](https://github.com/torkelo) +- **Fix:** Add support for datasource variable queries [#98098](https://github.com/grafana/grafana/pull/98098), [@sunker](https://github.com/sunker) +- **Fix:** Do not fetch Orgs if the user is authenticated by apikey/sa or render key [#97162](https://github.com/grafana/grafana/pull/97162), [@mgyongyosi](https://github.com/mgyongyosi) +- **Fix:** Double encoding of URLs when using data proxy [#98494](https://github.com/grafana/grafana/pull/98494), [@s4kh](https://github.com/s4kh) +- **Font:** Disable contextual font ligatures [#98521](https://github.com/grafana/grafana/pull/98521), [@ashharrison90](https://github.com/ashharrison90) +- **GrafanaUI:** Fix inconsistent controlled/uncontrolled state in AutoSizeInput [#96696](https://github.com/grafana/grafana/pull/96696), [@joshhunt](https://github.com/joshhunt) +- **GrafanaUI:** Revert: Fix inconsistent controlled/uncontrolled state in AutoSizeInput [#97551](https://github.com/grafana/grafana/pull/97551), [@itsmylife](https://github.com/itsmylife) +- **InfluxDB:** Adhoc filters can use template vars as values [#98567](https://github.com/grafana/grafana/pull/98567), [@bossinc](https://github.com/bossinc) +- **Library Panel:** Fix issue where library panels did not display panel links. [#98655](https://github.com/grafana/grafana/pull/98655), [@yincongcyincong](https://github.com/yincongcyincong) +- **LibraryPanel:** Fallback to panel title if library panel title is not set [#99411](https://github.com/grafana/grafana/pull/99411), [@ivanortegaalba](https://github.com/ivanortegaalba) +- **Loki:** Fix a bug when reading frames without values but warnings [#97197](https://github.com/grafana/grafana/pull/97197), [@svennergr](https://github.com/svennergr) +- **Loki:** Only hide a set of labels instead of every label starting with `__` [#98730](https://github.com/grafana/grafana/pull/98730), [@svennergr](https://github.com/svennergr) +- **Org:** Fix redirection logic to work consistently [#96521](https://github.com/grafana/grafana/pull/96521), [@yincongcyincong](https://github.com/yincongcyincong) +- **Panel inspect:** Fix file names of data download included uninterpolated variable names. [#98832](https://github.com/grafana/grafana/pull/98832), [@alexrosenfeld10](https://github.com/alexrosenfeld10) +- **Scenes:** Upgrade to 5.36.3 [#98661](https://github.com/grafana/grafana/pull/98661), [@ivanortegaalba](https://github.com/ivanortegaalba) +- **Snapshot:** Show proper breadcrumb path [#98806](https://github.com/grafana/grafana/pull/98806), [@ashharrison90](https://github.com/ashharrison90) +- **Time Picker:** Fix "Fiscal year start month" selection behaviour [#98576](https://github.com/grafana/grafana/pull/98576), [@ashharrison90](https://github.com/ashharrison90) +- **Unified Storage:** Add support for verify-full in postgres [#96825](https://github.com/grafana/grafana/pull/96825), [@chaudyg](https://github.com/chaudyg) +- **Unified Storage:** Use tls preferred when grafana db using ssl [#97378](https://github.com/grafana/grafana/pull/97378), [@owensmallwood](https://github.com/owensmallwood) +- **Usage Insights:** Fix usage insight errors being logged as [object Object] [#93502](https://github.com/grafana/grafana/pull/93502), [@mmandrus](https://github.com/mmandrus) + +### Breaking changes + +- **Loki:** Default to `/labels` API with `query` param instead of `/series` API [#97935](https://github.com/grafana/grafana/pull/97935), [@svennergr](https://github.com/svennergr) + +### Plugin development fixes & changes + +- **Grafana UI:** Re-add react-router-dom as a dependency [#97540](https://github.com/grafana/grafana/pull/97540), [@leventebalogh](https://github.com/leventebalogh) + + + + +# 11.4.1 (2025-01-28) + +### Features and enhancements + +- **Security:** Update to Go 1.23.5 - Backport to v11.4.x [#99123](https://github.com/grafana/grafana/pull/99123), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.23.5 - Backport to v11.4.x (Enterprise) + +### Bug fixes + +- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97830](https://github.com/grafana/grafana/pull/97830), [@gillesdemey](https://github.com/gillesdemey) +- **Alerting:** Fix alert rules unpausing after moving rule to different folder [#97583](https://github.com/grafana/grafana/pull/97583), [@santihernandezc](https://github.com/santihernandezc) +- **Alerting:** Fix label escaping in rule export [#98649](https://github.com/grafana/grafana/pull/98649), [@moustafab](https://github.com/moustafab) +- **Alerting:** Fix slack image uploading to use new api [#98066](https://github.com/grafana/grafana/pull/98066), [@moustafab](https://github.com/moustafab) +- **Azure/GCM:** Improve error display [#97594](https://github.com/grafana/grafana/pull/97594), [@aangelisc](https://github.com/aangelisc) +- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98734](https://github.com/grafana/grafana/pull/98734), [@oscarkilhed](https://github.com/oscarkilhed) +- **Dashboards:** Fixes issue with panel header showing even when hide time override was enabled [#98747](https://github.com/grafana/grafana/pull/98747), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98269](https://github.com/grafana/grafana/pull/98269), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Panel react for `timeFrom` and `timeShift` changes using variables [#98659](https://github.com/grafana/grafana/pull/98659), [@Sergej-Vlasov](https://github.com/Sergej-Vlasov) +- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97971](https://github.com/grafana/grafana/pull/97971), [@torkelo](https://github.com/torkelo) +- **Fix:** Add support for datasource variable queries [#98119](https://github.com/grafana/grafana/pull/98119), [@sunker](https://github.com/sunker) +- **InfluxDB:** Adhoc filters can use template vars as values [#98786](https://github.com/grafana/grafana/pull/98786), [@bossinc](https://github.com/bossinc) +- **LibraryPanel:** Fallback to panel title if library panel title is not set [#99410](https://github.com/grafana/grafana/pull/99410), [@ivanortegaalba](https://github.com/ivanortegaalba) + +### Plugin development fixes & changes + +- **Grafana UI:** Re-add react-router-dom as a dependency [#98422](https://github.com/grafana/grafana/pull/98422), [@leventebalogh](https://github.com/leventebalogh) + + + + +# 11.3.3 (2025-01-28) + +### Features and enhancements + +- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#97576](https://github.com/grafana/grafana/pull/97576), [@adamyeats](https://github.com/adamyeats) +- **Security:** Update to Go 1.23.5 - Backport to v11.3.x [#99124](https://github.com/grafana/grafana/pull/99124), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.23.5 - Backport to v11.3.x (Enterprise) + +### Bug fixes + +- **Alerting:** AlertingQueryRunner should skip descendant nodes of invalid queries [#97829](https://github.com/grafana/grafana/pull/97829), [@gillesdemey](https://github.com/gillesdemey) +- **Azure/GCM:** Improve error display [#97593](https://github.com/grafana/grafana/pull/97593), [@aangelisc](https://github.com/aangelisc) +- **Dashboard:** Fixes issue with compatability of old DashboardModel.annotations [#97467](https://github.com/grafana/grafana/pull/97467), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Fix issue where filtered panels would not react to variable changes [#98733](https://github.com/grafana/grafana/pull/98733), [@oscarkilhed](https://github.com/oscarkilhed) +- **Dashboards:** Fixes issue with panel header showing even when hide time override was enabled [#97389](https://github.com/grafana/grafana/pull/97389), [@torkelo](https://github.com/torkelo) +- **Dashboards:** Fixes week relative time ranges when weekStart was changed [#98268](https://github.com/grafana/grafana/pull/98268), [@torkelo](https://github.com/torkelo) +- **DateTimePicker:** Fixes issue with date picker showing invalid date [#97970](https://github.com/grafana/grafana/pull/97970), [@torkelo](https://github.com/torkelo) +- **Fix:** Add support for datasource variable queries [#98118](https://github.com/grafana/grafana/pull/98118), [@sunker](https://github.com/sunker) +- **InfluxDB:** Adhoc filters can use template vars as values [#98785](https://github.com/grafana/grafana/pull/98785), [@bossinc](https://github.com/bossinc) +- **Unified Storage:** Use tls preferred when grafana db using ssl [#97379](https://github.com/grafana/grafana/pull/97379), [@owensmallwood](https://github.com/owensmallwood) + +### Plugin development fixes & changes + +- **Grafana UI:** Re-add react-router-dom as a dependency [#98421](https://github.com/grafana/grafana/pull/98421), [@leventebalogh](https://github.com/leventebalogh) + + + + +# 11.2.6 (2025-01-28) + +### Features and enhancements + +- **Azure Monitor:** Add a feature flag to toggle user auth for Azure Monitor only [#97565](https://github.com/grafana/grafana/pull/97565), [@adamyeats](https://github.com/adamyeats) +- **Security:** Update to Go 1.22.11 - Backport to v11.2.x [#99125](https://github.com/grafana/grafana/pull/99125), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.22.11 - Backport to v11.2.x (Enterprise) + +### Bug fixes + +- **Azure/GCM:** Improve error display [#97591](https://github.com/grafana/grafana/pull/97591), [@aangelisc](https://github.com/aangelisc) + + + + +# 11.1.11 (2025-01-28) + +### Features and enhancements + +- **Security:** Update to Go 1.22.11 - Backport to v11.1.x [#99126](https://github.com/grafana/grafana/pull/99126), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.22.11 - Backport to v11.1.x (Enterprise) + +### Bug fixes + +- **Azure/GCM:** Improve error display [#97595](https://github.com/grafana/grafana/pull/97595), [@aangelisc](https://github.com/aangelisc) + + + + +# 11.0.10 (2025-01-28) + +### Features and enhancements + +- **Security:** Update to Go 1.22.11 - Backport to v11.0.x [#99127](https://github.com/grafana/grafana/pull/99127), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.22.11 - Backport to v11.0.x (Enterprise) + +### Bug fixes + +- **Azure/GCM:** Improve error display [#97592](https://github.com/grafana/grafana/pull/97592), [@aangelisc](https://github.com/aangelisc) + + + + +# 10.4.15 (2025-01-28) + +### Features and enhancements + +- **Security:** Update to Go 1.22.11 - Backport to v10.4.x [#99128](https://github.com/grafana/grafana/pull/99128), [@Proximyst](https://github.com/Proximyst) +- **Security:** Update to Go 1.22.11 - Backport to v10.4.x (Enterprise) + +### Bug fixes + +- **Azure/GCM:** Improve error display [#97590](https://github.com/grafana/grafana/pull/97590), [@aangelisc](https://github.com/aangelisc) + + # 11.4.0 (2024-12-05) diff --git a/Dockerfile b/Dockerfile index 7f05689eef2..1ba856b9220 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,13 +1,19 @@ +# syntax=docker/dockerfile:1 -ARG BASE_IMAGE=alpine:3.20 +# to maintain formatting of multiline commands in vscode, add the following to settings.json: +# "docker.languageserver.formatter.ignoreMultilineInstructions": true + +ARG BASE_IMAGE=alpine:3.21 ARG JS_IMAGE=node:22-alpine ARG JS_PLATFORM=linux/amd64 -ARG GO_IMAGE=golang:1.23.5-alpine +ARG GO_IMAGE=golang:1.23.7-alpine +# Default to building locally ARG GO_SRC=go-builder ARG JS_SRC=js-builder -FROM --platform=${JS_PLATFORM} ${JS_IMAGE} as js-builder +# Javascript build stage +FROM --platform=${JS_PLATFORM} ${JS_IMAGE} AS js-builder ENV NODE_OPTIONS=--max_old_space_size=8000 @@ -32,7 +38,8 @@ COPY emails emails ENV NODE_ENV=production RUN yarn build -FROM ${GO_IMAGE} as go-builder +# Golang build stage +FROM ${GO_IMAGE} AS go-builder ARG COMMIT_SHA="" ARG BUILD_BRANCH="" @@ -55,24 +62,24 @@ COPY go.* ./ COPY .bingo .bingo # Include vendored dependencies -COPY pkg/util/xorm/go.* pkg/util/xorm/ -COPY pkg/apiserver/go.* pkg/apiserver/ -COPY pkg/apimachinery/go.* pkg/apimachinery/ -COPY pkg/build/go.* pkg/build/ -COPY pkg/build/wire/go.* pkg/build/wire/ -COPY pkg/promlib/go.* pkg/promlib/ -COPY pkg/storage/unified/resource/go.* pkg/storage/unified/resource/ -COPY pkg/storage/unified/apistore/go.* pkg/storage/unified/apistore/ -COPY pkg/semconv/go.* pkg/semconv/ -COPY pkg/aggregator/go.* pkg/aggregator/ -COPY apps/playlist/go.* apps/playlist/ -COPY apps/investigation/go.* apps/investigation/ -COPY apps/advisor/go.* apps/advisor/ +COPY pkg/util/xorm pkg/util/xorm +COPY pkg/apiserver pkg/apiserver +COPY pkg/apimachinery pkg/apimachinery +COPY pkg/build pkg/build +COPY pkg/build/wire pkg/build/wire +COPY pkg/promlib pkg/promlib +COPY pkg/storage/unified/resource pkg/storage/unified/resource +COPY pkg/storage/unified/apistore pkg/storage/unified/apistore +COPY pkg/semconv pkg/semconv +COPY pkg/aggregator pkg/aggregator +COPY apps/playlist apps/playlist +COPY apps/investigations apps/investigations +COPY apps/advisor apps/advisor COPY apps apps COPY kindsv2 kindsv2 -COPY apps/alerting/notifications/go.* apps/alerting/notifications/ -COPY pkg/codegen/go.* pkg/codegen/ -COPY pkg/plugins/codegen/go.* pkg/plugins/codegen/ +COPY apps/alerting/notifications apps/alerting/notifications +COPY pkg/codegen pkg/codegen +COPY pkg/plugins/codegen pkg/plugins/codegen RUN go mod download RUN if [[ "$BINGO" = "true" ]]; then \ @@ -97,7 +104,8 @@ ENV BUILD_BRANCH=${BUILD_BRANCH} RUN make build-go GO_BUILD_TAGS=${GO_BUILD_TAGS} WIRE_TAGS=${WIRE_TAGS} -FROM ${BASE_IMAGE} as tgz-builder +# From-tarball build stage +FROM ${BASE_IMAGE} AS tgz-builder WORKDIR /tmp/grafana @@ -109,13 +117,14 @@ COPY ${GRAFANA_TGZ} /tmp/grafana.tar.gz RUN tar x -z -f /tmp/grafana.tar.gz --strip-components=1 # helpers for COPY --from -FROM ${GO_SRC} as go-src -FROM ${JS_SRC} as js-src +FROM ${GO_SRC} AS go-src +FROM ${JS_SRC} AS js-src # Final stage FROM ${BASE_IMAGE} LABEL maintainer="Grafana Labs " +LABEL org.opencontainers.image.source="https://github.com/grafana/grafana" ARG GF_UID="472" ARG GF_GID="0" @@ -145,19 +154,20 @@ RUN if grep -i -q alpine /etc/issue; then \ fi # glibc support for alpine x86_64 only +# docker run --rm --env STDOUT=1 sgerrand/glibc-builder 2.40 /usr/glibc-compat > glibc-bin-2.40.tar.gz +ARG GLIBC_VERSION=2.40 + RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \ - wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \ - wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \ - -O /tmp/glibc-2.35-r0.apk && \ - wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \ - -O /tmp/glibc-bin-2.35-r0.apk && \ - apk add --force-overwrite --no-cache /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \ - rm -f /lib64/ld-linux-x86-64.so.2 && \ - ln -s /usr/glibc-compat/lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 && \ - rm -f /tmp/glibc-2.35-r0.apk && \ - rm -f /tmp/glibc-bin-2.35-r0.apk && \ - rm -f /lib/ld-linux-x86-64.so.2 && \ - rm -f /etc/ld.so.cache; \ + wget -qO- "https://dl.grafana.com/glibc/glibc-bin-$GLIBC_VERSION.tar.gz" | tar zxf - -C / \ + usr/glibc-compat/lib/ld-linux-x86-64.so.2 \ + usr/glibc-compat/lib/libc.so.6 \ + usr/glibc-compat/lib/libdl.so.2 \ + usr/glibc-compat/lib/libm.so.6 \ + usr/glibc-compat/lib/libpthread.so.0 \ + usr/glibc-compat/lib/librt.so.1 \ + usr/glibc-compat/lib/libresolv.so.2 && \ + mkdir /lib64 && \ + ln -s /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64; \ fi COPY --from=go-src /tmp/grafana/conf ./conf diff --git a/MAINTAINERS.md b/MAINTAINERS.md index cab21a089cc..b1443b33722 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -8,4 +8,4 @@ - @davkal - Docs: - @chri2547 - - @brendamuir + - @JohnnyK-Grafana diff --git a/Makefile b/Makefile index 3df11c69545..699cfb0652e 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ WIRE_TAGS = "oss" include .bingo/Variables.mk GO = go -GO_VERSION = 1.23.5 +GO_VERSION = 1.23.7 GO_LINT_FILES ?= $(shell ./scripts/go-workspace/golangci-lint-includes.sh) GO_TEST_FILES ?= $(shell ./scripts/go-workspace/test-includes.sh) SH_FILES ?= $(shell find ./scripts -name *.sh) @@ -17,6 +17,7 @@ GO_RACE_FLAG := $(if $(GO_RACE),-race) GO_BUILD_FLAGS += $(if $(GO_BUILD_DEV),-dev) GO_BUILD_FLAGS += $(if $(GO_BUILD_TAGS),-build-tags=$(GO_BUILD_TAGS)) GO_BUILD_FLAGS += $(GO_RACE_FLAG) +GO_TEST_OUTPUT := $(shell [ -n "$(GO_TEST_OUTPUT)" ] && echo '-json | tee $(GO_TEST_OUTPUT) | tparse -all') GIT_BASE = remotes/origin/main # GNU xargs has flag -r, and BSD xargs (e.g. MacOS) has that behaviour by default @@ -130,14 +131,12 @@ else i18n-extract-enterprise: @echo "Extracting i18n strings for Enterprise" yarn run i18next --config public/locales/i18next-parser-enterprise.config.cjs - node ./public/locales/pseudo.mjs --mode enterprise endif .PHONY: i18n-extract i18n-extract: i18n-extract-enterprise @echo "Extracting i18n strings for OSS" yarn run i18next --config public/locales/i18next-parser.config.cjs - node ./public/locales/pseudo.mjs --mode oss ##@ Building .PHONY: gen-cue @@ -248,8 +247,7 @@ test-go: test-go-unit test-go-integration .PHONY: test-go-unit test-go-unit: ## Run unit tests for backend with flags. @echo "test backend unit tests" - printf '$(GO_TEST_FILES)' | xargs \ - $(GO) test $(GO_RACE_FLAG) -short -covermode=atomic -timeout=30m + $(GO) test $(GO_RACE_FLAG) -short -covermode=atomic -coverprofile=unit.cov -timeout=30m $(GO_TEST_FILES) $(GO_TEST_OUTPUT) .PHONY: test-go-unit-pretty test-go-unit-pretty: check-tparse @@ -262,7 +260,7 @@ test-go-unit-pretty: check-tparse .PHONY: test-go-integration test-go-integration: ## Run integration tests for backend with flags. @echo "test backend integration tests" - $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegration" -covermode=atomic -timeout=5m $(GO_INTEGRATION_TESTS) + $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegration" -covermode=atomic -coverprofile=integration.cov -timeout=5m $(GO_INTEGRATION_TESTS) $(GO_TEST_OUTPUT) .PHONY: test-go-integration-alertmanager test-go-integration-alertmanager: ## Run integration tests for the remote alertmanager (config taken from the mimir_backend block). @@ -271,6 +269,14 @@ test-go-integration-alertmanager: ## Run integration tests for the remote alertm AM_URL=http://localhost:8080 AM_TENANT_ID=test \ $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestIntegrationRemoteAlertmanager" -covermode=atomic -timeout=5m ./pkg/services/ngalert/... +.PHONY: test-go-integration-grafana-alertmanager +test-go-integration-grafana-alertmanager: ## Run integration tests for the grafana alertmanager + @echo "test grafana alertmanager integration tests" + @export GRAFANA_VERSION=11.5.0-81938; \ + $(GO) run tools/setup_grafana_alertmanager_integration_test_images.go; \ + $(GO) clean -testcache; \ + $(GO) test $(GO_RACE_FLAG) -count=1 -run "^TestAlertmanagerIntegration" -covermode=atomic -timeout=10m ./pkg/tests/alertmanager/... + .PHONY: test-go-integration-postgres test-go-integration-postgres: devenv-postgres ## Run integration tests for postgres backend with flags. @echo "test backend integration postgres tests" @@ -421,6 +427,7 @@ protobuf: ## Compile protobuf definitions buf generate pkg/plugins/backendplugin/secretsmanagerplugin --template pkg/plugins/backendplugin/secretsmanagerplugin/buf.gen.yaml buf generate pkg/storage/unified/resource --template pkg/storage/unified/resource/buf.gen.yaml buf generate pkg/services/authz/proto/v1 --template pkg/services/authz/proto/v1/buf.gen.yaml + buf generate pkg/services/ngalert/store/proto/v1 --template pkg/services/ngalert/store/proto/v1/buf.gen.yaml .PHONY: clean clean: ## Clean up intermediate build artifacts. diff --git a/README.md b/README.md index 7322e6a1c7d..033ebdc1ea6 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ If you're interested in contributing to the Grafana project: - If you have a specific question, check out our [discussion forums](https://community.grafana.com/). - For general discussions, join us on the [official Slack](https://slack.grafana.com) team. -This project is tested with [BrowserStack](https://www.browserstack.com/) +This project is tested with [BrowserStack](https://www.browserstack.com/). ## License diff --git a/apps/advisor/.gitignore b/apps/advisor/.gitignore new file mode 100644 index 00000000000..9e73bafbae8 --- /dev/null +++ b/apps/advisor/.gitignore @@ -0,0 +1 @@ +plugin/src \ No newline at end of file diff --git a/apps/advisor/Makefile b/apps/advisor/Makefile index 926f5a2840f..7a5f1c99365 100644 --- a/apps/advisor/Makefile +++ b/apps/advisor/Makefile @@ -1,8 +1,3 @@ .PHONY: generate generate: - @grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess - # HACK: Clean up generated CRD files. - # TODO: The SDK currently omits generating the manifest Go file with `--defencoding=none`, - # which we would normally use here to skip generating the CRD files. - # This needs to be addressed. - @rm -rf definitions + @grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none diff --git a/apps/advisor/go.mod b/apps/advisor/go.mod index 8fcc336a52b..917e2f985b4 100644 --- a/apps/advisor/go.mod +++ b/apps/advisor/go.mod @@ -1,10 +1,10 @@ module github.com/grafana/grafana/apps/advisor -go 1.23.4 +go 1.23.7 require ( - github.com/grafana/grafana-app-sdk v0.30.0 - k8s.io/apimachinery v0.32.0 + github.com/grafana/grafana-app-sdk v0.31.0 + k8s.io/apimachinery v0.32.1 k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f ) @@ -31,7 +31,7 @@ require ( github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect + github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect @@ -53,31 +53,31 @@ require ( github.com/spf13/pflag v1.0.5 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.36.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // indirect google.golang.org/grpc v1.69.4 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/protobuf v1.36.3 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.32.0 // indirect - k8s.io/apiextensions-apiserver v0.32.0 // indirect - k8s.io/client-go v0.32.0 // indirect + k8s.io/api v0.32.1 // indirect + k8s.io/apiextensions-apiserver v0.32.1 // indirect + k8s.io/client-go v0.32.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect diff --git a/apps/advisor/go.sum b/apps/advisor/go.sum index 858c73dd4b4..cdf6cf446ed 100644 --- a/apps/advisor/go.sum +++ b/apps/advisor/go.sum @@ -51,8 +51,10 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grafana/grafana-app-sdk v0.30.0 h1:Hqn2pETu2mQ4RpWkZYEQfu01P7xd1Z1Gj+HX/8aB0tw= github.com/grafana/grafana-app-sdk v0.30.0/go.mod h1:jhfqNIovb+Mes2vdMf9iMCWQkp1GTNtyNuExONtiNuk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4= github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= +github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -126,20 +128,27 @@ go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJyS go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -155,6 +164,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -162,17 +173,21 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -189,12 +204,15 @@ gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA= google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY= +google.golang.org/genproto/googleapis/api v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:Ic02D47M+zbarjYYUlK57y316f2MoN0gjAwI3f2S95o= google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.3/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -206,12 +224,16 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= +k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto= k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= diff --git a/apps/advisor/kinds/check.cue b/apps/advisor/kinds/check.cue index 4ab33fb05df..4aea38d6759 100644 --- a/apps/advisor/kinds/check.cue +++ b/apps/advisor/kinds/check.cue @@ -7,28 +7,45 @@ check: { versions: { "v0alpha1": { codegen: { - frontend: false + frontend: true backend: true } + validation: { + operations: [ + "CREATE", + "UPDATE", + ] + } schema: { - spec: { + #Data: { // Generic data input that a check can receive data?: [string]: string } - status: { - report: { + #ErrorLink: { + // URL to a page with more information about the error + url: string + // Human readable error message + message: string + } + #ReportFailure: { + // Severity of the failure + severity: "high" | "low" + // Step ID that the failure is associated with + stepID: string + // Human readable identifier of the item that failed + item: string + // Links to actions that can be taken to resolve the failure + links: [...#ErrorLink] + } + #Report: { // Number of elements analyzed count: int - // List of errors - errors: [...{ - // Severity of the error - severity: "high" | "low" - // Human readable reason for the error - reason: string - // Action to take to resolve the error - action: string - }] - } + // List of failures + failures: [...#ReportFailure] + } + spec: #Data + status: { + report: #Report } } } diff --git a/apps/advisor/kinds/checktype.cue b/apps/advisor/kinds/checktype.cue new file mode 100644 index 00000000000..e2d653e629e --- /dev/null +++ b/apps/advisor/kinds/checktype.cue @@ -0,0 +1,27 @@ +package advisor + +checktype: { + kind: "CheckType" + pluralName: "CheckTypes" + current: "v0alpha1" + versions: { + "v0alpha1": { + codegen: { + frontend: true + backend: true + } + schema: { + #Step: { + title: string + description: string + stepID: string + resolution: string + } + spec: { + name: string + steps: [...#Step] + } + } + } + } +} diff --git a/apps/advisor/kinds/manifest.cue b/apps/advisor/kinds/manifest.cue index 6f96066967d..75a0eee05ef 100644 --- a/apps/advisor/kinds/manifest.cue +++ b/apps/advisor/kinds/manifest.cue @@ -5,5 +5,6 @@ manifest: { groupOverride: "advisor.grafana.app" kinds: [ check, + checktype, ] } diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go index 057ed6c4b7e..c9acc5ce31c 100644 --- a/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/check_status_gen.go @@ -2,6 +2,36 @@ package v0alpha1 +// +k8s:openapi-gen=true +type CheckErrorLink struct { + // URL to a page with more information about the error + Url string `json:"url"` + // Human readable error message + Message string `json:"message"` +} + +// NewCheckErrorLink creates a new CheckErrorLink object. +func NewCheckErrorLink() *CheckErrorLink { + return &CheckErrorLink{} +} + +// +k8s:openapi-gen=true +type CheckReportFailure struct { + // Severity of the failure + Severity CheckReportFailureSeverity `json:"severity"` + // Step ID that the failure is associated with + StepID string `json:"stepID"` + // Human readable identifier of the item that failed + Item string `json:"item"` + // Links to actions that can be taken to resolve the failure + Links []CheckErrorLink `json:"links"` +} + +// NewCheckReportFailure creates a new CheckReportFailure object. +func NewCheckReportFailure() *CheckReportFailure { + return &CheckReportFailure{} +} + // +k8s:openapi-gen=true type CheckstatusOperatorState struct { // lastEvaluation is the ResourceVersion last evaluated @@ -37,6 +67,14 @@ func NewCheckStatus() *CheckStatus { } } +// +k8s:openapi-gen=true +type CheckReportFailureSeverity string + +const ( + CheckReportFailureSeverityHigh CheckReportFailureSeverity = "high" + CheckReportFailureSeverityLow CheckReportFailureSeverity = "low" +) + // +k8s:openapi-gen=true type CheckStatusOperatorStateState string @@ -46,35 +84,12 @@ const ( CheckStatusOperatorStateStateFailed CheckStatusOperatorStateState = "failed" ) -// +k8s:openapi-gen=true -type CheckStatusSeverity string - -const ( - CheckStatusSeverityHigh CheckStatusSeverity = "high" - CheckStatusSeverityLow CheckStatusSeverity = "low" -) - -// +k8s:openapi-gen=true -type CheckV0alpha1StatusReportErrors struct { - // Severity of the error - Severity CheckStatusSeverity `json:"severity"` - // Human readable reason for the error - Reason string `json:"reason"` - // Action to take to resolve the error - Action string `json:"action"` -} - -// NewCheckV0alpha1StatusReportErrors creates a new CheckV0alpha1StatusReportErrors object. -func NewCheckV0alpha1StatusReportErrors() *CheckV0alpha1StatusReportErrors { - return &CheckV0alpha1StatusReportErrors{} -} - // +k8s:openapi-gen=true type CheckV0alpha1StatusReport struct { // Number of elements analyzed Count int64 `json:"count"` - // List of errors - Errors []CheckV0alpha1StatusReportErrors `json:"errors"` + // List of failures + Failures []CheckReportFailure `json:"failures"` } // NewCheckV0alpha1StatusReport creates a new CheckV0alpha1StatusReport object. diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_codec_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_codec_gen.go new file mode 100644 index 00000000000..9881ce9d96f --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// CheckTypeJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type CheckTypeJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*CheckTypeJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*CheckTypeJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &CheckTypeJSONCodec{} diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_metadata_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_metadata_gen.go new file mode 100644 index 00000000000..9998cffb37d --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type CheckTypeMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewCheckTypeMetadata creates a new CheckTypeMetadata object. +func NewCheckTypeMetadata() *CheckTypeMetadata { + return &CheckTypeMetadata{} +} diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_object_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_object_gen.go new file mode 100644 index 00000000000..80bd02b1cc8 --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_object_gen.go @@ -0,0 +1,266 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "fmt" + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "time" +) + +// +k8s:openapi-gen=true +type CheckType struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + Spec CheckTypeSpec `json:"spec" yaml:"spec"` + CheckTypeStatus CheckTypeStatus `json:"status" yaml:"status"` +} + +func (o *CheckType) GetSpec() any { + return o.Spec +} + +func (o *CheckType) SetSpec(spec any) error { + cast, ok := spec.(CheckTypeSpec) + if !ok { + return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) + } + o.Spec = cast + return nil +} + +func (o *CheckType) GetSubresources() map[string]any { + return map[string]any{ + "status": o.CheckTypeStatus, + } +} + +func (o *CheckType) GetSubresource(name string) (any, bool) { + switch name { + case "status": + return o.CheckTypeStatus, true + default: + return nil, false + } +} + +func (o *CheckType) SetSubresource(name string, value any) error { + switch name { + case "status": + cast, ok := value.(CheckTypeStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type CheckTypeStatus", value) + } + o.CheckTypeStatus = cast + return nil + default: + return fmt.Errorf("subresource '%s' does not exist", name) + } +} + +func (o *CheckType) GetStaticMetadata() resource.StaticMetadata { + gvk := o.GroupVersionKind() + return resource.StaticMetadata{ + Name: o.ObjectMeta.Name, + Namespace: o.ObjectMeta.Namespace, + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func (o *CheckType) SetStaticMetadata(metadata resource.StaticMetadata) { + o.Name = metadata.Name + o.Namespace = metadata.Namespace + o.SetGroupVersionKind(schema.GroupVersionKind{ + Group: metadata.Group, + Version: metadata.Version, + Kind: metadata.Kind, + }) +} + +func (o *CheckType) GetCommonMetadata() resource.CommonMetadata { + dt := o.DeletionTimestamp + var deletionTimestamp *time.Time + if dt != nil { + deletionTimestamp = &dt.Time + } + // Legacy ExtraFields support + extraFields := make(map[string]any) + if o.Annotations != nil { + extraFields["annotations"] = o.Annotations + } + if o.ManagedFields != nil { + extraFields["managedFields"] = o.ManagedFields + } + if o.OwnerReferences != nil { + extraFields["ownerReferences"] = o.OwnerReferences + } + return resource.CommonMetadata{ + UID: string(o.UID), + ResourceVersion: o.ResourceVersion, + Generation: o.Generation, + Labels: o.Labels, + CreationTimestamp: o.CreationTimestamp.Time, + DeletionTimestamp: deletionTimestamp, + Finalizers: o.Finalizers, + UpdateTimestamp: o.GetUpdateTimestamp(), + CreatedBy: o.GetCreatedBy(), + UpdatedBy: o.GetUpdatedBy(), + ExtraFields: extraFields, + } +} + +func (o *CheckType) SetCommonMetadata(metadata resource.CommonMetadata) { + o.UID = types.UID(metadata.UID) + o.ResourceVersion = metadata.ResourceVersion + o.Generation = metadata.Generation + o.Labels = metadata.Labels + o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) + if metadata.DeletionTimestamp != nil { + dt := metav1.NewTime(*metadata.DeletionTimestamp) + o.DeletionTimestamp = &dt + } else { + o.DeletionTimestamp = nil + } + o.Finalizers = metadata.Finalizers + if o.Annotations == nil { + o.Annotations = make(map[string]string) + } + if !metadata.UpdateTimestamp.IsZero() { + o.SetUpdateTimestamp(metadata.UpdateTimestamp) + } + if metadata.CreatedBy != "" { + o.SetCreatedBy(metadata.CreatedBy) + } + if metadata.UpdatedBy != "" { + o.SetUpdatedBy(metadata.UpdatedBy) + } + // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields + if metadata.ExtraFields != nil { + if annotations, ok := metadata.ExtraFields["annotations"]; ok { + if cast, ok := annotations.(map[string]string); ok { + o.Annotations = cast + } + } + if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { + if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { + o.ManagedFields = cast + } + } + if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { + if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { + o.OwnerReferences = cast + } + } + } +} + +func (o *CheckType) GetCreatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/createdBy"] +} + +func (o *CheckType) SetCreatedBy(createdBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy +} + +func (o *CheckType) GetUpdateTimestamp() time.Time { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) + return parsed +} + +func (o *CheckType) SetUpdateTimestamp(updateTimestamp time.Time) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) +} + +func (o *CheckType) GetUpdatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/updatedBy"] +} + +func (o *CheckType) SetUpdatedBy(updatedBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy +} + +func (o *CheckType) Copy() resource.Object { + return resource.CopyObject(o) +} + +func (o *CheckType) DeepCopyObject() runtime.Object { + return o.Copy() +} + +// Interface compliance compile-time check +var _ resource.Object = &CheckType{} + +// +k8s:openapi-gen=true +type CheckTypeList struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []CheckType `json:"items" yaml:"items"` +} + +func (o *CheckTypeList) DeepCopyObject() runtime.Object { + return o.Copy() +} + +func (o *CheckTypeList) Copy() resource.ListObject { + cpy := &CheckTypeList{ + TypeMeta: o.TypeMeta, + Items: make([]CheckType, len(o.Items)), + } + o.ListMeta.DeepCopyInto(&cpy.ListMeta) + for i := 0; i < len(o.Items); i++ { + if item, ok := o.Items[i].Copy().(*CheckType); ok { + cpy.Items[i] = *item + } + } + return cpy +} + +func (o *CheckTypeList) GetItems() []resource.Object { + items := make([]resource.Object, len(o.Items)) + for i := 0; i < len(o.Items); i++ { + items[i] = &o.Items[i] + } + return items +} + +func (o *CheckTypeList) SetItems(items []resource.Object) { + o.Items = make([]CheckType, len(items)) + for i := 0; i < len(items); i++ { + o.Items[i] = *items[i].(*CheckType) + } +} + +// Interface compliance compile-time check +var _ resource.ListObject = &CheckTypeList{} diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_schema_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_schema_gen.go new file mode 100644 index 00000000000..15b4a6fbb11 --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaCheckType = resource.NewSimpleSchema("advisor.grafana.app", "v0alpha1", &CheckType{}, &CheckTypeList{}, resource.WithKind("CheckType"), + resource.WithPlural("checktypes"), resource.WithScope(resource.NamespacedScope)) + kindCheckType = resource.Kind{ + Schema: schemaCheckType, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &CheckTypeJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func CheckTypeKind() resource.Kind { + return kindCheckType +} + +// Schema returns a resource.SimpleSchema representation of CheckType +func CheckTypeSchema() *resource.SimpleSchema { + return schemaCheckType +} + +// Interface compliance checks +var _ resource.Schema = kindCheckType diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go new file mode 100644 index 00000000000..528643b69dd --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_spec_gen.go @@ -0,0 +1,27 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type CheckTypeStep struct { + Title string `json:"title"` + Description string `json:"description"` + StepID string `json:"stepID"` + Resolution string `json:"resolution"` +} + +// NewCheckTypeStep creates a new CheckTypeStep object. +func NewCheckTypeStep() *CheckTypeStep { + return &CheckTypeStep{} +} + +// +k8s:openapi-gen=true +type CheckTypeSpec struct { + Name string `json:"name"` + Steps []CheckTypeStep `json:"steps"` +} + +// NewCheckTypeSpec creates a new CheckTypeSpec object. +func NewCheckTypeSpec() *CheckTypeSpec { + return &CheckTypeSpec{} +} diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_status_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_status_gen.go new file mode 100644 index 00000000000..87db65316d0 --- /dev/null +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/checktype_status_gen.go @@ -0,0 +1,44 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type CheckTypestatusOperatorState struct { + // lastEvaluation is the ResourceVersion last evaluated + LastEvaluation string `json:"lastEvaluation"` + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + State CheckTypeStatusOperatorStateState `json:"state"` + // descriptiveState is an optional more descriptive state field which has no requirements on format + DescriptiveState *string `json:"descriptiveState,omitempty"` + // details contains any extra information that is operator-specific + Details map[string]interface{} `json:"details,omitempty"` +} + +// NewCheckTypestatusOperatorState creates a new CheckTypestatusOperatorState object. +func NewCheckTypestatusOperatorState() *CheckTypestatusOperatorState { + return &CheckTypestatusOperatorState{} +} + +// +k8s:openapi-gen=true +type CheckTypeStatus struct { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + OperatorStates map[string]CheckTypestatusOperatorState `json:"operatorStates,omitempty"` + // additionalFields is reserved for future use + AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` +} + +// NewCheckTypeStatus creates a new CheckTypeStatus object. +func NewCheckTypeStatus() *CheckTypeStatus { + return &CheckTypeStatus{} +} + +// +k8s:openapi-gen=true +type CheckTypeStatusOperatorStateState string + +const ( + CheckTypeStatusOperatorStateStateSuccess CheckTypeStatusOperatorStateState = "success" + CheckTypeStatusOperatorStateStateInProgress CheckTypeStatusOperatorStateState = "in_progress" + CheckTypeStatusOperatorStateStateFailed CheckTypeStatusOperatorStateState = "failed" +) diff --git a/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go b/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go index a78d033bb26..79d78cd2766 100644 --- a/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go +++ b/apps/advisor/pkg/apis/advisor/v0alpha1/zz_openapi_gen.go @@ -12,13 +12,20 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check": schema_pkg_apis_advisor_v0alpha1_Check(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus": schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReportErrors(ref), - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.Check": schema_pkg_apis_advisor_v0alpha1_Check(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink": schema_pkg_apis_advisor_v0alpha1_CheckErrorLink(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckList": schema_pkg_apis_advisor_v0alpha1_CheckList(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure": schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckSpec": schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckStatus": schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType": schema_pkg_apis_advisor_v0alpha1_CheckType(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeList": schema_pkg_apis_advisor_v0alpha1_CheckTypeList(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec": schema_pkg_apis_advisor_v0alpha1_CheckTypeSpec(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus": schema_pkg_apis_advisor_v0alpha1_CheckTypeStatus(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep": schema_pkg_apis_advisor_v0alpha1_CheckTypeStep(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckTypestatusOperatorState(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReport": schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref), + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckstatusOperatorState": schema_pkg_apis_advisor_v0alpha1_CheckstatusOperatorState(ref), } } @@ -69,6 +76,35 @@ func schema_pkg_apis_advisor_v0alpha1_Check(ref common.ReferenceCallback) common } } +func schema_pkg_apis_advisor_v0alpha1_CheckErrorLink(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "url": { + SchemaProps: spec.SchemaProps{ + Description: "URL to a page with more information about the error", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "message": { + SchemaProps: spec.SchemaProps{ + Description: "Human readable error message", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"url", "message"}, + }, + }, + } +} + func schema_pkg_apis_advisor_v0alpha1_CheckList(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -117,6 +153,59 @@ func schema_pkg_apis_advisor_v0alpha1_CheckList(ref common.ReferenceCallback) co } } +func schema_pkg_apis_advisor_v0alpha1_CheckReportFailure(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "severity": { + SchemaProps: spec.SchemaProps{ + Description: "Severity of the failure", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "stepID": { + SchemaProps: spec.SchemaProps{ + Description: "Step ID that the failure is associated with", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "item": { + SchemaProps: spec.SchemaProps{ + Description: "Human readable identifier of the item that failed", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "links": { + SchemaProps: spec.SchemaProps{ + Description: "Links to actions that can be taken to resolve the failure", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink"), + }, + }, + }, + }, + }, + }, + Required: []string{"severity", "stepID", "item", "links"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckErrorLink"}, + } +} + func schema_pkg_apis_advisor_v0alpha1_CheckSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -196,6 +285,272 @@ func schema_pkg_apis_advisor_v0alpha1_CheckStatus(ref common.ReferenceCallback) } } +func schema_pkg_apis_advisor_v0alpha1_CheckType(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus"), + }, + }, + }, + Required: []string{"metadata", "spec", "status"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeSpec", "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_advisor_v0alpha1_CheckTypeList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckType", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_advisor_v0alpha1_CheckTypeSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "steps": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep"), + }, + }, + }, + }, + }, + }, + Required: []string{"name", "steps"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypeStep"}, + } +} + +func schema_pkg_apis_advisor_v0alpha1_CheckTypeStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "operatorStates": { + SchemaProps: spec.SchemaProps{ + Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState"), + }, + }, + }, + }, + }, + "additionalFields": { + SchemaProps: spec.SchemaProps{ + Description: "additionalFields is reserved for future use", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckTypestatusOperatorState"}, + } +} + +func schema_pkg_apis_advisor_v0alpha1_CheckTypeStep(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "description": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "stepID": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "resolution": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"title", "description", "stepID", "resolution"}, + }, + }, + } +} + +func schema_pkg_apis_advisor_v0alpha1_CheckTypestatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "lastEvaluation": { + SchemaProps: spec.SchemaProps{ + Description: "lastEvaluation is the ResourceVersion last evaluated", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "state": { + SchemaProps: spec.SchemaProps{ + Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "descriptiveState": { + SchemaProps: spec.SchemaProps{ + Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", + Type: []string{"string"}, + Format: "", + }, + }, + "details": { + SchemaProps: spec.SchemaProps{ + Description: "details contains any extra information that is operator-specific", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"lastEvaluation", "state"}, + }, + }, + } +} + func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -210,63 +565,26 @@ func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReport(ref common.Refer Format: "int64", }, }, - "errors": { + "failures": { SchemaProps: spec.SchemaProps{ - Description: "List of errors", + Description: "List of failures", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors"), + Ref: ref("github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure"), }, }, }, }, }, }, - Required: []string{"count", "errors"}, + Required: []string{"count", "failures"}, }, }, Dependencies: []string{ - "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckV0alpha1StatusReportErrors"}, - } -} - -func schema_pkg_apis_advisor_v0alpha1_CheckV0alpha1StatusReportErrors(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "severity": { - SchemaProps: spec.SchemaProps{ - Description: "Severity of the error", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "reason": { - SchemaProps: spec.SchemaProps{ - Description: "Human readable reason for the error", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "action": { - SchemaProps: spec.SchemaProps{ - Description: "Action to take to resolve the error", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"severity", "reason", "action"}, - }, - }, + "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1.CheckReportFailure"}, } } diff --git a/apps/advisor/pkg/apis/advisor_manifest.go b/apps/advisor/pkg/apis/advisor_manifest.go index 2e8bb06fb65..e333774303f 100644 --- a/apps/advisor/pkg/apis/advisor_manifest.go +++ b/apps/advisor/pkg/apis/advisor_manifest.go @@ -12,9 +12,12 @@ import ( ) var ( - rawSchemaCheckv0alpha1 = []byte(`{"spec":{"properties":{"data":{"additionalProperties":{"type":"string"},"description":"Generic data input that a check can receive","type":"object"}},"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"},"report":{"properties":{"count":{"description":"Number of elements analyzed","type":"integer"},"errors":{"description":"List of errors","items":{"properties":{"action":{"description":"Action to take to resolve the error","type":"string"},"reason":{"description":"Human readable reason for the error","type":"string"},"severity":{"description":"Severity of the error","enum":["high","low"],"type":"string"}},"required":["severity","reason","action"],"type":"object"},"type":"array"}},"required":["count","errors"],"type":"object"}},"required":["report"],"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) - versionSchemaCheckv0alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaCheckv0alpha1, &versionSchemaCheckv0alpha1) + rawSchemaCheckv0alpha1 = []byte(`{"spec":{"properties":{"data":{"additionalProperties":{"type":"string"},"description":"Generic data input that a check can receive","type":"object"}},"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"},"report":{"properties":{"count":{"description":"Number of elements analyzed","type":"integer"},"failures":{"description":"List of failures","items":{"properties":{"item":{"description":"Human readable identifier of the item that failed","type":"string"},"links":{"description":"Links to actions that can be taken to resolve the failure","items":{"properties":{"message":{"description":"Human readable error message","type":"string"},"url":{"description":"URL to a page with more information about the error","type":"string"}},"required":["url","message"],"type":"object"},"type":"array"},"severity":{"description":"Severity of the failure","enum":["high","low"],"type":"string"},"stepID":{"description":"Step ID that the failure is associated with","type":"string"}},"required":["severity","stepID","item","links"],"type":"object"},"type":"array"}},"required":["count","failures"],"type":"object"}},"required":["report"],"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) + versionSchemaCheckv0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaCheckv0alpha1, &versionSchemaCheckv0alpha1) + rawSchemaCheckTypev0alpha1 = []byte(`{"spec":{"properties":{"name":{"type":"string"},"steps":{"items":{"properties":{"description":{"type":"string"},"resolution":{"type":"string"},"stepID":{"type":"string"},"title":{"type":"string"}},"required":["title","description","stepID","resolution"],"type":"object"},"type":"array"}},"required":["name","steps"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) + versionSchemaCheckTypev0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaCheckTypev0alpha1, &versionSchemaCheckTypev0alpha1) ) var appManifestData = app.ManifestData{ @@ -27,11 +30,31 @@ var appManifestData = app.ManifestData{ Conversion: false, Versions: []app.ManifestKindVersion{ { - Name: "v0alpha1", + Name: "v0alpha1", + Admission: &app.AdmissionCapabilities{ + Validation: &app.ValidationCapability{ + Operations: []app.AdmissionOperation{ + app.AdmissionOperationCreate, + app.AdmissionOperationUpdate, + }, + }, + }, Schema: &versionSchemaCheckv0alpha1, }, }, }, + + { + Kind: "CheckType", + Scope: "Namespaced", + Conversion: false, + Versions: []app.ManifestKindVersion{ + { + Name: "v0alpha1", + Schema: &versionSchemaCheckTypev0alpha1, + }, + }, + }, }, } diff --git a/apps/advisor/pkg/app/app.go b/apps/advisor/pkg/app/app.go index e4ccafbcaaf..efa9188f8e5 100644 --- a/apps/advisor/pkg/app/app.go +++ b/apps/advisor/pkg/app/app.go @@ -2,16 +2,49 @@ package app import ( "context" + "fmt" "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/k8s" "github.com/grafana/grafana-app-sdk/resource" "github.com/grafana/grafana-app-sdk/simple" advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/apps/advisor/pkg/app/checkscheduler" + "github.com/grafana/grafana/apps/advisor/pkg/app/checktyperegisterer" + "github.com/grafana/grafana/pkg/infra/log" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/klog/v2" ) func New(cfg app.Config) (app.App, error) { + // Read config + specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig) + if !ok { + return nil, fmt.Errorf("invalid config type") + } + checkRegistry := specificConfig.CheckRegistry + stackID := specificConfig.StackID + namespace, err := checks.GetNamespace(stackID) + if err != nil { + return nil, err + } + log := log.New("advisor.app") + + // Prepare storage client + clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{}) + client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckKind()) + if err != nil { + return nil, err + } + + // Initialize checks + checkMap := map[string]checks.Check{} + for _, c := range checkRegistry.Checks() { + checkMap[c.ID()] = c + } + simpleConfig := simple.AppConfig{ Name: "advisor", KubeConfig: cfg.KubeConfig, @@ -23,6 +56,34 @@ func New(cfg app.Config) (app.App, error) { ManagedKinds: []simple.AppManagedKind{ { Kind: advisorv0alpha1.CheckKind(), + Validator: &simple.Validator{ + ValidateFunc: func(ctx context.Context, req *app.AdmissionRequest) error { + if req.Object != nil { + _, err := getCheck(req.Object, checkMap) + return err + } + return nil + }, + }, + Watcher: &simple.Watcher{ + AddFunc: func(ctx context.Context, obj resource.Object) error { + log.Debug("Adding check", "namespace", obj.GetNamespace()) + if obj.GetNamespace() != namespace { + log.Debug("Skipping check in namespace", "namespace", obj.GetNamespace()) + return nil + } else { + log.Debug("Processing check in namespace", "namespace", obj.GetNamespace()) + } + check, err := getCheck(obj, checkMap) + if err != nil { + return err + } + return processCheck(ctx, client, obj, check) + }, + }, + }, + { + Kind: advisorv0alpha1.CheckTypeKind(), }, }, } @@ -37,6 +98,20 @@ func New(cfg app.Config) (app.App, error) { return nil, err } + // Save check types as resources + ctr, err := checktyperegisterer.New(cfg) + if err != nil { + return nil, err + } + a.AddRunnable(ctr) + + // Start scheduler + csch, err := checkscheduler.New(cfg) + if err != nil { + return nil, err + } + a.AddRunnable(csch) + return a, nil } @@ -49,6 +124,7 @@ func GetKinds() map[schema.GroupVersion][]resource.Kind { return map[schema.GroupVersion][]resource.Kind{ gv: { advisorv0alpha1.CheckKind(), + advisorv0alpha1.CheckTypeKind(), }, } } diff --git a/apps/advisor/pkg/app/authorizer.go b/apps/advisor/pkg/app/authorizer.go new file mode 100644 index 00000000000..4d216ee9edd --- /dev/null +++ b/apps/advisor/pkg/app/authorizer.go @@ -0,0 +1,31 @@ +package app + +import ( + "context" + + "github.com/grafana/grafana/pkg/apimachinery/identity" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +func GetAuthorizer() authorizer.Authorizer { + return authorizer.AuthorizerFunc(func( + ctx context.Context, attr authorizer.Attributes, + ) (authorized authorizer.Decision, reason string, err error) { + if !attr.IsResourceRequest() { + return authorizer.DecisionNoOpinion, "", nil + } + + // require a user + u, err := identity.GetRequester(ctx) + if err != nil { + return authorizer.DecisionDeny, "valid user is required", err + } + + // check if is admin + if u.HasRole(identity.RoleAdmin) { + return authorizer.DecisionAllow, "", nil + } + + return authorizer.DecisionDeny, "forbidden", nil + }) +} diff --git a/apps/advisor/pkg/app/authorizer_test.go b/apps/advisor/pkg/app/authorizer_test.go new file mode 100644 index 00000000000..1384176969e --- /dev/null +++ b/apps/advisor/pkg/app/authorizer_test.go @@ -0,0 +1,82 @@ +package app + +import ( + "context" + "testing" + + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/stretchr/testify/assert" + "k8s.io/apiserver/pkg/authorization/authorizer" +) + +func TestGetAuthorizer(t *testing.T) { + tests := []struct { + name string + ctx context.Context + attr authorizer.Attributes + expectedDecision authorizer.Decision + expectedReason string + expectedErr error + }{ + { + name: "non-resource request", + ctx: context.TODO(), + attr: &mockAttributes{resourceRequest: false}, + expectedDecision: authorizer.DecisionNoOpinion, + expectedReason: "", + expectedErr: nil, + }, + { + name: "user is admin", + ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: true}), + attr: &mockAttributes{resourceRequest: true}, + expectedDecision: authorizer.DecisionAllow, + expectedReason: "", + expectedErr: nil, + }, + { + name: "user is not admin", + ctx: identity.WithRequester(context.TODO(), &mockUser{isGrafanaAdmin: false}), + attr: &mockAttributes{resourceRequest: true}, + expectedDecision: authorizer.DecisionDeny, + expectedReason: "forbidden", + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + auth := GetAuthorizer() + decision, reason, err := auth.Authorize(tt.ctx, tt.attr) + assert.Equal(t, tt.expectedDecision, decision) + assert.Equal(t, tt.expectedReason, reason) + assert.Equal(t, tt.expectedErr, err) + }) + } +} + +type mockAttributes struct { + authorizer.Attributes + resourceRequest bool +} + +func (m *mockAttributes) IsResourceRequest() bool { + return m.resourceRequest +} + +// Implement other methods of authorizer.Attributes as needed + +type mockUser struct { + identity.Requester + isGrafanaAdmin bool +} + +func (m *mockUser) GetIsGrafanaAdmin() bool { + return m.isGrafanaAdmin +} + +func (m *mockUser) HasRole(role identity.RoleType) bool { + return role == identity.RoleAdmin && m.isGrafanaAdmin +} + +// Implement other methods of identity.Requester as needed diff --git a/apps/advisor/pkg/app/checkregistry/checkregistry.go b/apps/advisor/pkg/app/checkregistry/checkregistry.go new file mode 100644 index 00000000000..335b9cc7567 --- /dev/null +++ b/apps/advisor/pkg/app/checkregistry/checkregistry.go @@ -0,0 +1,66 @@ +package checkregistry + +import ( + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks/datasourcecheck" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks/plugincheck" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/repo" + "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" + "github.com/grafana/grafana/pkg/services/pluginsintegration/plugincontext" + "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" +) + +type CheckService interface { + Checks() []checks.Check +} + +type Service struct { + datasourceSvc datasources.DataSourceService + pluginStore pluginstore.Store + pluginContextProvider *plugincontext.Provider + pluginClient plugins.Client + pluginRepo repo.Service + pluginPreinstall plugininstaller.Preinstall + managedPlugins managedplugins.Manager +} + +func ProvideService(datasourceSvc datasources.DataSourceService, pluginStore pluginstore.Store, + pluginContextProvider *plugincontext.Provider, pluginClient plugins.Client, + pluginRepo repo.Service, pluginPreinstall plugininstaller.Preinstall, managedPlugins managedplugins.Manager) *Service { + return &Service{ + datasourceSvc: datasourceSvc, + pluginStore: pluginStore, + pluginContextProvider: pluginContextProvider, + pluginClient: pluginClient, + pluginRepo: pluginRepo, + pluginPreinstall: pluginPreinstall, + managedPlugins: managedPlugins, + } +} + +func (s *Service) Checks() []checks.Check { + return []checks.Check{ + datasourcecheck.New( + s.datasourceSvc, + s.pluginStore, + s.pluginContextProvider, + s.pluginClient, + ), + plugincheck.New( + s.pluginStore, + s.pluginRepo, + s.pluginPreinstall, + s.managedPlugins, + ), + } +} + +// AdvisorAppConfig is the configuration received from Grafana to run the app +type AdvisorAppConfig struct { + CheckRegistry CheckService + PluginConfig map[string]string + StackID string +} diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check.go b/apps/advisor/pkg/app/checks/datasourcecheck/check.go new file mode 100644 index 00000000000..0cdac81e4b8 --- /dev/null +++ b/apps/advisor/pkg/app/checks/datasourcecheck/check.go @@ -0,0 +1,177 @@ +package datasourcecheck + +import ( + "context" + "errors" + "fmt" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" + "github.com/grafana/grafana/pkg/util" +) + +type check struct { + DatasourceSvc datasources.DataSourceService + PluginStore pluginstore.Store + PluginContextProvider pluginContextProvider + PluginClient plugins.Client + log log.Logger +} + +func New( + datasourceSvc datasources.DataSourceService, + pluginStore pluginstore.Store, + pluginContextProvider pluginContextProvider, + pluginClient plugins.Client, +) checks.Check { + return &check{ + DatasourceSvc: datasourceSvc, + PluginStore: pluginStore, + PluginContextProvider: pluginContextProvider, + PluginClient: pluginClient, + log: log.New("advisor.datasourcecheck"), + } +} + +func (c *check) Items(ctx context.Context) ([]any, error) { + dss, err := c.DatasourceSvc.GetAllDataSources(ctx, &datasources.GetAllDataSourcesQuery{}) + if err != nil { + return nil, err + } + res := make([]any, len(dss)) + for i, ds := range dss { + res[i] = ds + } + return res, nil +} + +func (c *check) ID() string { + return "datasource" +} + +func (c *check) Steps() []checks.Step { + return []checks.Step{ + &uidValidationStep{}, + &healthCheckStep{ + PluginContextProvider: c.PluginContextProvider, + PluginClient: c.PluginClient, + log: c.log, + }, + } +} + +type uidValidationStep struct{} + +func (s *uidValidationStep) ID() string { + return "uid-validation" +} + +func (s *uidValidationStep) Title() string { + return "UID validation" +} + +func (s *uidValidationStep) Description() string { + return "Checks if the UID of a data source is valid." +} + +func (s *uidValidationStep) Resolution() string { + return "Check the documentation for more information or delete the data source and create a new one." +} + +func (s *uidValidationStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) { + ds, ok := i.(*datasources.DataSource) + if !ok { + return nil, fmt.Errorf("invalid item type %T", i) + } + // Data source UID validation + err := util.ValidateUID(ds.UID) + if err != nil { + return checks.NewCheckReportFailure( + advisor.CheckReportFailureSeverityLow, + s.ID(), + fmt.Sprintf("%s (%s)", ds.Name, ds.UID), + []advisor.CheckErrorLink{}, + ), nil + } + return nil, nil +} + +type healthCheckStep struct { + PluginContextProvider pluginContextProvider + PluginClient plugins.Client + log log.Logger +} + +func (s *healthCheckStep) Title() string { + return "Health check" +} + +func (s *healthCheckStep) Description() string { + return "Checks if a data sources is healthy." +} + +func (s *healthCheckStep) Resolution() string { + return "Go to the data source configuration page and address the issues reported." +} + +func (s *healthCheckStep) ID() string { + return "health-check" +} + +func (s *healthCheckStep) Run(ctx context.Context, obj *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) { + ds, ok := i.(*datasources.DataSource) + if !ok { + return nil, fmt.Errorf("invalid item type %T", i) + } + + // Health check execution + requester, err := identity.GetRequester(ctx) + if err != nil { + return nil, err + } + pCtx, err := s.PluginContextProvider.GetWithDataSource(ctx, ds.Type, requester, ds) + if err != nil { + // Unable to check health check + s.log.Error("Failed to get plugin context", "datasource_uid", ds.UID, "error", err) + return nil, nil + } + req := &backend.CheckHealthRequest{ + PluginContext: pCtx, + Headers: map[string]string{}, + } + resp, err := s.PluginClient.CheckHealth(ctx, req) + if err != nil || resp.Status != backend.HealthStatusOk { + if err != nil { + s.log.Debug("Failed to check health", "datasource_uid", ds.UID, "error", err) + if errors.Is(err, plugins.ErrMethodNotImplemented) || errors.Is(err, plugins.ErrPluginUnavailable) { + // The plugin does not support backend health checks + return nil, nil + } + } else { + s.log.Debug("Failed to check health", "datasource_uid", ds.UID, "status", resp.Status, "message", resp.Message) + } + return checks.NewCheckReportFailure( + advisor.CheckReportFailureSeverityHigh, + s.ID(), + ds.Name, + []advisor.CheckErrorLink{ + { + Message: "Fix me", + Url: fmt.Sprintf("/connections/datasources/edit/%s", ds.UID), + }, + }, + ), nil + } + return nil, nil +} + +type pluginContextProvider interface { + GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) +} diff --git a/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go new file mode 100644 index 00000000000..ee8a991555d --- /dev/null +++ b/apps/advisor/pkg/app/checks/datasourcecheck/check_test.go @@ -0,0 +1,188 @@ +package datasourcecheck + +import ( + "context" + "testing" + + "github.com/grafana/grafana-plugin-sdk-go/backend" + advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/infra/log" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/services/datasources" + "github.com/grafana/grafana/pkg/services/user" + "github.com/stretchr/testify/assert" +) + +func TestCheck_Run(t *testing.T) { + t.Run("should return no failures when all datasources are healthy", func(t *testing.T) { + datasources := []*datasources.DataSource{ + {UID: "valid-uid-1", Type: "prometheus", Name: "Prometheus"}, + {UID: "valid-uid-2", Type: "mysql", Name: "MySQL"}, + } + + mockDatasourceSvc := &MockDatasourceSvc{dss: datasources} + mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}} + mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusOk}} + + check := &check{ + DatasourceSvc: mockDatasourceSvc, + PluginContextProvider: mockPluginContextProvider, + PluginClient: mockPluginClient, + log: log.New("advisor.datasourcecheck"), + } + + ctx := identity.WithRequester(context.Background(), &user.SignedInUser{}) + items, err := check.Items(ctx) + assert.NoError(t, err) + failures := []advisor.CheckReportFailure{} + for _, step := range check.Steps() { + for _, item := range items { + stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item) + assert.NoError(t, err) + if stepFailures != nil { + failures = append(failures, *stepFailures) + } + } + } + + assert.NoError(t, err) + assert.Equal(t, 2, len(items)) + assert.Empty(t, failures) + }) + + t.Run("should return failures when datasource UID is invalid", func(t *testing.T) { + datasources := []*datasources.DataSource{ + {UID: "invalid uid", Type: "prometheus", Name: "Prometheus"}, + } + + mockDatasourceSvc := &MockDatasourceSvc{dss: datasources} + mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}} + mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusOk}} + + check := &check{ + DatasourceSvc: mockDatasourceSvc, + PluginContextProvider: mockPluginContextProvider, + PluginClient: mockPluginClient, + log: log.New("advisor.datasourcecheck"), + } + + ctx := identity.WithRequester(context.Background(), &user.SignedInUser{}) + items, err := check.Items(ctx) + assert.NoError(t, err) + failures := []advisor.CheckReportFailure{} + for _, step := range check.Steps() { + for _, item := range items { + stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item) + assert.NoError(t, err) + if stepFailures != nil { + failures = append(failures, *stepFailures) + } + } + } + + assert.NoError(t, err) + assert.Equal(t, 1, len(items)) + assert.Len(t, failures, 1) + assert.Equal(t, "uid-validation", failures[0].StepID) + }) + + t.Run("should return failures when datasource health check fails", func(t *testing.T) { + datasources := []*datasources.DataSource{ + {UID: "valid-uid-1", Type: "prometheus", Name: "Prometheus"}, + } + + mockDatasourceSvc := &MockDatasourceSvc{dss: datasources} + mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}} + mockPluginClient := &MockPluginClient{res: &backend.CheckHealthResult{Status: backend.HealthStatusError}} + + check := &check{ + DatasourceSvc: mockDatasourceSvc, + PluginContextProvider: mockPluginContextProvider, + PluginClient: mockPluginClient, + log: log.New("advisor.datasourcecheck"), + } + + ctx := identity.WithRequester(context.Background(), &user.SignedInUser{}) + items, err := check.Items(ctx) + assert.NoError(t, err) + failures := []advisor.CheckReportFailure{} + for _, step := range check.Steps() { + for _, item := range items { + stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item) + assert.NoError(t, err) + if stepFailures != nil { + failures = append(failures, *stepFailures) + } + } + } + + assert.NoError(t, err) + assert.Equal(t, 1, len(items)) + assert.Len(t, failures, 1) + assert.Equal(t, "health-check", failures[0].StepID) + }) + + t.Run("should skip health check when plugin does not support backend health checks", func(t *testing.T) { + datasources := []*datasources.DataSource{ + {UID: "valid-uid-1", Type: "prometheus", Name: "Prometheus"}, + } + mockDatasourceSvc := &MockDatasourceSvc{dss: datasources} + mockPluginContextProvider := &MockPluginContextProvider{pCtx: backend.PluginContext{}} + mockPluginClient := &MockPluginClient{err: plugins.ErrMethodNotImplemented} + + check := &check{ + DatasourceSvc: mockDatasourceSvc, + PluginContextProvider: mockPluginContextProvider, + PluginClient: mockPluginClient, + log: log.New("advisor.datasourcecheck"), + } + + ctx := identity.WithRequester(context.Background(), &user.SignedInUser{}) + items, err := check.Items(ctx) + assert.NoError(t, err) + failures := []advisor.CheckReportFailure{} + for _, step := range check.Steps() { + for _, item := range items { + stepFailures, err := step.Run(ctx, &advisor.CheckSpec{}, item) + assert.NoError(t, err) + if stepFailures != nil { + failures = append(failures, *stepFailures) + } + } + } + + assert.NoError(t, err) + assert.Equal(t, 1, len(items)) + assert.Len(t, failures, 0) + }) +} + +type MockDatasourceSvc struct { + datasources.DataSourceService + + dss []*datasources.DataSource +} + +func (m *MockDatasourceSvc) GetAllDataSources(ctx context.Context, query *datasources.GetAllDataSourcesQuery) ([]*datasources.DataSource, error) { + return m.dss, nil +} + +type MockPluginContextProvider struct { + pCtx backend.PluginContext +} + +func (m *MockPluginContextProvider) GetWithDataSource(ctx context.Context, pluginID string, user identity.Requester, ds *datasources.DataSource) (backend.PluginContext, error) { + return m.pCtx, nil +} + +type MockPluginClient struct { + plugins.Client + + res *backend.CheckHealthResult + err error +} + +func (m *MockPluginClient) CheckHealth(ctx context.Context, req *backend.CheckHealthRequest) (*backend.CheckHealthResult, error) { + return m.res, m.err +} diff --git a/apps/advisor/pkg/app/checks/ifaces.go b/apps/advisor/pkg/app/checks/ifaces.go new file mode 100644 index 00000000000..31456599381 --- /dev/null +++ b/apps/advisor/pkg/app/checks/ifaces.go @@ -0,0 +1,31 @@ +package checks + +import ( + "context" + + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" +) + +// Check returns metadata about the check being executed and the list of Steps +type Check interface { + // ID returns the unique identifier of the check + ID() string + // Items returns the list of items that will be checked + Items(ctx context.Context) ([]any, error) + // Steps returns the list of steps that will be executed + Steps() []Step +} + +// Step is a single step in a check, including its metadata +type Step interface { + // ID returns the unique identifier of the step + ID() string + // Title returns the title of the step + Title() string + // Description returns the description of the step + Description() string + // Explains the action that needs to be taken to resolve the issue + Resolution() string + // Run executes the step for an item and returns a report + Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error) +} diff --git a/apps/advisor/pkg/app/checks/plugincheck/check.go b/apps/advisor/pkg/app/checks/plugincheck/check.go new file mode 100644 index 00000000000..45c54d4fdc0 --- /dev/null +++ b/apps/advisor/pkg/app/checks/plugincheck/check.go @@ -0,0 +1,199 @@ +package plugincheck + +import ( + "context" + "fmt" + sysruntime "runtime" + + "github.com/Masterminds/semver/v3" + advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/pkg/cmd/grafana-cli/services" + "github.com/grafana/grafana/pkg/plugins/repo" + "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" + "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" +) + +func New( + pluginStore pluginstore.Store, + pluginRepo repo.Service, + pluginPreinstall plugininstaller.Preinstall, + managedPlugins managedplugins.Manager, +) checks.Check { + return &check{ + PluginStore: pluginStore, + PluginRepo: pluginRepo, + PluginPreinstall: pluginPreinstall, + ManagedPlugins: managedPlugins, + } +} + +type check struct { + PluginStore pluginstore.Store + PluginRepo repo.Service + PluginPreinstall plugininstaller.Preinstall + ManagedPlugins managedplugins.Manager +} + +func (c *check) ID() string { + return "plugin" +} + +func (c *check) Items(ctx context.Context) ([]any, error) { + ps := c.PluginStore.Plugins(ctx) + res := make([]any, len(ps)) + for i, p := range ps { + res[i] = p + } + return res, nil +} + +func (c *check) Steps() []checks.Step { + return []checks.Step{ + &deprecationStep{ + PluginRepo: c.PluginRepo, + }, + &updateStep{ + PluginRepo: c.PluginRepo, + PluginPreinstall: c.PluginPreinstall, + ManagedPlugins: c.ManagedPlugins, + }, + } +} + +type deprecationStep struct { + PluginRepo repo.Service +} + +func (s *deprecationStep) Title() string { + return "Deprecation check" +} + +func (s *deprecationStep) Description() string { + return "Check if any installed plugins are deprecated." +} + +func (s *deprecationStep) Resolution() string { + return "Check the documentation for recommended steps or delete the plugin." +} + +func (s *deprecationStep) ID() string { + return "deprecation" +} + +func (s *deprecationStep) Run(ctx context.Context, _ *advisor.CheckSpec, it any) (*advisor.CheckReportFailure, error) { + p, ok := it.(pluginstore.Plugin) + if !ok { + return nil, fmt.Errorf("invalid item type %T", it) + } + + // Skip if it's a core plugin + if p.IsCorePlugin() { + return nil, nil + } + + // Check if plugin is deprecated + i, err := s.PluginRepo.PluginInfo(ctx, p.ID) + if err != nil { + // Unable to check deprecation status + return nil, nil + } + if i.Status == "deprecated" { + return checks.NewCheckReportFailure( + advisor.CheckReportFailureSeverityHigh, + s.ID(), + p.ID, + []advisor.CheckErrorLink{ + { + Message: "Admin", + Url: fmt.Sprintf("/plugins/%s", p.ID), + }, + }, + ), nil + } + return nil, nil +} + +type updateStep struct { + PluginRepo repo.Service + PluginPreinstall plugininstaller.Preinstall + ManagedPlugins managedplugins.Manager +} + +func (s *updateStep) Title() string { + return "Update check" +} + +func (s *updateStep) Description() string { + return "Checks if an installed plugins has a newer version available." +} + +func (s *updateStep) Resolution() string { + return "Go to the plugin admin page and upgrade to the latest version." +} + +func (s *updateStep) ID() string { + return "update" +} + +func (s *updateStep) Run(ctx context.Context, _ *advisor.CheckSpec, i any) (*advisor.CheckReportFailure, error) { + p, ok := i.(pluginstore.Plugin) + if !ok { + return nil, fmt.Errorf("invalid item type %T", i) + } + + // Skip if it's a core plugin + if p.IsCorePlugin() { + return nil, nil + } + + // Skip if it's managed or pinned + if s.isManaged(ctx, p.ID) || s.PluginPreinstall.IsPinned(p.ID) { + return nil, nil + } + + // Check if plugin has a newer version available + compatOpts := repo.NewCompatOpts(services.GrafanaVersion, sysruntime.GOOS, sysruntime.GOARCH) + info, err := s.PluginRepo.GetPluginArchiveInfo(ctx, p.ID, "", compatOpts) + if err != nil { + // Unable to check updates + return nil, nil + } + if hasUpdate(p, info) { + return checks.NewCheckReportFailure( + advisor.CheckReportFailureSeverityLow, + s.ID(), + p.ID, + []advisor.CheckErrorLink{ + { + Message: "Upgrade", + Url: fmt.Sprintf("/plugins/%s?page=version-history", p.ID), + }, + }, + ), nil + } + + return nil, nil +} + +func hasUpdate(current pluginstore.Plugin, latest *repo.PluginArchiveInfo) bool { + // If both versions are semver-valid, compare them + v1, err1 := semver.NewVersion(current.Info.Version) + v2, err2 := semver.NewVersion(latest.Version) + if err1 == nil && err2 == nil { + return v1.LessThan(v2) + } + // In other case, assume that a different latest version will always be newer + return current.Info.Version != latest.Version +} + +func (s *updateStep) isManaged(ctx context.Context, pluginID string) bool { + for _, managedPlugin := range s.ManagedPlugins.ManagedPlugins(ctx) { + if managedPlugin == pluginID { + return true + } + } + return false +} diff --git a/apps/advisor/pkg/app/checks/plugincheck/check_test.go b/apps/advisor/pkg/app/checks/plugincheck/check_test.go new file mode 100644 index 00000000000..13b2a17ea1b --- /dev/null +++ b/apps/advisor/pkg/app/checks/plugincheck/check_test.go @@ -0,0 +1,210 @@ +package plugincheck + +import ( + "context" + "testing" + + advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/pkg/plugins" + "github.com/grafana/grafana/pkg/plugins/repo" + "github.com/grafana/grafana/pkg/services/pluginsintegration/managedplugins" + "github.com/grafana/grafana/pkg/services/pluginsintegration/plugininstaller" + "github.com/grafana/grafana/pkg/services/pluginsintegration/pluginstore" + "github.com/stretchr/testify/assert" +) + +func TestRun(t *testing.T) { + tests := []struct { + name string + plugins []pluginstore.Plugin + pluginInfo map[string]*repo.PluginInfo + pluginArchives map[string]*repo.PluginArchiveInfo + pluginPreinstalled []string + pluginManaged []string + expectedFailures []advisor.CheckReportFailure + }{ + { + name: "No plugins", + plugins: []pluginstore.Plugin{}, + expectedFailures: []advisor.CheckReportFailure{}, + }, + { + name: "Deprecated plugin", + plugins: []pluginstore.Plugin{ + {JSONData: plugins.JSONData{ID: "plugin1", Info: plugins.Info{Version: "1.0.0"}}}, + }, + pluginInfo: map[string]*repo.PluginInfo{ + "plugin1": {Status: "deprecated"}, + }, + pluginArchives: map[string]*repo.PluginArchiveInfo{ + "plugin1": {Version: "1.0.0"}, + }, + expectedFailures: []advisor.CheckReportFailure{ + { + Severity: advisor.CheckReportFailureSeverityHigh, + StepID: "deprecation", + Item: "plugin1", + Links: []advisor.CheckErrorLink{ + { + Url: "/plugins/plugin1", + Message: "Admin", + }, + }, + }, + }, + }, + { + name: "Plugin with update", + plugins: []pluginstore.Plugin{ + {JSONData: plugins.JSONData{ID: "plugin2", Info: plugins.Info{Version: "1.0.0"}}}, + }, + pluginInfo: map[string]*repo.PluginInfo{ + "plugin2": {Status: "active"}, + }, + pluginArchives: map[string]*repo.PluginArchiveInfo{ + "plugin2": {Version: "1.1.0"}, + }, + expectedFailures: []advisor.CheckReportFailure{ + { + Severity: advisor.CheckReportFailureSeverityLow, + StepID: "update", + Item: "plugin2", + Links: []advisor.CheckErrorLink{ + { + Url: "/plugins/plugin2?page=version-history", + Message: "Upgrade", + }, + }, + }, + }, + }, + { + name: "Plugin with update (non semver)", + plugins: []pluginstore.Plugin{ + {JSONData: plugins.JSONData{ID: "plugin2", Info: plugins.Info{Version: "alpha"}}}, + }, + pluginInfo: map[string]*repo.PluginInfo{ + "plugin2": {Status: "active"}, + }, + pluginArchives: map[string]*repo.PluginArchiveInfo{ + "plugin2": {Version: "beta"}, + }, + expectedFailures: []advisor.CheckReportFailure{ + { + Severity: advisor.CheckReportFailureSeverityLow, + StepID: "update", + Item: "plugin2", + Links: []advisor.CheckErrorLink{ + { + Url: "/plugins/plugin2?page=version-history", + Message: "Upgrade", + }, + }, + }, + }, + }, + { + name: "Plugin pinned", + plugins: []pluginstore.Plugin{ + {JSONData: plugins.JSONData{ID: "plugin3", Info: plugins.Info{Version: "1.0.0"}}}, + }, + pluginInfo: map[string]*repo.PluginInfo{ + "plugin3": {Status: "active"}, + }, + pluginArchives: map[string]*repo.PluginArchiveInfo{ + "plugin3": {Version: "1.1.0"}, + }, + pluginPreinstalled: []string{"plugin3"}, + expectedFailures: []advisor.CheckReportFailure{}, + }, + { + name: "Managed plugin", + plugins: []pluginstore.Plugin{ + {JSONData: plugins.JSONData{ID: "plugin4", Info: plugins.Info{Version: "1.0.0"}}}, + }, + pluginInfo: map[string]*repo.PluginInfo{ + "plugin4": {Status: "active"}, + }, + pluginArchives: map[string]*repo.PluginArchiveInfo{ + "plugin4": {Version: "1.1.0"}, + }, + pluginManaged: []string{"plugin4"}, + expectedFailures: []advisor.CheckReportFailure{}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + pluginStore := &mockPluginStore{plugins: tt.plugins} + pluginRepo := &mockPluginRepo{ + pluginInfo: tt.pluginInfo, + pluginArchiveInfo: tt.pluginArchives, + } + pluginPreinstall := &mockPluginPreinstall{pinned: tt.pluginPreinstalled} + managedPlugins := &mockManagedPlugins{managed: tt.pluginManaged} + check := New(pluginStore, pluginRepo, pluginPreinstall, managedPlugins) + + items, err := check.Items(context.Background()) + assert.NoError(t, err) + failures := []advisor.CheckReportFailure{} + for _, step := range check.Steps() { + for _, item := range items { + stepFailures, err := step.Run(context.Background(), &advisor.CheckSpec{}, item) + assert.NoError(t, err) + if stepFailures != nil { + failures = append(failures, *stepFailures) + } + } + } + assert.NoError(t, err) + assert.Equal(t, len(tt.plugins), len(items)) + assert.Equal(t, tt.expectedFailures, failures) + }) + } +} + +type mockPluginStore struct { + pluginstore.Store + plugins []pluginstore.Plugin +} + +func (m *mockPluginStore) Plugins(ctx context.Context, t ...plugins.Type) []pluginstore.Plugin { + return m.plugins +} + +type mockPluginRepo struct { + repo.Service + pluginInfo map[string]*repo.PluginInfo + pluginArchiveInfo map[string]*repo.PluginArchiveInfo +} + +func (m *mockPluginRepo) PluginInfo(ctx context.Context, id string) (*repo.PluginInfo, error) { + return m.pluginInfo[id], nil +} + +func (m *mockPluginRepo) GetPluginArchiveInfo(ctx context.Context, id, version string, opts repo.CompatOpts) (*repo.PluginArchiveInfo, error) { + return m.pluginArchiveInfo[id], nil +} + +type mockPluginPreinstall struct { + plugininstaller.Preinstall + pinned []string +} + +func (m *mockPluginPreinstall) IsPinned(pluginID string) bool { + for _, p := range m.pinned { + if p == pluginID { + return true + } + } + return false +} + +type mockManagedPlugins struct { + managedplugins.Manager + managed []string +} + +func (m *mockManagedPlugins) ManagedPlugins(ctx context.Context) []string { + return m.managed +} diff --git a/apps/advisor/pkg/app/checks/utils.go b/apps/advisor/pkg/app/checks/utils.go new file mode 100644 index 00000000000..145c98d0961 --- /dev/null +++ b/apps/advisor/pkg/app/checks/utils.go @@ -0,0 +1,40 @@ +package checks + +import ( + "fmt" + "strconv" + + "github.com/grafana/authlib/types" + advisor "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const ( + TypeLabel = "advisor.grafana.app/type" + StatusAnnotation = "advisor.grafana.app/status" +) + +func NewCheckReportFailure( + severity advisor.CheckReportFailureSeverity, + stepID string, + item string, + links []advisor.CheckErrorLink, +) *advisor.CheckReportFailure { + return &advisor.CheckReportFailure{ + Severity: severity, + StepID: stepID, + Item: item, + Links: links, + } +} + +func GetNamespace(stackID string) (string, error) { + if stackID == "" { + return metav1.NamespaceDefault, nil + } + stackId, err := strconv.ParseInt(stackID, 10, 64) + if err != nil { + return "", fmt.Errorf("invalid stack id: %s", stackID) + } + return types.CloudNamespaceFormatter(stackId), nil +} diff --git a/apps/advisor/pkg/app/checks/utils_test.go b/apps/advisor/pkg/app/checks/utils_test.go new file mode 100644 index 00000000000..ad0fda89de8 --- /dev/null +++ b/apps/advisor/pkg/app/checks/utils_test.go @@ -0,0 +1,46 @@ +package checks + +import ( + "testing" + + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestGetNamespace(t *testing.T) { + tests := []struct { + name string + input string + expected string + expectedErr string + }{ + { + name: "empty stack ID", + input: "", + expected: metav1.NamespaceDefault, + }, + { + name: "valid stack ID", + input: "1234567890", + expected: "stacks-1234567890", + }, + { + name: "invalid stack ID", + input: "invalid", + expected: "", + expectedErr: "invalid stack id: invalid", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result, err := GetNamespace(tt.input) + if tt.expectedErr != "" { + assert.EqualError(t, err, tt.expectedErr) + } else { + assert.NoError(t, err) + } + assert.Equal(t, tt.expected, result) + }) + } +} diff --git a/apps/advisor/pkg/app/checkscheduler/checkscheduler.go b/apps/advisor/pkg/app/checkscheduler/checkscheduler.go new file mode 100644 index 00000000000..2bcb8d43f19 --- /dev/null +++ b/apps/advisor/pkg/app/checkscheduler/checkscheduler.go @@ -0,0 +1,225 @@ +package checkscheduler + +import ( + "context" + "fmt" + "sort" + "strconv" + "time" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/k8s" + "github.com/grafana/grafana-app-sdk/resource" + "github.com/grafana/grafana-plugin-sdk-go/backend/gtime" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/klog/v2" +) + +const defaultEvaluationInterval = 24 * time.Hour +const defaultMaxHistory = 10 + +// Runner is a "runnable" app used to be able to expose and API endpoint +// with the existing checks types. This does not need to be a CRUD resource, but it is +// the only way existing at the moment to expose the check types. +type Runner struct { + checkRegistry checkregistry.CheckService + client resource.Client + evaluationInterval time.Duration + maxHistory int + namespace string +} + +// NewRunner creates a new Runner. +func New(cfg app.Config) (app.Runnable, error) { + // Read config + specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig) + if !ok { + return nil, fmt.Errorf("invalid config type") + } + checkRegistry := specificConfig.CheckRegistry + evalInterval, err := getEvaluationInterval(specificConfig.PluginConfig) + if err != nil { + return nil, err + } + maxHistory, err := getMaxHistory(specificConfig.PluginConfig) + if err != nil { + return nil, err + } + namespace, err := checks.GetNamespace(specificConfig.StackID) + if err != nil { + return nil, err + } + + // Prepare storage client + clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{}) + client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckKind()) + if err != nil { + return nil, err + } + + return &Runner{ + checkRegistry: checkRegistry, + client: client, + evaluationInterval: evalInterval, + maxHistory: maxHistory, + namespace: namespace, + }, nil +} + +func (r *Runner) Run(ctx context.Context) error { + lastCreated, err := r.checkLastCreated(ctx) + if err != nil { + return err + } + + // do an initial creation if necessary + if lastCreated.IsZero() { + err = r.createChecks(ctx) + if err != nil { + klog.Error("Error creating new check reports", "error", err) + } else { + lastCreated = time.Now() + } + } + + nextSendInterval := time.Until(lastCreated.Add(r.evaluationInterval)) + if nextSendInterval < time.Minute { + nextSendInterval = 1 * time.Minute + } + + ticker := time.NewTicker(nextSendInterval) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + err = r.createChecks(ctx) + if err != nil { + klog.Error("Error creating new check reports", "error", err) + } + + err = r.cleanupChecks(ctx) + if err != nil { + klog.Error("Error cleaning up old check reports", "error", err) + } + + if nextSendInterval != r.evaluationInterval { + nextSendInterval = r.evaluationInterval + } + ticker.Reset(nextSendInterval) + case <-ctx.Done(): + return ctx.Err() + } + } +} + +// checkLastCreated returns the creation time of the last check created +// regardless of its ID. This assumes that the checks are created in batches +// so a batch will have a similar creation time. +func (r *Runner) checkLastCreated(ctx context.Context) (time.Time, error) { + list, err := r.client.List(ctx, r.namespace, resource.ListOptions{}) + if err != nil { + return time.Time{}, err + } + lastCreated := time.Time{} + for _, item := range list.GetItems() { + itemCreated := item.GetCreationTimestamp().Time + if itemCreated.After(lastCreated) { + lastCreated = itemCreated + } + } + return lastCreated, nil +} + +// createChecks creates a new check for each check type in the registry. +func (r *Runner) createChecks(ctx context.Context) error { + for _, check := range r.checkRegistry.Checks() { + obj := &advisorv0alpha1.Check{ + ObjectMeta: metav1.ObjectMeta{ + GenerateName: "check-", + Namespace: r.namespace, + Labels: map[string]string{ + checks.TypeLabel: check.ID(), + }, + }, + Spec: advisorv0alpha1.CheckSpec{}, + } + id := obj.GetStaticMetadata().Identifier() + _, err := r.client.Create(ctx, id, obj, resource.CreateOptions{}) + if err != nil { + return fmt.Errorf("error creating check: %w", err) + } + } + return nil +} + +// cleanupChecks deletes the olders checks if the number of checks exceeds the limit. +func (r *Runner) cleanupChecks(ctx context.Context) error { + list, err := r.client.List(ctx, r.namespace, resource.ListOptions{Limit: -1}) + if err != nil { + return err + } + + // organize checks by type + checksByType := map[string][]resource.Object{} + for _, check := range list.GetItems() { + labels := check.GetLabels() + checkType, ok := labels[checks.TypeLabel] + if !ok { + klog.Error("Check type not found in labels", "check", check) + continue + } + checksByType[checkType] = append(checksByType[checkType], check) + } + + for _, checks := range checksByType { + if len(checks) > r.maxHistory { + // Sort checks by creation time + sort.Slice(checks, func(i, j int) bool { + ti := checks[i].GetCreationTimestamp().Time + tj := checks[j].GetCreationTimestamp().Time + return ti.Before(tj) + }) + // Delete the oldest checks + for i := 0; i < len(checks)-r.maxHistory; i++ { + check := checks[i] + id := check.GetStaticMetadata().Identifier() + err := r.client.Delete(ctx, id, resource.DeleteOptions{}) + if err != nil { + return fmt.Errorf("error deleting check: %w", err) + } + } + } + } + + return nil +} + +func getEvaluationInterval(pluginConfig map[string]string) (time.Duration, error) { + evaluationInterval := defaultEvaluationInterval + configEvaluationInterval, ok := pluginConfig["evaluation_interval"] + if ok { + var err error + evaluationInterval, err = gtime.ParseDuration(configEvaluationInterval) + if err != nil { + return 0, fmt.Errorf("invalid evaluation interval: %w", err) + } + } + return evaluationInterval, nil +} + +func getMaxHistory(pluginConfig map[string]string) (int, error) { + maxHistory := defaultMaxHistory + configMaxHistory, ok := pluginConfig["max_history"] + if ok { + var err error + maxHistory, err = strconv.Atoi(configMaxHistory) + if err != nil { + return 0, fmt.Errorf("invalid max history: %w", err) + } + } + return maxHistory, nil +} diff --git a/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go b/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go new file mode 100644 index 00000000000..4fd5876b9ff --- /dev/null +++ b/apps/advisor/pkg/app/checkscheduler/checkscheduler_test.go @@ -0,0 +1,279 @@ +package checkscheduler + +import ( + "context" + "errors" + "fmt" + "math/rand/v2" + "testing" + "time" + + "github.com/grafana/grafana-app-sdk/resource" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/stretchr/testify/assert" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestRunner_Run_ErrorOnList(t *testing.T) { + mockCheckService := &MockCheckService{} + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return nil, errors.New("list error") + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return &advisorv0alpha1.Check{}, nil + }, + } + + runner := &Runner{ + checkRegistry: mockCheckService, + client: mockClient, + } + + err := runner.Run(context.Background()) + assert.Error(t, err) +} + +func TestRunner_checkLastCreated_ErrorOnList(t *testing.T) { + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return nil, errors.New("list error") + }, + } + + runner := &Runner{ + client: mockClient, + } + + lastCreated, err := runner.checkLastCreated(context.Background()) + assert.Error(t, err) + assert.True(t, lastCreated.IsZero()) +} + +func TestRunner_createChecks_ErrorOnCreate(t *testing.T) { + mockCheckService := &MockCheckService{ + checks: []checks.Check{ + &mockCheck{ + id: "check-1", + }, + }, + } + mockClient := &MockClient{ + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return nil, errors.New("create error") + }, + } + + runner := &Runner{ + checkRegistry: mockCheckService, + client: mockClient, + } + + err := runner.createChecks(context.Background()) + assert.Error(t, err) +} + +func TestRunner_createChecks_Success(t *testing.T) { + mockCheckService := &MockCheckService{ + checks: []checks.Check{ + &mockCheck{ + id: "check-1", + }, + }, + } + mockClient := &MockClient{ + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return &advisorv0alpha1.Check{}, nil + }, + } + + runner := &Runner{ + checkRegistry: mockCheckService, + client: mockClient, + } + + err := runner.createChecks(context.Background()) + assert.NoError(t, err) +} + +func TestRunner_cleanupChecks_ErrorOnList(t *testing.T) { + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return nil, errors.New("list error") + }, + } + + runner := &Runner{ + client: mockClient, + } + + err := runner.cleanupChecks(context.Background()) + assert.Error(t, err) +} + +func TestRunner_cleanupChecks_WithinMax(t *testing.T) { + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return &advisorv0alpha1.CheckList{ + Items: []advisorv0alpha1.Check{{}, {}}, + }, nil + }, + deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error { + return fmt.Errorf("shouldn't be called") + }, + } + + runner := &Runner{ + client: mockClient, + } + + err := runner.cleanupChecks(context.Background()) + assert.NoError(t, err) +} + +func TestRunner_cleanupChecks_ErrorOnDelete(t *testing.T) { + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + items := make([]advisorv0alpha1.Check, 0, defaultMaxHistory+1) + for i := 0; i < defaultMaxHistory+1; i++ { + item := advisorv0alpha1.Check{} + item.ObjectMeta.SetLabels(map[string]string{ + checks.TypeLabel: "mock", + }) + items = append(items, item) + } + return &advisorv0alpha1.CheckList{ + Items: items, + }, nil + }, + deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error { + return errors.New("delete error") + }, + } + + runner := &Runner{ + client: mockClient, + maxHistory: defaultMaxHistory, + } + err := runner.cleanupChecks(context.Background()) + assert.ErrorContains(t, err, "delete error") +} + +func TestRunner_cleanupChecks_Success(t *testing.T) { + itemsDeleted := []string{} + items := make([]advisorv0alpha1.Check, 0, defaultMaxHistory+1) + for i := 0; i < defaultMaxHistory+1; i++ { + item := advisorv0alpha1.Check{} + item.ObjectMeta.SetName(fmt.Sprintf("check-%d", i)) + item.ObjectMeta.SetLabels(map[string]string{ + checks.TypeLabel: "mock", + }) + item.ObjectMeta.SetCreationTimestamp(metav1.NewTime(time.Time{}.Add(time.Duration(i) * time.Hour))) + items = append(items, item) + } + // shuffle the items to ensure the oldest are deleted + rand.Shuffle(len(items), func(i, j int) { items[i], items[j] = items[j], items[i] }) + + mockClient := &MockClient{ + listFunc: func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return &advisorv0alpha1.CheckList{ + Items: items, + }, nil + }, + deleteFunc: func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error { + itemsDeleted = append(itemsDeleted, identifier.Name) + return nil + }, + } + + runner := &Runner{ + client: mockClient, + maxHistory: defaultMaxHistory, + } + err := runner.cleanupChecks(context.Background()) + assert.NoError(t, err) + assert.Equal(t, []string{"check-0"}, itemsDeleted) +} + +func Test_getEvaluationInterval(t *testing.T) { + t.Run("default", func(t *testing.T) { + interval, err := getEvaluationInterval(map[string]string{}) + assert.NoError(t, err) + assert.Equal(t, 24*time.Hour, interval) + }) + + t.Run("invalid", func(t *testing.T) { + interval, err := getEvaluationInterval(map[string]string{"evaluation_interval": "invalid"}) + assert.Error(t, err) + assert.Zero(t, interval) + }) + + t.Run("custom", func(t *testing.T) { + interval, err := getEvaluationInterval(map[string]string{"evaluation_interval": "1h"}) + assert.NoError(t, err) + assert.Equal(t, time.Hour, interval) + }) +} + +func Test_getMaxHistory(t *testing.T) { + t.Run("default", func(t *testing.T) { + history, err := getMaxHistory(map[string]string{}) + assert.NoError(t, err) + assert.Equal(t, 10, history) + }) + + t.Run("invalid", func(t *testing.T) { + history, err := getMaxHistory(map[string]string{"max_history": "invalid"}) + assert.Error(t, err) + assert.Zero(t, history) + }) + + t.Run("custom", func(t *testing.T) { + history, err := getMaxHistory(map[string]string{"max_history": "5"}) + assert.NoError(t, err) + assert.Equal(t, 5, history) + }) +} + +type MockCheckService struct { + checks []checks.Check +} + +func (m *MockCheckService) Checks() []checks.Check { + return m.checks +} + +type MockClient struct { + resource.Client + listFunc func(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) + createFunc func(ctx context.Context, identifier resource.Identifier, obj resource.Object, options resource.CreateOptions) (resource.Object, error) + deleteFunc func(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error +} + +func (m *MockClient) List(ctx context.Context, namespace string, options resource.ListOptions) (resource.ListObject, error) { + return m.listFunc(ctx, namespace, options) +} + +func (m *MockClient) Create(ctx context.Context, identifier resource.Identifier, obj resource.Object, options resource.CreateOptions) (resource.Object, error) { + return m.createFunc(ctx, identifier, obj, options) +} + +func (m *MockClient) Delete(ctx context.Context, identifier resource.Identifier, options resource.DeleteOptions) error { + return m.deleteFunc(ctx, identifier, options) +} + +type mockCheck struct { + checks.Check + + id string + steps []checks.Step +} + +func (m *mockCheck) ID() string { + return m.id +} + +func (m *mockCheck) Steps() []checks.Step { + return m.steps +} diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go new file mode 100644 index 00000000000..2ed38e51ecb --- /dev/null +++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer.go @@ -0,0 +1,91 @@ +package checktyperegisterer + +import ( + "context" + "fmt" + + "github.com/grafana/grafana-app-sdk/app" + "github.com/grafana/grafana-app-sdk/k8s" + "github.com/grafana/grafana-app-sdk/resource" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checkregistry" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// Runner is a "runnable" app used to be able to expose and API endpoint +// with the existing checks types. This does not need to be a CRUD resource, but it is +// the only way existing at the moment to expose the check types. +type Runner struct { + checkRegistry checkregistry.CheckService + client resource.Client + namespace string +} + +// NewRunner creates a new Runner. +func New(cfg app.Config) (app.Runnable, error) { + // Read config + specificConfig, ok := cfg.SpecificConfig.(checkregistry.AdvisorAppConfig) + if !ok { + return nil, fmt.Errorf("invalid config type") + } + checkRegistry := specificConfig.CheckRegistry + namespace, err := checks.GetNamespace(specificConfig.StackID) + if err != nil { + return nil, err + } + + // Prepare storage client + clientGenerator := k8s.NewClientRegistry(cfg.KubeConfig, k8s.ClientConfig{}) + client, err := clientGenerator.ClientFor(advisorv0alpha1.CheckTypeKind()) + if err != nil { + return nil, err + } + + return &Runner{ + checkRegistry: checkRegistry, + client: client, + namespace: namespace, + }, nil +} + +func (r *Runner) Run(ctx context.Context) error { + for _, t := range r.checkRegistry.Checks() { + steps := t.Steps() + stepTypes := make([]advisorv0alpha1.CheckTypeStep, len(steps)) + for i, s := range steps { + stepTypes[i] = advisorv0alpha1.CheckTypeStep{ + Title: s.Title(), + Description: s.Description(), + StepID: s.ID(), + Resolution: s.Resolution(), + } + } + obj := &advisorv0alpha1.CheckType{ + ObjectMeta: metav1.ObjectMeta{ + Name: t.ID(), + Namespace: r.namespace, + }, + Spec: advisorv0alpha1.CheckTypeSpec{ + Name: t.ID(), + Steps: stepTypes, + }, + } + id := obj.GetStaticMetadata().Identifier() + _, err := r.client.Create(ctx, id, obj, resource.CreateOptions{}) + if err != nil { + if errors.IsAlreadyExists(err) { + // Already exists, update + _, err = r.client.Update(ctx, id, obj, resource.UpdateOptions{}) + if err != nil { + return err + } else { + continue + } + } + return err + } + } + return nil +} diff --git a/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go new file mode 100644 index 00000000000..97fc7742504 --- /dev/null +++ b/apps/advisor/pkg/app/checktyperegisterer/checktyperegisterer_test.go @@ -0,0 +1,196 @@ +package checktyperegisterer + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/grafana/grafana-app-sdk/resource" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + k8sErrs "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +func TestCheckTypesRegisterer_Run(t *testing.T) { + tests := []struct { + name string + checks []checks.Check + createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) + updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) + expectedErr error + }{ + { + name: "successful create", + checks: []checks.Check{ + &mockCheck{ + id: "check1", + steps: []checks.Step{ + &mockStep{id: "step1", title: "Step 1", description: "Description 1"}, + }, + }, + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return obj, nil + }, + updateFunc: nil, + expectedErr: nil, + }, + { + name: "create already exists, successful update", + checks: []checks.Check{ + &mockCheck{ + id: "check1", + steps: []checks.Step{ + &mockStep{id: "step1", title: "Step 1", description: "Description 1"}, + }, + }, + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return nil, k8sErrs.NewAlreadyExists(schema.GroupResource{}, obj.GetName()) + }, + updateFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) { + return obj, nil + }, + expectedErr: nil, + }, + { + name: "create error", + checks: []checks.Check{ + &mockCheck{ + id: "check1", + steps: []checks.Step{ + &mockStep{id: "step1", title: "Step 1", description: "Description 1"}, + }, + }, + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return nil, errors.New("create error") + }, + updateFunc: nil, + expectedErr: errors.New("create error"), + }, + { + name: "update error", + checks: []checks.Check{ + &mockCheck{ + id: "check1", + steps: []checks.Step{ + &mockStep{id: "step1", title: "Step 1", description: "Description 1"}, + }, + }, + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return nil, k8sErrs.NewAlreadyExists(schema.GroupResource{}, obj.GetName()) + }, + updateFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) { + return nil, errors.New("update error") + }, + expectedErr: errors.New("update error"), + }, + { + name: "custom namespace", + checks: []checks.Check{ + &mockCheck{ + id: "check1", + steps: []checks.Step{ + &mockStep{id: "step1", title: "Step 1", description: "Description 1"}, + }, + }, + }, + createFunc: func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + if obj.GetNamespace() != "custom-namespace" { + return nil, fmt.Errorf("expected namespace %s, got %s", "custom-namespace", obj.GetNamespace()) + } + return obj, nil + }, + expectedErr: nil, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &Runner{ + checkRegistry: &mockCheckRegistry{checks: tt.checks}, + client: &mockClient{ + createFunc: tt.createFunc, + updateFunc: tt.updateFunc, + }, + namespace: "custom-namespace", + } + err := r.Run(context.Background()) + if err != nil { + if tt.expectedErr == nil { + t.Errorf("unexpected error: %v", err) + } else if err.Error() != tt.expectedErr.Error() { + t.Errorf("expected error: %v, got: %v", tt.expectedErr, err) + } + } + }) + } +} + +type mockCheckRegistry struct { + checks []checks.Check +} + +func (m *mockCheckRegistry) Checks() []checks.Check { + return m.checks +} + +type mockCheck struct { + checks.Check + + id string + steps []checks.Step +} + +func (m *mockCheck) ID() string { + return m.id +} + +func (m *mockCheck) Steps() []checks.Step { + return m.steps +} + +type mockStep struct { + id string + title string + description string +} + +func (m *mockStep) ID() string { + return m.id +} + +func (m *mockStep) Title() string { + return m.title +} + +func (m *mockStep) Description() string { + return m.description +} + +func (m *mockStep) Resolution() string { + return "" +} + +func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, item any) (*advisorv0alpha1.CheckReportFailure, error) { + return nil, nil +} + +type mockClient struct { + resource.Client + + createFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) + updateFunc func(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) +} + +func (m *mockClient) Create(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.CreateOptions) (resource.Object, error) { + return m.createFunc(ctx, id, obj, opts) +} + +func (m *mockClient) Update(ctx context.Context, id resource.Identifier, obj resource.Object, opts resource.UpdateOptions) (resource.Object, error) { + return m.updateFunc(ctx, id, obj, opts) +} diff --git a/apps/advisor/pkg/app/utils.go b/apps/advisor/pkg/app/utils.go new file mode 100644 index 00000000000..8c1b6c00eb8 --- /dev/null +++ b/apps/advisor/pkg/app/utils.go @@ -0,0 +1,143 @@ +package app + +import ( + "context" + "errors" + "fmt" + "sync" + + claims "github.com/grafana/authlib/types" + "github.com/grafana/grafana-app-sdk/resource" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/pkg/apimachinery/identity" + "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/grafana/grafana/pkg/services/user" +) + +func getCheck(obj resource.Object, checkMap map[string]checks.Check) (checks.Check, error) { + labels := obj.GetLabels() + objTypeLabel, ok := labels[checks.TypeLabel] + if !ok { + return nil, errors.New("missing check type as label") + } + c, ok := checkMap[objTypeLabel] + if !ok { + supportedTypes := "" + for k := range checkMap { + supportedTypes += k + ", " + } + return nil, fmt.Errorf("unknown check type %s. Supported types are: %s", objTypeLabel, supportedTypes) + } + + return c, nil +} + +func getStatusAnnotation(obj resource.Object) string { + return obj.GetAnnotations()[checks.StatusAnnotation] +} + +func setStatusAnnotation(ctx context.Context, client resource.Client, obj resource.Object, status string) error { + annotations := obj.GetAnnotations() + annotations[checks.StatusAnnotation] = status + return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{ + Operations: []resource.PatchOperation{{ + Operation: resource.PatchOpAdd, + Path: "/metadata/annotations", + Value: annotations, + }}, + }, resource.PatchOptions{}, obj) +} + +func processCheck(ctx context.Context, client resource.Client, obj resource.Object, check checks.Check) error { + status := getStatusAnnotation(obj) + if status != "" { + // Check already processed + return nil + } + c, ok := obj.(*advisorv0alpha1.Check) + if !ok { + return fmt.Errorf("invalid object type") + } + // Populate ctx with the user that created the check + meta, err := utils.MetaAccessor(obj) + if err != nil { + return err + } + createdBy := meta.GetCreatedBy() + typ, uid, err := claims.ParseTypeID(createdBy) + if err != nil { + return err + } + ctx = identity.WithRequester(ctx, &user.SignedInUser{ + UserUID: uid, + FallbackType: typ, + }) + // Get the items to check + items, err := check.Items(ctx) + if err != nil { + setErr := setStatusAnnotation(ctx, client, obj, "error") + if setErr != nil { + return setErr + } + return fmt.Errorf("error initializing check: %w", err) + } + // Run the steps + steps := check.Steps() + failures, err := runStepsInParallel(ctx, &c.Spec, steps, items) + if err != nil { + setErr := setStatusAnnotation(ctx, client, obj, "error") + if setErr != nil { + return setErr + } + return fmt.Errorf("error running steps: %w", err) + } + + report := &advisorv0alpha1.CheckV0alpha1StatusReport{ + Failures: failures, + Count: int64(len(items)), + } + err = setStatusAnnotation(ctx, client, obj, "processed") + if err != nil { + return err + } + return client.PatchInto(ctx, obj.GetStaticMetadata().Identifier(), resource.PatchRequest{ + Operations: []resource.PatchOperation{{ + Operation: resource.PatchOpAdd, + Path: "/status/report", + Value: *report, + }}, + }, resource.PatchOptions{}, obj) +} + +func runStepsInParallel(ctx context.Context, spec *advisorv0alpha1.CheckSpec, steps []checks.Step, items []any) ([]advisorv0alpha1.CheckReportFailure, error) { + reportFailures := []advisorv0alpha1.CheckReportFailure{} + var internalErr error + var wg sync.WaitGroup + var mu sync.Mutex + // Avoid too many concurrent requests + limit := make(chan struct{}, 10) + + for _, step := range steps { + for _, item := range items { + wg.Add(1) + limit <- struct{}{} + go func(step checks.Step, item any) { + defer wg.Done() + defer func() { <-limit }() + stepErr, err := step.Run(ctx, spec, item) + mu.Lock() + defer mu.Unlock() + if err != nil { + internalErr = fmt.Errorf("error running step %s: %w", step.ID(), err) + return + } + if stepErr != nil { + reportFailures = append(reportFailures, *stepErr) + } + }(step, item) + } + } + wg.Wait() + return reportFailures, internalErr +} diff --git a/apps/advisor/pkg/app/utils_test.go b/apps/advisor/pkg/app/utils_test.go new file mode 100644 index 00000000000..b3b8d36f60b --- /dev/null +++ b/apps/advisor/pkg/app/utils_test.go @@ -0,0 +1,200 @@ +package app + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/grafana/grafana-app-sdk/resource" + advisorv0alpha1 "github.com/grafana/grafana/apps/advisor/pkg/apis/advisor/v0alpha1" + "github.com/grafana/grafana/apps/advisor/pkg/app/checks" + "github.com/grafana/grafana/pkg/apimachinery/utils" + "github.com/stretchr/testify/assert" +) + +func TestGetCheck(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetLabels(map[string]string{checks.TypeLabel: "testType"}) + + checkMap := map[string]checks.Check{ + "testType": &mockCheck{}, + } + + check, err := getCheck(obj, checkMap) + assert.NoError(t, err) + assert.NotNil(t, check) +} + +func TestGetCheck_MissingLabel(t *testing.T) { + obj := &advisorv0alpha1.Check{} + checkMap := map[string]checks.Check{} + + _, err := getCheck(obj, checkMap) + assert.Error(t, err) + assert.Equal(t, "missing check type as label", err.Error()) +} + +func TestGetCheck_UnknownType(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetLabels(map[string]string{checks.TypeLabel: "unknownType"}) + + checkMap := map[string]checks.Check{ + "testType": &mockCheck{}, + } + + _, err := getCheck(obj, checkMap) + assert.Error(t, err) + assert.Contains(t, err.Error(), "unknown check type unknownType") +} + +func TestSetStatusAnnotation(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetAnnotations(map[string]string{}) + client := &mockClient{} + ctx := context.TODO() + + err := setStatusAnnotation(ctx, client, obj, "processed") + assert.NoError(t, err) + assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation]) +} + +func TestProcessCheck(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetAnnotations(map[string]string{}) + meta, err := utils.MetaAccessor(obj) + if err != nil { + t.Fatal(err) + } + meta.SetCreatedBy("user:1") + client := &mockClient{} + ctx := context.TODO() + check := &mockCheck{ + items: []any{"item"}, + } + + err = processCheck(ctx, client, obj, check) + assert.NoError(t, err) + assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation]) +} + +func TestProcessMultipleCheckItems(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetAnnotations(map[string]string{}) + meta, err := utils.MetaAccessor(obj) + if err != nil { + t.Fatal(err) + } + meta.SetCreatedBy("user:1") + client := &mockClient{} + ctx := context.TODO() + items := make([]any, 100) + for i := range items { + if i%2 == 0 { + items[i] = fmt.Sprintf("item-%d", i) + } else { + items[i] = errors.New("error") + } + } + check := &mockCheck{ + items: items, + } + + err = processCheck(ctx, client, obj, check) + assert.NoError(t, err) + assert.Equal(t, "processed", obj.GetAnnotations()[checks.StatusAnnotation]) + r := client.lastValue.(advisorv0alpha1.CheckV0alpha1StatusReport) + assert.Equal(t, r.Count, int64(100)) + assert.Len(t, r.Failures, 50) +} + +func TestProcessCheck_AlreadyProcessed(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetAnnotations(map[string]string{checks.StatusAnnotation: "processed"}) + client := &mockClient{} + ctx := context.TODO() + check := &mockCheck{} + + err := processCheck(ctx, client, obj, check) + assert.NoError(t, err) +} + +func TestProcessCheck_RunError(t *testing.T) { + obj := &advisorv0alpha1.Check{} + obj.SetAnnotations(map[string]string{}) + meta, err := utils.MetaAccessor(obj) + if err != nil { + t.Fatal(err) + } + meta.SetCreatedBy("user:1") + client := &mockClient{} + ctx := context.TODO() + + check := &mockCheck{ + items: []any{"item"}, + err: errors.New("run error"), + } + + err = processCheck(ctx, client, obj, check) + assert.Error(t, err) + assert.Equal(t, "error", obj.GetAnnotations()[checks.StatusAnnotation]) +} + +type mockClient struct { + resource.Client + lastValue any +} + +func (m *mockClient) PatchInto(ctx context.Context, id resource.Identifier, req resource.PatchRequest, opts resource.PatchOptions, obj resource.Object) error { + m.lastValue = req.Operations[0].Value + return nil +} + +type mockCheck struct { + err error + items []any +} + +func (m *mockCheck) ID() string { + return "mock" +} + +func (m *mockCheck) Items(ctx context.Context) ([]any, error) { + return m.items, nil +} + +func (m *mockCheck) Steps() []checks.Step { + return []checks.Step{ + &mockStep{err: m.err}, + } +} + +type mockStep struct { + err error +} + +func (m *mockStep) Run(ctx context.Context, obj *advisorv0alpha1.CheckSpec, items any) (*advisorv0alpha1.CheckReportFailure, error) { + if m.err != nil { + return nil, m.err + } + if _, ok := items.(error); ok { + return &advisorv0alpha1.CheckReportFailure{}, nil + } + return nil, nil +} + +func (m *mockStep) Title() string { + return "mock" +} + +func (m *mockStep) Description() string { + return "mock" +} + +func (m *mockStep) Resolution() string { + return "mock" +} + +func (m *mockStep) ID() string { + return "mock" +} diff --git a/apps/advisor/plugin/README.md b/apps/advisor/plugin/README.md new file mode 100644 index 00000000000..5b9e2bc8744 --- /dev/null +++ b/apps/advisor/plugin/README.md @@ -0,0 +1,7 @@ +This folder contains the automatically generated types for the frontend that are used in the app plugin. + +To update the types: + +1. Make any necessary changes in the `kinds` directory +2. Run `make generate` +3. Copy the `plugin` directory to the frontend app: https://github.com/grafana/grafana-advisor-app/tree/main/src/plugin diff --git a/apps/alerting/notifications/go.mod b/apps/alerting/notifications/go.mod index 61093d88f4b..eaa0b14475d 100644 --- a/apps/alerting/notifications/go.mod +++ b/apps/alerting/notifications/go.mod @@ -1,14 +1,14 @@ module github.com/grafana/grafana/apps/alerting/notifications -go 1.23.5 +go 1.23.7 replace github.com/grafana/grafana => ../../.. require ( github.com/grafana/grafana v11.4.0-00010101000000-000000000000+incompatible - github.com/grafana/grafana-app-sdk v0.30.0 - k8s.io/apimachinery v0.32.0 - k8s.io/apiserver v0.32.0 + github.com/grafana/grafana-app-sdk v0.31.0 + k8s.io/apimachinery v0.32.1 + k8s.io/apiserver v0.32.1 k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f ) @@ -32,13 +32,13 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d // indirect + github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250220154326-6e5de80ef295 // indirect github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jmespath-community/go-jmespath v1.1.1 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -50,46 +50,46 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.21.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - github.com/spf13/cobra v1.8.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/cobra v1.9.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/x448/float16 v0.8.4 // indirect go.etcd.io/etcd/api/v3 v3.5.16 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.16 // indirect go.etcd.io/etcd/client/v3 v3.5.16 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.27.0 // indirect - golang.org/x/crypto v0.32.0 // indirect + golang.org/x/crypto v0.35.0 // indirect golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/grpc v1.69.4 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect + google.golang.org/grpc v1.70.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.32.0 // indirect - k8s.io/client-go v0.32.0 // indirect - k8s.io/component-base v0.32.0 // indirect + k8s.io/api v0.32.1 // indirect + k8s.io/client-go v0.32.1 // indirect + k8s.io/component-base v0.32.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.31.0 // indirect diff --git a/apps/alerting/notifications/go.sum b/apps/alerting/notifications/go.sum index a140089cc39..26ad8bf9fc2 100644 --- a/apps/alerting/notifications/go.sum +++ b/apps/alerting/notifications/go.sum @@ -19,7 +19,7 @@ github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec= github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -60,8 +60,8 @@ github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl76 github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -71,18 +71,18 @@ github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/grafana-app-sdk v0.30.0 h1:Hqn2pETu2mQ4RpWkZYEQfu01P7xd1Z1Gj+HX/8aB0tw= -github.com/grafana/grafana-app-sdk v0.30.0/go.mod h1:jhfqNIovb+Mes2vdMf9iMCWQkp1GTNtyNuExONtiNuk= -github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d h1:0WJ4uZ3gtbX7S5RGMarA+0TccmB7qEPhhNm34NcfBzs= -github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250121113133-e747350fee2d/go.mod h1:PNmbi49lVrv2b2I8pdu46dTs2728lKEbnVuQD8I5MnM= +github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250220154326-6e5de80ef295 h1:bOKkAzmkCnK2EN0LGsHoq5HyfXMLKXrr8+q35Fh+XQI= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250220154326-6e5de80ef295/go.mod h1:1iWqntBW91TsiyqneHrqTFV12vd1Tei+f5VY2ovkNAo= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 h1:uGoIog/wiQHI9GAxXO5TJbT0wWKH3O9HhOJW1F9c3fY= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340/go.mod h1:3bDW6wMZJB7tiONtC/1Xpicra6Wp5GgbTbQWCbI5fkc= github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jmespath-community/go-jmespath v1.1.1 h1:bFikPhsi/FdmlZhVgSCd2jj1e7G/rw+zyQfyg5UF+L4= @@ -113,25 +113,25 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= +github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= @@ -142,10 +142,10 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/spf13/cobra v1.8.1 h1:e5/vxKd/rZsfSJMUX1agtjeTDf+qv1/JdBF8gg5k9ZM= -github.com/spf13/cobra v1.8.1/go.mod h1:wHxEcudfqmLYa8iTfL+OuZPbBZkmvliBWKIezN3kD9Y= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -178,24 +178,24 @@ go.etcd.io/etcd/server/v3 v3.5.16 h1:d0/SAdJ3vVsZvF8IFVb1k8zqMZ+heGcNfft71ul9GWE go.etcd.io/etcd/server/v3 v3.5.16/go.mod h1:ynhyZZpdDp1Gq49jkUg5mfkDWZwXnn3eIqCqtJnrD/s= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0 h1:PS8wXpbyaDJQ2VDHHncMe9Vct0Zn1fEjpsjrLxGJoSc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.58.0/go.mod h1:HDBUsEjOuRC0EzKZ1bSaRGZWUBAzo+MhAcUUORSr4D0= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0 h1:yd02MEjBdJkG3uabWP9apV+OuWRIXGDuJEUJbOHmCFU= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.58.0/go.mod h1:umTcuxiv1n/s/S6/c2AT/g2CQ7u5C59sHDNmfSwgz7Q= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0 h1:rgMkmiGfix9vFJDcDi1PK8WEQP4FLQwLDfhp5ZLpFeE= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.59.0/go.mod h1:ijPqXp5P6IRRByFVVg9DY8P5HkxkHE5ARIa+86aXPf4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0 h1:CV7UdSGJt/Ao6Gp4CXckLxVRRsRgDHoI8XjbL3PDl8s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.59.0/go.mod h1:FRmFuRJfag1IZ2dPkHnEoSFVgTVPUd2qf5Vi69hLb8I= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -207,8 +207,8 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= -golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -223,11 +223,11 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -237,14 +237,14 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -260,17 +260,17 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38 h1:Q3nlH8iSQSRUwOskjbcSMcF2jiYMNiQYZ0c2KEJLKKU= -google.golang.org/genproto v0.0.0-20241021214115-324edc3d5d38/go.mod h1:xBI+tzfqGGN2JBeSebfKXFSdBpWVQ7sLW40PTupVRm4= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= +google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4 h1:Pw6WnI9W/LIdRxqK7T6XGugGbHIRl5Q7q3BssH6xk4s= +google.golang.org/genproto v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:qbZzneIOXSq+KFAFut9krLfRLZiFLzZL5u2t8SV83EE= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.18.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= -google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= -google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -283,16 +283,16 @@ gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYs gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/apiserver v0.32.0 h1:VJ89ZvQZ8p1sLeiWdRJpRD6oLozNZD2+qVSLi+ft5Qs= -k8s.io/apiserver v0.32.0/go.mod h1:HFh+dM1/BE/Hm4bS4nTXHVfN6Z6tFIZPi649n83b4Ag= -k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= -k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= -k8s.io/component-base v0.32.0 h1:d6cWHZkCiiep41ObYQS6IcgzOUQUNpywm39KVYaUqzU= -k8s.io/component-base v0.32.0/go.mod h1:JLG2W5TUxUu5uDyKiH2R/7NnxJo1HlPoRIIbVLkK5eM= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/apiserver v0.32.1 h1:oo0OozRos66WFq87Zc5tclUX2r0mymoVHRq8JmR7Aak= +k8s.io/apiserver v0.32.1/go.mod h1:UcB9tWjBY7aryeI5zAgzVJB/6k7E97bkr1RgqDz0jPw= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= +k8s.io/component-base v0.32.1 h1:/5IfJ0dHIKBWysGV0yKTFfacZ5yNV1sulPh3ilJjRZk= +k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= diff --git a/apps/dashboard/Makefile b/apps/dashboard/Makefile new file mode 100644 index 00000000000..d95e25e1abd --- /dev/null +++ b/apps/dashboard/Makefile @@ -0,0 +1,18 @@ +.PHONY: generate +generate: + @grafana-app-sdk generate \ + --source=./kinds/ \ + --gogenpath=../../pkg/apis \ + --tsgenpath=../../packages/grafana-schema/src/schema \ + --grouping=group \ + --defencoding=none \ + --genoperatorstate=false \ + --noschemasinmanifest + + # This is a workaround for SDK codegen not producing correct output for v0alpha1 + @rm ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts + @cp ./tshack/v0alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v0alpha1/types.spec.gen.ts + + # Same for v1alpha1 + @rm ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts + @cp ./tshack/v1alpha1_spec_gen.ts ../../packages/grafana-schema/src/schema/dashboard/v1alpha1/types.spec.gen.ts diff --git a/apps/dashboard/kinds/cue.mod/module.cue b/apps/dashboard/kinds/cue.mod/module.cue new file mode 100644 index 00000000000..a3b88f8aa81 --- /dev/null +++ b/apps/dashboard/kinds/cue.mod/module.cue @@ -0,0 +1,4 @@ +module: "github.com/grafana/grafana/sdkkinds/dashboard" +language: { + version: "v0.9.0" +} diff --git a/apps/dashboard/kinds/dashboard.cue b/apps/dashboard/kinds/dashboard.cue new file mode 100644 index 00000000000..da09322e0e8 --- /dev/null +++ b/apps/dashboard/kinds/dashboard.cue @@ -0,0 +1,68 @@ +package kinds + +import ( + "github.com/grafana/grafana/sdkkinds/dashboard/v0alpha1" + "github.com/grafana/grafana/sdkkinds/dashboard/v1alpha1" + "github.com/grafana/grafana/sdkkinds/dashboard/v2alpha1" +) + +// Status is the shared status of all dashboard versions. +DashboardStatus: { + // Optional conversion status. + conversion?: ConversionStatus +} + +// ConversionStatus is the status of the conversion of the dashboard. +ConversionStatus: { + // Whether from another version has failed. + // If true, means that the dashboard is not valid, + // and the caller should instead fetch the stored version. + failed: bool + + // The version which was stored when the dashboard was created / updated. + // Fetching this version should always succeed. + storedVersion: string + + // The error message from the conversion. + // Empty if the conversion has not failed. + error: string +} + +dashboard: { + kind: "Dashboard" + pluralName: "Dashboards" + current: "v0alpha1" + + codegen: { + ts: { + enabled: true + config: { + enumsAsUnionTypes: true + } + } + go: { + enabled: true + } + } + + versions: { + "v0alpha1": { + schema: { + spec: v0alpha1.DashboardSpec + status: DashboardStatus + } + } + "v1alpha1": { + schema: { + spec: v1alpha1.DashboardSpec + status: DashboardStatus + } + } + "v2alpha1": { + schema: { + spec: v2alpha1.DashboardSpec + status: DashboardStatus + } + } + } +} diff --git a/apps/dashboard/kinds/manifest.cue b/apps/dashboard/kinds/manifest.cue new file mode 100644 index 00000000000..1ec0fb4f21c --- /dev/null +++ b/apps/dashboard/kinds/manifest.cue @@ -0,0 +1,9 @@ +package kinds + +manifest: { + appName: "dashboard" + groupOverride: "dashboard.grafana.app" + kinds: [ + dashboard, + ] +} diff --git a/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..a59f79e97e9 --- /dev/null +++ b/apps/dashboard/kinds/v0alpha1/dashboard_spec.cue @@ -0,0 +1,6 @@ +package v0alpha1 + +// TODO: this outputs nothing. +// For now, we use unstructured for the spec, +// but it cannot be produced by the SDK codegen. +DashboardSpec: [string]: _ diff --git a/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..709fb40fd02 --- /dev/null +++ b/apps/dashboard/kinds/v1alpha1/dashboard_spec.cue @@ -0,0 +1,6 @@ +package v1alpha1 + +// TODO: this outputs nothing. +// For now, we use unstructured for the spec, +// but it cannot be produced by the SDK codegen. +DashboardSpec: [string]: _ diff --git a/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue new file mode 100644 index 00000000000..a1216596268 --- /dev/null +++ b/apps/dashboard/kinds/v2alpha1/dashboard_spec.cue @@ -0,0 +1,923 @@ +package v2alpha1 + +DashboardSpec: { + // Title of dashboard. + annotations: [...AnnotationQueryKind] + + // Configuration of dashboard cursor sync behavior. + // "Off" for no shared crosshair or tooltip (default). + // "Crosshair" for shared crosshair. + // "Tooltip" for shared crosshair AND shared tooltip. + cursorSync: DashboardCursorSync + + // Description of dashboard. + description?: string + + // Whether a dashboard is editable or not. + editable?: bool | *true + + elements: [ElementReference.name]: Element + + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind + + // Links with references to other dashboards or external websites. + links: [...DashboardLink] + + // When set to true, the dashboard will redraw panels at an interval matching the pixel width. + // This will keep data "moving left" regardless of the query refresh rate. This setting helps + // avoid dashboards presenting stale live data. + liveNow?: bool + + // When set to true, the dashboard will load all panels in the dashboard when it's loaded. + preload: bool + + // Plugins only. The version of the dashboard installed together with the plugin. + // This is used to determine if the dashboard should be updated when the plugin is updated. + revision?: uint16 + + // Tags associated with dashboard. + tags: [...string] + + timeSettings: TimeSettingsSpec + + // Title of dashboard. + title: string + + // Configured template variables. + variables: [...VariableKind] +} + +// Supported dashboard elements +Element: PanelKind | LibraryPanelKind // |* more element types in the future + +LibraryPanelKind: { + kind: "LibraryPanel" + spec: LibraryPanelKindSpec +} + +LibraryPanelKindSpec: { + // Panel ID for the library panel in the dashboard + id: number + // Title for the library panel in the dashboard + title: string + + libraryPanel: LibraryPanelRef +} + +// A library panel is a reusable panel that you can use in any dashboard. +// When you make a change to a library panel, that change propagates to all instances of where the panel is used. +// Library panels streamline reuse of panels across multiple dashboards. +LibraryPanelRef: { + // Library panel name + name: string + // Library panel uid + uid: string +} + +AnnotationPanelFilter: { + // Should the specified panels be included or excluded + exclude?: bool | *false + + // Panel IDs that should be included or excluded + ids: [...uint8] +} + +// "Off" for no shared crosshair or tooltip (default). +// "Crosshair" for shared crosshair. +// "Tooltip" for shared crosshair AND shared tooltip. +DashboardCursorSync: "Off" | "Crosshair" | "Tooltip" + +// Links with references to other dashboards or external resources +DashboardLink: { + // Title to display with the link + title: string + // Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) + // FIXME: The type is generated as `type: DashboardLinkType | dashboardLinkType.Link;` but it should be `type: DashboardLinkType` + type: DashboardLinkType + // Icon name to be displayed with the link + icon: string + // Tooltip to display when the user hovers their mouse over it + tooltip: string + // Link URL. Only required/valid if the type is link + url?: string + // List of tags to limit the linked dashboards. If empty, all dashboards will be displayed. Only valid if the type is dashboards + tags: [...string] + // If true, all dashboards links will be displayed in a dropdown. If false, all dashboards links will be displayed side by side. Only valid if the type is dashboards + asDropdown: bool | *false + // If true, the link will be opened in a new tab + targetBlank: bool | *false + // If true, includes current template variables values in the link as query params + includeVars: bool | *false + // If true, includes current time range in the link as query params + keepTime: bool | *false +} + +DataSourceRef: { + // The plugin type-id + type?: string + + // Specific datasource instance + uid?: string +} + +// A topic is attached to DataFrame metadata in query results. +// This specifies where the data should be used. +DataTopic: "series" | "annotations" | "alertStates" @cog(kind="enum",memberNames="Series|Annotations|AlertStates") + +// Transformations allow to manipulate data returned by a query before the system applies a visualization. +// Using transformations you can: rename fields, join time series data, perform mathematical operations across queries, +// use the output of one transformation as the input to another transformation, etc. +DataTransformerConfig: { + // Unique identifier of transformer + id: string + // Disabled transformations are skipped + disabled?: bool + // Optional frame matcher. When missing it will be applied to all results + filter?: MatcherConfig + // Where to pull DataFrames from as input to transformation + topic?: DataTopic + // Options to be passed to the transformer + // Valid options depend on the transformer id + options: _ +} + +DataLink: { + title: string + url: string + targetBlank?: bool +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +FieldConfigSource: { + // Defaults are the options applied to all fields. + defaults: FieldConfig + // Overrides are the options applied to specific fields overriding the defaults. + overrides: [...{ + matcher: MatcherConfig + properties: [...DynamicConfigValue] + }] +} + +// The data model used in Grafana, namely the data frame, is a columnar-oriented table structure that unifies both time series and table query results. +// Each column within this structure is called a field. A field can represent a single time series or table column. +// Field options allow you to change how the data is displayed in your visualizations. +FieldConfig: { + // The display value for this field. This supports template variables blank is auto + displayName?: string + + // This can be used by data sources that return and explicit naming structure for values and labels + // When this property is configured, this value is used rather than the default naming strategy. + displayNameFromDS?: string + + // Human readable field metadata + description?: string + + // An explicit path to the field in the datasource. When the frame meta includes a path, + // This will default to `${frame.meta.path}/${field.name} + // + // When defined, this value can be used as an identifier within the datasource scope, and + // may be used to update the results + path?: string + + // True if data source can write a value to the path. Auth/authz are supported separately + writeable?: bool + + // True if data source field supports ad-hoc filters + filterable?: bool + + // Unit a field should use. The unit you select is applied to all fields except time. + // You can use the units ID availables in Grafana or a custom unit. + // Available units in Grafana: https://github.com/grafana/grafana/blob/main/packages/grafana-data/src/valueFormats/categories.ts + // As custom unit, you can use the following formats: + // `suffix:` for custom unit that should go after value. + // `prefix:` for custom unit that should go before value. + // `time:` For custom date time formats type for example `time:YYYY-MM-DD`. + // `si:` for custom SI units. For example: `si: mF`. This one is a bit more advanced as you can specify both a unit and the source data scale. So if your source data is represented as milli (thousands of) something prefix the unit with that SI scale character. + // `count:` for a custom count unit. + // `currency:` for custom a currency unit. + unit?: string + + // Specify the number of decimals Grafana includes in the rendered value. + // If you leave this field blank, Grafana automatically truncates the number of decimals based on the value. + // For example 1.1234 will display as 1.12 and 100.456 will display as 100. + // To display all decimals, set the unit to `String`. + decimals?: number + + // The minimum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + min?: number + // The maximum value used in percentage threshold calculations. Leave blank for auto calculation based on all series and fields. + max?: number + + // Convert input values into a display string + mappings?: [...ValueMapping] + + // Map numeric values to states + thresholds?: ThresholdsConfig + + // Panel color configuration + color?: FieldColor + + // The behavior when clicking on a result + links?: [...] + + // Alternative to empty string + noValue?: string + + // custom is specified by the FieldConfig field + // in panel plugin schemas. + custom?: {...} +} + +DynamicConfigValue: { + id: string | *"" + value?: _ +} + +// Matcher is a predicate configuration. Based on the config a set of field(s) or values is filtered in order to apply override / transformation. +// It comes with in id ( to resolve implementation from registry) and a configuration that’s specific to a particular matcher type. +MatcherConfig: { + // The matcher id. This is used to find the matcher implementation from registry. + id: string | *"" + // The matcher options. This is specific to the matcher implementation. + options?: _ +} + +Threshold: { + value: number + color: string +} + +ThresholdsMode: "absolute" | "percentage" + +ThresholdsConfig: { + mode: ThresholdsMode + steps: [...Threshold] +} + +ValueMapping: ValueMap | RangeMap | RegexMap | SpecialValueMap + +// Supported value mapping types +// `value`: Maps text values to a color or different display text and color. 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. See SpecialValueMatch to see the list of special values. For example, you can configure a special value mapping so that null values appear as N/A. +MappingType: "value" | "range" | "regex" | "special" @cog(kind="enum",memberNames="ValueToText|RangeToText|RegexToText|SpecialValue") + +// Maps text values to a color or different display text and color. +// For example, you can configure a value mapping so that all instances of the value 10 appear as Perfection! rather than the number. +ValueMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "value" + type: "value" + // Map with : ValueMappingResult. For example: { "10": { text: "Perfection!", color: "green" } } + options: [string]: ValueMappingResult +} + +// 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. +RangeMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "range" + type: "range" + // Range to match against and the result to apply when the value is within the range + options: { + // Min value of the range. It can be null which means -Infinity + from: float64 | null + // Max value of the range. It can be null which means +Infinity + to: float64 | null + // Config to apply when the value is within the range + result: ValueMappingResult + } +} + +// 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. +RegexMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "regex" + type: "regex" + // Regular expression to match against and the result to apply when the value matches the regex + options: { + // Regular expression to match against + pattern: string + // Config to apply when the value matches the regex + result: ValueMappingResult + } +} + +// Maps special values like Null, NaN (not a number), and boolean values like true and false to a display text and color. +// See SpecialValueMatch to see the list of special values. +// For example, you can configure a special value mapping so that null values appear as N/A. +SpecialValueMap: { + // TODO (@radiohead): Something broke in cog / app SDK codegen + // And this is no longer producing valid TS / Go output + // type: MappingType & "special" + type: "special" + options: { + // Special value to match against + match: SpecialValueMatch + // Config to apply when the value matches the special value + result: ValueMappingResult + } +} + +// Special value types supported by the `SpecialValueMap` +SpecialValueMatch: "true" | "false" | "null" | "nan" | "null+nan" | "empty" @cog(kind="enum",memberNames="True|False|Null|NaN|NullAndNaN|Empty") + +// Result used as replacement with text and color when the value matches +ValueMappingResult: { + // Text to display when the value matches + text?: string + // Text to use when the value matches + color?: string + // Icon to display when the value matches. Only specific visualizations. + icon?: string + // Position in the mapping array. Only used internally. + index?: int32 +} + +// Color mode for a field. You can specify a single color, or select a continuous (gradient) color schemes, based on a value. +// Continuous color interpolates a color using the percentage of a value relative to min and max. +// Accepted values are: +// `thresholds`: From thresholds. Informs Grafana to take the color from the matching threshold +// `palette-classic`: Classic palette. Grafana will assign color by looking up a color in a palette by series index. Useful for Graphs and pie charts and other categorical data visualizations +// `palette-classic-by-name`: Classic palette (by name). Grafana will assign color by looking up a color in a palette by series name. Useful for Graphs and pie charts and other categorical data visualizations +// `continuous-GrYlRd`: ontinuous Green-Yellow-Red palette mode +// `continuous-RdYlGr`: Continuous Red-Yellow-Green palette mode +// `continuous-BlYlRd`: Continuous Blue-Yellow-Red palette mode +// `continuous-YlRd`: Continuous Yellow-Red palette mode +// `continuous-BlPu`: Continuous Blue-Purple palette mode +// `continuous-YlBl`: Continuous Yellow-Blue palette mode +// `continuous-blues`: Continuous Blue palette mode +// `continuous-reds`: Continuous Red palette mode +// `continuous-greens`: Continuous Green palette mode +// `continuous-purples`: Continuous Purple palette mode +// `shades`: Shades of a single color. Specify a single color, useful in an override rule. +// `fixed`: Fixed color mode. Specify a single color, useful in an override rule. +FieldColorModeId: "thresholds" | "palette-classic" | "palette-classic-by-name" | "continuous-GrYlRd" | "continuous-RdYlGr" | "continuous-BlYlRd" | "continuous-YlRd" | "continuous-BlPu" | "continuous-YlBl" | "continuous-blues" | "continuous-reds" | "continuous-greens" | "continuous-purples" | "fixed" | "shades" + +// Defines how to assign a series color from "by value" color schemes. For example for an aggregated data points like a timeseries, the color can be assigned by the min, max or last value. +FieldColorSeriesByMode: "min" | "max" | "last" + +// Map a field to a color. +FieldColor: { + // The main color scheme mode. + mode: FieldColorModeId + // The fixed color value for fixed or shades color modes. + fixedColor?: string + // Some visualizations need to know how to assign a series color from by value color schemes. + seriesBy?: FieldColorSeriesByMode +} + +// Dashboard Link type. Accepted values are dashboards (to refer to another dashboard) and link (to refer to an external resource) +DashboardLinkType: "link" | "dashboards" + +// --- Common types --- +Kind: { + kind: string + spec: _ + metadata?: _ +} + +// --- Kinds --- +VizConfigSpec: { + pluginVersion: string + options: [string]: _ + fieldConfig: FieldConfigSource +} + +VizConfigKind: { + // The kind of a VizConfigKind is the plugin ID + kind: string + spec: VizConfigSpec +} + +AnnotationQuerySpec: { + datasource?: DataSourceRef + query?: DataQueryKind + enable: bool + hide: bool + iconColor: string + name: string + builtIn?: bool | *false + filter?: AnnotationPanelFilter +} + +AnnotationQueryKind: { + kind: "AnnotationQuery" + spec: AnnotationQuerySpec +} + +QueryOptionsSpec: { + timeFrom?: string + maxDataPoints?: int + timeShift?: string + queryCachingTTL?: int + interval?: string + cacheTimeout?: string + hideTimeOverride?: bool +} + +DataQueryKind: { + // The kind of a DataQueryKind is the datasource type + kind: string + spec: [string]: _ +} + +PanelQuerySpec: { + query: DataQueryKind + datasource?: DataSourceRef + + refId: string + hidden: bool +} + +PanelQueryKind: { + kind: "PanelQuery" + spec: PanelQuerySpec +} + +TransformationKind: { + // The kind of a TransformationKind is the transformation ID + kind: string + spec: DataTransformerConfig +} + +QueryGroupSpec: { + queries: [...PanelQueryKind] + transformations: [...TransformationKind] + queryOptions: QueryOptionsSpec +} + +QueryGroupKind: { + kind: "QueryGroup" + spec: QueryGroupSpec +} + +TimeRangeOption: { + display: string | *"Last 6 hours" + from: string | *"now-6h" + to: string | *"now" +} + +// Time configuration +// It defines the default time config for the time picker, the refresh picker for the specific dashboard. +TimeSettingsSpec: { + // Timezone of dashboard. Accepted values are IANA TZDB zone ID or "browser" or "utc". + timezone?: string | *"browser" + // Start time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + from: string | *"now-6h" + // End time range for dashboard. + // Accepted values are relative time strings like "now-6h" or absolute time strings like "2020-07-10T08:00:00.000Z". + to: string | *"now" + // Refresh rate of dashboard. Represented via interval string, e.g. "5s", "1m", "1h", "1d". + autoRefresh: string // v1: refresh + // Interval options available in the refresh picker dropdown. + autoRefreshIntervals: [...string] | *["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] // v1: timepicker.refresh_intervals + // Selectable options available in the time picker dropdown. Has no effect on provisioned dashboard. + quickRanges?: [...TimeRangeOption] // v1: timepicker.quick_ranges , not exposed in the UI + // Whether timepicker is visible or not. + hideTimepicker: bool // v1: timepicker.hidden + // Day when the week starts. Expressed by the name of the day in lowercase, e.g. "monday". + weekStart?: "saturday" | "monday" | "sunday" + // The month that the fiscal year starts on. 0 = January, 11 = December + fiscalYearStartMonth: int + // Override the now time by entering a time delay. Use this option to accommodate known delays in data aggregation to avoid null values. + nowDelay?: string // v1: timepicker.nowDelay +} + +RepeatMode: "variable" // other repeat modes will be added in the future: label, frame + +RepeatOptions: { + mode: RepeatMode + value: string + direction?: "h" | "v" + maxPerRow?: int +} + +RowRepeatOptions: { + mode: RepeatMode + value: string +} + +ResponsiveGridRepeatOptions: { + mode: RepeatMode + value: string +} + +GridLayoutItemSpec: { + x: int + y: int + width: int + height: int + element: ElementReference // reference to a PanelKind from dashboard.spec.elements Expressed as JSON Schema reference + repeat?: RepeatOptions +} + +GridLayoutItemKind: { + kind: "GridLayoutItem" + spec: GridLayoutItemSpec +} + +GridLayoutRowKind: { + kind: "GridLayoutRow" + spec: GridLayoutRowSpec +} + +GridLayoutRowSpec: { + y: int + collapsed: bool + title: string + elements: [...GridLayoutItemKind] // Grid items in the row will have their Y value be relative to the rows Y value. This means a panel positioned at Y: 0 in a row with Y: 10 will be positioned at Y: 11 (row header has a heigh of 1) in the dashboard. + repeat?: RowRepeatOptions +} + +GridLayoutSpec: { + items: [...GridLayoutItemKind | GridLayoutRowKind] +} + +GridLayoutKind: { + kind: "GridLayout" + spec: GridLayoutSpec +} + +RowsLayoutKind: { + kind: "RowsLayout" + spec: RowsLayoutSpec +} + +RowsLayoutSpec: { + rows: [...RowsLayoutRowKind] +} + +RowsLayoutRowKind: { + kind: "RowsLayoutRow" + spec: RowsLayoutRowSpec +} + +RowsLayoutRowSpec: { + title?: string + collapsed: bool + repeat?: RowRepeatOptions + layout: GridLayoutKind | ResponsiveGridLayoutKind | TabsLayoutKind +} + +ResponsiveGridLayoutKind: { + kind: "ResponsiveGridLayout" + spec: ResponsiveGridLayoutSpec +} + +ResponsiveGridLayoutSpec: { + row: string + col: string + items: [...ResponsiveGridLayoutItemKind] +} + +ResponsiveGridLayoutItemKind: { + kind: "ResponsiveGridLayoutItem" + spec: ResponsiveGridLayoutItemSpec +} + +ResponsiveGridLayoutItemSpec: { + element: ElementReference + repeat?: ResponsiveGridRepeatOptions +} + +TabsLayoutKind: { + kind: "TabsLayout" + spec: TabsLayoutSpec +} + +TabsLayoutSpec: { + tabs: [...TabsLayoutTabKind] +} + +TabsLayoutTabKind: { + kind: "TabsLayoutTab" + spec: TabsLayoutTabSpec +} + +TabsLayoutTabSpec: { + title?: string + layout: GridLayoutKind | RowsLayoutKind | ResponsiveGridLayoutKind +} + +PanelSpec: { + id: number + title: string + description: string + links: [...DataLink] + data: QueryGroupKind + vizConfig: VizConfigKind + transparent?: bool +} + +PanelKind: { + kind: "Panel" + spec: PanelSpec +} + +ElementReference: { + kind: "ElementReference" + name: string +} + +// Start FIXME: variables - in CUE PR - this are things that should be added into the cue schema +// TODO: properties such as `hide`, `skipUrlSync`, `multi` are type boolean, and in the old schema they are conditional, +// should we make them conditional in the new schema as well? or should we make them required but default to false? + +// Variable types +VariableValue: VariableValueSingle | [...VariableValueSingle] + +VariableValueSingle: string | bool | number | CustomVariableValue + +// Custom formatter variable +CustomFormatterVariable: { + name: string + type: VariableType + multi: bool + includeAll: bool +} + +// Custom variable value +CustomVariableValue: { + // The format name or function used in the expression + formatter: *null | string | VariableCustomFormatterFn +} + +// Custom formatter function +VariableCustomFormatterFn: { + value: _ + legacyVariableModel: { + name: string + type: VariableType + multi: bool + includeAll: bool + } + legacyDefaultFormatter?: VariableCustomFormatterFn +} + +// Dashboard variable type +// `query`: Query-generated list of values such as metric names, server names, sensor IDs, data centers, and so on. +// `adhoc`: Key/value filters that are automatically added to all metric queries for a data source (Prometheus, Loki, InfluxDB, and Elasticsearch only). +// `constant`: Define a hidden constant. +// `datasource`: Quickly change the data source for an entire dashboard. +// `interval`: Interval variables represent time spans. +// `textbox`: Display a free text input field with an optional default value. +// `custom`: Define the variable options manually using a comma-separated list. +// `system`: Variables defined by Grafana. See: https://grafana.com/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables +VariableType: "query" | "adhoc" | "groupby" | "constant" | "datasource" | "interval" | "textbox" | "custom" | + "system" | "snapshot" + +VariableKind: QueryVariableKind | TextVariableKind | ConstantVariableKind | DatasourceVariableKind | IntervalVariableKind | CustomVariableKind | GroupByVariableKind | AdhocVariableKind + +// Sort variable options +// Accepted values are: +// `disabled`: No sorting +// `alphabeticalAsc`: Alphabetical ASC +// `alphabeticalDesc`: Alphabetical DESC +// `numericalAsc`: Numerical ASC +// `numericalDesc`: Numerical DESC +// `alphabeticalCaseInsensitiveAsc`: Alphabetical Case Insensitive ASC +// `alphabeticalCaseInsensitiveDesc`: Alphabetical Case Insensitive DESC +// `naturalAsc`: Natural ASC +// `naturalDesc`: Natural DESC +// VariableSort enum with default value +VariableSort: "disabled" | "alphabeticalAsc" | "alphabeticalDesc" | "numericalAsc" | "numericalDesc" | "alphabeticalCaseInsensitiveAsc" | "alphabeticalCaseInsensitiveDesc" | "naturalAsc" | "naturalDesc" + +// Options to config when to refresh a variable +// `never`: Never refresh the variable +// `onDashboardLoad`: Queries the data source every time the dashboard loads. +// `onTimeRangeChanged`: Queries the data source when the dashboard time range changes. +VariableRefresh: *"never" | "onDashboardLoad" | "onTimeRangeChanged" + +// Determine if the variable shows on dashboard +// Accepted values are `dontHide` (show label and value), `hideLabel` (show value only), `hideVariable` (show nothing). +VariableHide: *"dontHide" | "hideLabel" | "hideVariable" + +// FIXME: should we introduce this? --- Variable value option +VariableValueOption: { + label: string + value: VariableValueSingle + group?: string +} + +// Variable option specification +VariableOption: { + // Whether the option is selected or not + selected?: bool + // Text to be displayed for the option + text: string | [...string] + // Value of the option + value: string | [...string] +} + +// Query variable specification +QueryVariableSpec: { + name: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + label?: string + hide: VariableHide + refresh: VariableRefresh + skipUrlSync: bool | *false + description?: string + datasource?: DataSourceRef + query: DataQueryKind + regex: string | *"" + sort: VariableSort + definition?: string + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + placeholder?: string +} + +// Query variable kind +QueryVariableKind: { + kind: "QueryVariable" + spec: QueryVariableSpec +} + +// Text variable specification +TextVariableSpec: { + name: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + query: string | *"" + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Text variable kind +TextVariableKind: { + kind: "TextVariable" + spec: TextVariableSpec +} + +// Constant variable specification +ConstantVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Constant variable kind +ConstantVariableKind: { + kind: "ConstantVariable" + spec: ConstantVariableSpec +} + +// Datasource variable specification +DatasourceVariableSpec: { + name: string | *"" + pluginId: string | *"" + refresh: VariableRefresh + regex: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Datasource variable kind +DatasourceVariableKind: { + kind: "DatasourceVariable" + spec: DatasourceVariableSpec +} + +// Interval variable specification +IntervalVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + auto: bool | *false + auto_min: string | *"" + auto_count: int | *0 + refresh: VariableRefresh + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Interval variable kind +IntervalVariableKind: { + kind: "IntervalVariable" + spec: IntervalVariableSpec +} + +// Custom variable specification +CustomVariableSpec: { + name: string | *"" + query: string | *"" + current: VariableOption + options: [...VariableOption] | *[] + multi: bool | *false + includeAll: bool | *false + allValue?: string + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Custom variable kind +CustomVariableKind: { + kind: "CustomVariable" + spec: CustomVariableSpec +} + +// GroupBy variable specification +GroupByVariableSpec: { + name: string | *"" + datasource?: DataSourceRef + current: VariableOption | *{ + text: "" + value: "" + } + options: [...VariableOption] | *[] + multi: bool | *false + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Group variable kind +GroupByVariableKind: { + kind: "GroupByVariable" + spec: GroupByVariableSpec +} + +// Adhoc variable specification +AdhocVariableSpec: { + name: string | *"" + datasource?: DataSourceRef + baseFilters: [...AdHocFilterWithLabels] | *[] + filters: [...AdHocFilterWithLabels] | *[] + defaultKeys: [...MetricFindValue] | *[] + label?: string + hide: VariableHide + skipUrlSync: bool | *false + description?: string +} + +// Define the MetricFindValue type +MetricFindValue: { + text: string + value?: string | number + group?: string + expandable?: bool +} + +// Define the AdHocFilterWithLabels type +AdHocFilterWithLabels: { + key: string + operator: string + value: string + values?: [...string] + keyLabel?: string + valueLabels?: [...string] + forceEdit?: bool + // @deprecated + condition?: string +} + +// Adhoc variable kind +AdhocVariableKind: { + kind: "AdhocVariable" + spec: AdhocVariableSpec +} diff --git a/apps/dashboard/tshack/v0alpha1_spec_gen.ts b/apps/dashboard/tshack/v0alpha1_spec_gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/apps/dashboard/tshack/v0alpha1_spec_gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/apps/dashboard/tshack/v1alpha1_spec_gen.ts b/apps/dashboard/tshack/v1alpha1_spec_gen.ts new file mode 100644 index 00000000000..3de7e52c72e --- /dev/null +++ b/apps/dashboard/tshack/v1alpha1_spec_gen.ts @@ -0,0 +1,7 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface Spec { + [key: string]: any; +} + +export const defaultSpec = (): Spec => ({}); diff --git a/apps/investigation/Makefile b/apps/investigation/Makefile deleted file mode 100644 index b4ea1f97c89..00000000000 --- a/apps/investigation/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -.PHONY: generate -generate: - @grafana-app-sdk generate -g ./pkg/apis --kindgrouping=group --postprocess --crdencoding none diff --git a/apps/investigation/kinds/cue.mod/module.cue b/apps/investigation/kinds/cue.mod/module.cue deleted file mode 100644 index 80ce68f4833..00000000000 --- a/apps/investigation/kinds/cue.mod/module.cue +++ /dev/null @@ -1,2 +0,0 @@ -module: "github.com/grafana/grafana/apps/investigation/kinds" -language: version: "v0.8.2" diff --git a/apps/investigation/kinds/investigation.cue b/apps/investigation/kinds/investigation.cue deleted file mode 100644 index 64d4b9b3105..00000000000 --- a/apps/investigation/kinds/investigation.cue +++ /dev/null @@ -1,96 +0,0 @@ -package kinds - -// This is our Investigation definition, which contains metadata about the kind, and the kind's schema -investigation: { - group: "investigation" - kind: "Investigation" - pluralName: "Investigations" - scope: "Namespaced" - - apiResource: { - groupOverride: "investigation.grafana.app" - } - - codegen: { - frontend: false - backend: true - } - - current: "v1alpha1" - versions: { - "v1alpha1": { - version: "v1alpha1" - schema: { - // spec is the schema of our resource. The spec should include all the user-ediable information for the kind. - spec: #InvestigationSpec - } - } - } -} - -#InvestigationSpec: { - title: string - status: "open" | "closed" - items: [...#InvestigationItem] -} - -// InvestigationItem is an item in an investigation. -#InvestigationItem: { - id: string - title: string - // type is the type of the item "timeseries", "heatmap", "log-table" (not an enum to allow for future extensions). - type: string - // url is the URL to the item. - url: string - // origin is where the item was created from. - origin: string // "explore-metrics", "explore-logs", "explore-traces" (not an enum to allow for future extensions) - // iconPath (optional) is the path to the icon for the item. - iconPath?: string - // timeRange (optional) is the time range of the item. - timeRange: #AbsoluteTimeRange - // note (optional) is a comment on the item. - note?: [...#Comment] - // queryType is the type of the query used to generate this item. - queryType: "logs" | "metrics" - // dataQuery contains the query used to generate this item. - dataQuery: #DataQueryLogs | #DataQueryMetrics -} - -// DataQueryLogs is a data query for logs. -#DataQueryLogs: { - // refId is the reference ID of the query. - refId: string - // datasource is the datasource of the query. - datasource: #DatasourceRef - // expr is the expression of the query. - expr: string - // maxLines (optional) is used to limit the number of log rows returned. - maxLines?: int64 -} - -// DataQueryMetrics is a data query for metrics. -#DataQueryMetrics: { - refId: string - datasource: #DatasourceRef - expr: string -} - -// Comment is a comment on an investigation item. -#Comment: { - authorUserID: string - bodyMarkdown: string -} - -// DatasourceRef is a reference to a datasource. -#DatasourceRef: { - uid: string - type: string - apiVersion: string - name: string -} - -// AbsoluteTimeRange is a time range specified by absolute timestamps. -#AbsoluteTimeRange: { - from: number - to: number -} diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_metadata_gen.go b/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_metadata_gen.go deleted file mode 100644 index 8a8e44d35ac..00000000000 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_metadata_gen.go +++ /dev/null @@ -1,32 +0,0 @@ -package v1alpha1 - -import ( - "time" -) - -// InvestigationMetadata defines model for InvestigationMetadata. -type InvestigationMetadata struct { - CreatedBy string `json:"createdBy"` - CreationTimestamp time.Time `json:"creationTimestamp"` - DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` - Finalizers []string `json:"finalizers"` - Generation int64 `json:"generation"` - Labels map[string]string `json:"labels"` - ResourceVersion string `json:"resourceVersion"` - Uid string `json:"uid"` - UpdateTimestamp time.Time `json:"updateTimestamp"` - UpdatedBy string `json:"updatedBy"` -} - -// _kubeObjectMetadata is metadata found in a kubernetes object's metadata field. -// It is not exhaustive and only includes fields which may be relevant to a kind's implementation, -// As it is also intended to be generic enough to function with any API Server. -type InvestigationKubeObjectMetadata struct { - CreationTimestamp time.Time `json:"creationTimestamp"` - DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` - Finalizers []string `json:"finalizers"` - Generation int64 `json:"generation"` - Labels map[string]string `json:"labels"` - ResourceVersion string `json:"resourceVersion"` - Uid string `json:"uid"` -} diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_spec_gen.go b/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_spec_gen.go deleted file mode 100644 index 1ed1173238b..00000000000 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_spec_gen.go +++ /dev/null @@ -1,107 +0,0 @@ -package v1alpha1 - -// Defines values for InvestigationInvestigationItemQueryType. -const ( - InvestigationInvestigationItemQueryTypeLogs InvestigationInvestigationItemQueryType = "logs" - InvestigationInvestigationItemQueryTypeMetrics InvestigationInvestigationItemQueryType = "metrics" -) - -// Defines values for InvestigationSpecStatus. -const ( - InvestigationSpecStatusClosed InvestigationSpecStatus = "closed" - InvestigationSpecStatusOpen InvestigationSpecStatus = "open" -) - -// AbsoluteTimeRange is a time range specified by absolute timestamps. -// +k8s:openapi-gen=true -type InvestigationAbsoluteTimeRange struct { - From float32 `json:"from"` - To float32 `json:"to"` -} - -// Comment is a comment on an investigation item. -// +k8s:openapi-gen=true -type InvestigationComment struct { - AuthorUserID string `json:"authorUserID"` - BodyMarkdown string `json:"bodyMarkdown"` -} - -// DataQueryLogs is a data query for logs. -// +k8s:openapi-gen=true -type InvestigationDataQueryLogs struct { - // DatasourceRef is a reference to a datasource. - Datasource InvestigationDatasourceRef `json:"datasource"` - - // expr is the expression of the query. - Expr string `json:"expr"` - - // maxLines (optional) is used to limit the number of log rows returned. - MaxLines *int64 `json:"maxLines,omitempty"` - - // refId is the reference ID of the query. - RefId string `json:"refId"` -} - -// DataQueryMetrics is a data query for metrics. -// +k8s:openapi-gen=true -type InvestigationDataQueryMetrics struct { - // DatasourceRef is a reference to a datasource. - Datasource InvestigationDatasourceRef `json:"datasource"` - Expr string `json:"expr"` - RefId string `json:"refId"` -} - -// DatasourceRef is a reference to a datasource. -// +k8s:openapi-gen=true -type InvestigationDatasourceRef struct { - ApiVersion string `json:"apiVersion"` - Name string `json:"name"` - Type string `json:"type"` - Uid string `json:"uid"` -} - -// InvestigationItem is an item in an investigation. -// +k8s:openapi-gen=true -type InvestigationInvestigationItem struct { - // dataQuery contains the query used to generate this item. - DataQuery interface{} `json:"dataQuery"` - - // iconPath (optional) is the path to the icon for the item. - IconPath *string `json:"iconPath,omitempty"` - Id string `json:"id"` - - // note (optional) is a comment on the item. - Note []InvestigationComment `json:"note,omitempty"` - - // origin is where the item was created from. - Origin string `json:"origin"` - - // queryType is the type of the query used to generate this item. - QueryType InvestigationInvestigationItemQueryType `json:"queryType"` - - // AbsoluteTimeRange is a time range specified by absolute timestamps. - TimeRange InvestigationAbsoluteTimeRange `json:"timeRange"` - Title string `json:"title"` - - // type is the type of the item "timeseries", "heatmap", "log-table" (not an enum to allow for future extensions). - Type string `json:"type"` - - // url is the URL to the item. - Url string `json:"url"` -} - -// InvestigationInvestigationItemQueryType queryType is the type of the query used to generate this item. -// +k8s:openapi-gen=true -type InvestigationInvestigationItemQueryType string - -// InvestigationSpec defines model for InvestigationSpec. -// +k8s:openapi-gen=true -type InvestigationSpec struct { - Items []InvestigationInvestigationItem `json:"items"` - Status InvestigationSpecStatus `json:"status"` - Title string `json:"title"` -} - -// InvestigationSpecStatus defines model for InvestigationSpec.Status. -// +k8s:openapi-gen=true -type InvestigationSpecStatus string diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_status_gen.go b/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_status_gen.go deleted file mode 100644 index 3f0870f9c04..00000000000 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_status_gen.go +++ /dev/null @@ -1,70 +0,0 @@ -package v1alpha1 - -// Defines values for InvestigationOperatorStateState. -const ( - InvestigationOperatorStateStateFailed InvestigationOperatorStateState = "failed" - InvestigationOperatorStateStateInProgress InvestigationOperatorStateState = "in_progress" - InvestigationOperatorStateStateSuccess InvestigationOperatorStateState = "success" -) - -// Defines values for InvestigationstatusOperatorStateState. -const ( - InvestigationstatusOperatorStateStateFailed InvestigationstatusOperatorStateState = "failed" - InvestigationstatusOperatorStateStateInProgress InvestigationstatusOperatorStateState = "in_progress" - InvestigationstatusOperatorStateStateSuccess InvestigationstatusOperatorStateState = "success" -) - -// InvestigationOperatorState defines model for InvestigationOperatorState. -// +k8s:openapi-gen=true -type InvestigationOperatorState struct { - // descriptiveState is an optional more descriptive state field which has no requirements on format - DescriptiveState *string `json:"descriptiveState,omitempty"` - - // details contains any extra information that is operator-specific - Details map[string]interface{} `json:"details,omitempty"` - - // lastEvaluation is the ResourceVersion last evaluated - LastEvaluation string `json:"lastEvaluation"` - - // state describes the state of the lastEvaluation. - // It is limited to three possible states for machine evaluation. - State InvestigationOperatorStateState `json:"state"` -} - -// InvestigationOperatorStateState state describes the state of the lastEvaluation. -// It is limited to three possible states for machine evaluation. -// +k8s:openapi-gen=true -type InvestigationOperatorStateState string - -// InvestigationStatus defines model for InvestigationStatus. -// +k8s:openapi-gen=true -type InvestigationStatus struct { - // additionalFields is reserved for future use - AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` - - // operatorStates is a map of operator ID to operator state evaluations. - // Any operator which consumes this kind SHOULD add its state evaluation information to this field. - OperatorStates map[string]InvestigationstatusOperatorState `json:"operatorStates,omitempty"` -} - -// InvestigationstatusOperatorState defines model for Investigationstatus.#OperatorState. -// +k8s:openapi-gen=true -type InvestigationstatusOperatorState struct { - // descriptiveState is an optional more descriptive state field which has no requirements on format - DescriptiveState *string `json:"descriptiveState,omitempty"` - - // details contains any extra information that is operator-specific - Details map[string]interface{} `json:"details,omitempty"` - - // lastEvaluation is the ResourceVersion last evaluated - LastEvaluation string `json:"lastEvaluation"` - - // state describes the state of the lastEvaluation. - // It is limited to three possible states for machine evaluation. - State InvestigationstatusOperatorStateState `json:"state"` -} - -// InvestigationstatusOperatorStateState state describes the state of the lastEvaluation. -// It is limited to three possible states for machine evaluation. -// +k8s:openapi-gen=true -type InvestigationstatusOperatorStateState string diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/zz_openapi_gen.go b/apps/investigation/pkg/apis/investigation/v1alpha1/zz_openapi_gen.go deleted file mode 100644 index 356c42c01fc..00000000000 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/zz_openapi_gen.go +++ /dev/null @@ -1,593 +0,0 @@ -//go:build !ignore_autogenerated -// +build !ignore_autogenerated - -// Code generated by grafana-app-sdk. DO NOT EDIT. - -package v1alpha1 - -import ( - common "k8s.io/kube-openapi/pkg/common" - spec "k8s.io/kube-openapi/pkg/validation/spec" -) - -func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { - return map[string]common.OpenAPIDefinition{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation": schema_pkg_apis_investigation_v1alpha1_Investigation(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange": schema_pkg_apis_investigation_v1alpha1_InvestigationAbsoluteTimeRange(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment": schema_pkg_apis_investigation_v1alpha1_InvestigationComment(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDataQueryLogs": schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryLogs(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDataQueryMetrics": schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryMetrics(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef": schema_pkg_apis_investigation_v1alpha1_InvestigationDatasourceRef(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem": schema_pkg_apis_investigation_v1alpha1_InvestigationInvestigationItem(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationList": schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationOperatorState": schema_pkg_apis_investigation_v1alpha1_InvestigationOperatorState(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec": schema_pkg_apis_investigation_v1alpha1_InvestigationSpec(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus": schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref), - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState": schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref), - } -} - -func schema_pkg_apis_investigation_v1alpha1_Investigation(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus"), - }, - }, - }, - Required: []string{"metadata", "spec", "status"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationSpec", "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationAbsoluteTimeRange(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "AbsoluteTimeRange is a time range specified by absolute timestamps.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "from": { - SchemaProps: spec.SchemaProps{ - Default: 0, - Type: []string{"number"}, - Format: "float", - }, - }, - "to": { - SchemaProps: spec.SchemaProps{ - Default: 0, - Type: []string{"number"}, - Format: "float", - }, - }, - }, - Required: []string{"from", "to"}, - }, - }, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationComment(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "Comment is a comment on an investigation item.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "authorUserID": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "bodyMarkdown": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"authorUserID", "bodyMarkdown"}, - }, - }, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryLogs(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DataQueryLogs is a data query for logs.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "datasource": { - SchemaProps: spec.SchemaProps{ - Description: "DatasourceRef is a reference to a datasource.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"), - }, - }, - "expr": { - SchemaProps: spec.SchemaProps{ - Description: "expr is the expression of the query.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "maxLines": { - SchemaProps: spec.SchemaProps{ - Description: "maxLines (optional) is used to limit the number of log rows returned.", - Type: []string{"integer"}, - Format: "int64", - }, - }, - "refId": { - SchemaProps: spec.SchemaProps{ - Description: "refId is the reference ID of the query.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"datasource", "expr", "refId"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationDataQueryMetrics(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DataQueryMetrics is a data query for metrics.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "datasource": { - SchemaProps: spec.SchemaProps{ - Description: "DatasourceRef is a reference to a datasource.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"), - }, - }, - "expr": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "refId": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"datasource", "expr", "refId"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationDatasourceRef"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationDatasourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatasourceRef is a reference to a datasource.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "name": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "type": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "uid": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"apiVersion", "name", "type", "uid"}, - }, - }, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationInvestigationItem(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InvestigationItem is an item in an investigation.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "dataQuery": { - SchemaProps: spec.SchemaProps{ - Description: "dataQuery contains the query used to generate this item.", - Type: []string{"object"}, - Format: "", - }, - }, - "iconPath": { - SchemaProps: spec.SchemaProps{ - Description: "iconPath (optional) is the path to the icon for the item.", - Type: []string{"string"}, - Format: "", - }, - }, - "id": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "note": { - SchemaProps: spec.SchemaProps{ - Description: "note (optional) is a comment on the item.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment"), - }, - }, - }, - }, - }, - "origin": { - SchemaProps: spec.SchemaProps{ - Description: "origin is where the item was created from.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "queryType": { - SchemaProps: spec.SchemaProps{ - Description: "queryType is the type of the query used to generate this item.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "timeRange": { - SchemaProps: spec.SchemaProps{ - Description: "AbsoluteTimeRange is a time range specified by absolute timestamps.", - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange"), - }, - }, - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "type": { - SchemaProps: spec.SchemaProps{ - Description: "type is the type of the item \"timeseries\", \"heatmap\", \"log-table\" (not an enum to allow for future extensions).", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "url": { - SchemaProps: spec.SchemaProps{ - Description: "url is the URL to the item.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"dataQuery", "id", "origin", "queryType", "timeRange", "title", "type", "url"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationAbsoluteTimeRange", "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationComment"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationList(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), - }, - }, - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation"), - }, - }, - }, - }, - }, - }, - Required: []string{"metadata", "items"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.Investigation", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InvestigationOperatorState defines model for InvestigationOperatorState.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "descriptiveState": { - SchemaProps: spec.SchemaProps{ - Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", - Type: []string{"string"}, - Format: "", - }, - }, - "details": { - SchemaProps: spec.SchemaProps{ - Description: "details contains any extra information that is operator-specific", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - "lastEvaluation": { - SchemaProps: spec.SchemaProps{ - Description: "lastEvaluation is the ResourceVersion last evaluated", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "state": { - SchemaProps: spec.SchemaProps{ - Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"lastEvaluation", "state"}, - }, - }, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InvestigationSpec defines model for InvestigationSpec.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "items": { - SchemaProps: spec.SchemaProps{ - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem"), - }, - }, - }, - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "title": { - SchemaProps: spec.SchemaProps{ - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"items", "status", "title"}, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationInvestigationItem"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InvestigationStatus defines model for InvestigationStatus.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "additionalFields": { - SchemaProps: spec.SchemaProps{ - Description: "additionalFields is reserved for future use", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - "operatorStates": { - SchemaProps: spec.SchemaProps{ - Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1.InvestigationstatusOperatorState"}, - } -} - -func schema_pkg_apis_investigation_v1alpha1_InvestigationstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "InvestigationstatusOperatorState defines model for Investigationstatus.#OperatorState.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "descriptiveState": { - SchemaProps: spec.SchemaProps{ - Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", - Type: []string{"string"}, - Format: "", - }, - }, - "details": { - SchemaProps: spec.SchemaProps{ - Description: "details contains any extra information that is operator-specific", - Type: []string{"object"}, - AdditionalProperties: &spec.SchemaOrBool{ - Allows: true, - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Type: []string{"object"}, - Format: "", - }, - }, - }, - }, - }, - "lastEvaluation": { - SchemaProps: spec.SchemaProps{ - Description: "lastEvaluation is the ResourceVersion last evaluated", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - "state": { - SchemaProps: spec.SchemaProps{ - Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, - }, - Required: []string{"lastEvaluation", "state"}, - }, - }, - } -} diff --git a/apps/investigation/pkg/apis/manifest.go b/apps/investigation/pkg/apis/manifest.go deleted file mode 100644 index 2812059e14a..00000000000 --- a/apps/investigation/pkg/apis/manifest.go +++ /dev/null @@ -1,50 +0,0 @@ -// -// This file is generated by grafana-app-sdk -// DO NOT EDIT -// - -package apis - -import ( - "encoding/json" - - "github.com/grafana/grafana-app-sdk/app" -) - -var ( - rawSchemaInvestigationv1alpha1 = []byte(`{"spec":{"description":"spec is the schema of our resource. The spec should include all the user-ediable information for the kind.","properties":{"items":{"items":{"properties":{"dataQuery":{"description":"dataQuery contains the query used to generate this item.","oneOf":[{"allOf":[{"required":["refId","datasource","expr"]},{"not":{"anyOf":[{"required":["refId","datasource","expr"]}]}}]},{"allOf":[{"required":["refId","datasource","expr"]},{"not":{"anyOf":[{"required":["refId","datasource","expr"]}]}}]}],"properties":{"datasource":{"description":"datasource is the datasource of the query.","properties":{"apiVersion":{"type":"string"},"name":{"type":"string"},"type":{"type":"string"},"uid":{"type":"string"}},"required":["uid","type","apiVersion","name"],"type":"object"},"expr":{"description":"expr is the expression of the query.","type":"string"},"maxLines":{"description":"maxLines (optional) is used to limit the number of log rows returned.","format":"int64","type":"integer"},"refId":{"description":"refId is the reference ID of the query.","type":"string"}},"type":"object"},"iconPath":{"description":"iconPath (optional) is the path to the icon for the item.","type":"string"},"id":{"type":"string"},"note":{"description":"note (optional) is a comment on the item.","items":{"properties":{"authorUserID":{"type":"string"},"bodyMarkdown":{"type":"string"}},"required":["authorUserID","bodyMarkdown"],"type":"object"},"type":"array"},"origin":{"description":"origin is where the item was created from.","type":"string"},"queryType":{"description":"queryType is the type of the query used to generate this item.","enum":["logs","metrics"],"type":"string"},"timeRange":{"description":"timeRange (optional) is the time range of the item.","properties":{"from":{"type":"number"},"to":{"type":"number"}},"required":["from","to"],"type":"object"},"title":{"type":"string"},"type":{"description":"type is the type of the item \"timeseries\", \"heatmap\", \"log-table\" (not an enum to allow for future extensions).","type":"string"},"url":{"description":"url is the URL to the item.","type":"string"}},"required":["id","title","type","url","origin","timeRange","queryType","dataQuery"],"type":"object"},"type":"array"},"status":{"enum":["open","closed"],"type":"string"},"title":{"type":"string"}},"required":["title","status","items"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) - versionSchemaInvestigationv1alpha1 app.VersionSchema - _ = json.Unmarshal(rawSchemaInvestigationv1alpha1, &versionSchemaInvestigationv1alpha1) -) - -var appManifestData = app.ManifestData{ - AppName: "investigation", - Group: "investigation.grafana.app", - Kinds: []app.ManifestKind{ - { - Kind: "Investigation", - Scope: "Namespaced", - Conversion: false, - Versions: []app.ManifestKindVersion{ - { - Name: "v1alpha1", - Schema: &versionSchemaInvestigationv1alpha1, - }, - }, - }, - }, -} - -func jsonToMap(j string) map[string]any { - m := make(map[string]any) - json.Unmarshal([]byte(j), &j) - return m -} - -func LocalManifest() app.Manifest { - return app.NewEmbeddedManifest(appManifestData) -} - -func RemoteManifest() app.Manifest { - return app.NewAPIServerManifest("investigation") -} diff --git a/apps/investigations/Makefile b/apps/investigations/Makefile new file mode 100644 index 00000000000..7a5f1c99365 --- /dev/null +++ b/apps/investigations/Makefile @@ -0,0 +1,3 @@ +.PHONY: generate +generate: + @grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none diff --git a/apps/investigations/example.json b/apps/investigations/example.json new file mode 100644 index 00000000000..0a390fb074f --- /dev/null +++ b/apps/investigations/example.json @@ -0,0 +1,152 @@ +[ + { + "id": "896312ce-65b0-4b50-ade1-e7f04fa22c66", + "title": "Thursday morning investigation", + "hasCustomName": false, + "isFavorite": false, + "collectables": [ + { + "origin": "Explore Logs", + "type": "timeseries", + "queries": [ + { + "refId": "LABEL_BREAKDOWN_VALUES", + "queryType": "range", + "editorMode": "code", + "supportingQueryType": "grafana-lokiexplore-app", + "legendFormat": "{{detected_level}}", + "expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)" + } + ], + "timeRange": { + "to": "2025-02-13T11:31:20.536Z", + "from": "2025-02-13T11:16:20.536Z", + "raw": { + "from": "now-15m", + "to": "now" + } + }, + "datasource": { + "uid": "fe9k7u07b1a0wc" + }, + "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", + "id": "LABEL_BREAKDOWN_VALUES_detected_level", + "title": "detected_level", + "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", + "createdAt": "2025-02-13T11:31:23.637Z" + } + ], + "createdAt": "2025-02-13T11:31:23.636Z", + "updatedAt": "2025-02-13T11:31:23.637Z", + "viewMode": { + "mode": "compact", + "showComments": true, + "showTooltips": false + } + }, + { + "id": "e9cf1958-d0ed-46b7-b597-9052c7648656", + "title": "Thursday morning investigation", + "hasCustomName": false, + "isFavorite": false, + "collectables": [ + { + "origin": "Explore Logs", + "type": "timeseries", + "queries": [ + { + "refId": "LABEL_BREAKDOWN_VALUES", + "queryType": "range", + "editorMode": "code", + "supportingQueryType": "grafana-lokiexplore-app", + "legendFormat": "{{detected_level}}", + "expr": "sum(count_over_time({service_name=\"web_app_1\"} | detected_level != \"\"[$__auto])) by (detected_level)" + } + ], + "timeRange": { + "to": "2025-02-13T11:31:20.536Z", + "from": "2025-02-13T11:16:20.536Z", + "raw": { + "from": "now-15m", + "to": "now" + } + }, + "datasource": { + "uid": "fe9k7u07b1a0wc" + }, + "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", + "id": "LABEL_BREAKDOWN_VALUES_detected_level", + "title": "detected_level", + "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", + "createdAt": "2025-02-13T11:31:23.638Z" + }, + { + "origin": "Explore Logs", + "type": "timeseries", + "queries": [ + { + "refId": "LABEL_BREAKDOWN_VALUES", + "queryType": "range", + "editorMode": "code", + "supportingQueryType": "grafana-lokiexplore-app", + "legendFormat": "{{service_name}}", + "expr": "sum(count_over_time({service_name=\"web_app_1\",service_name != \"\"} [$__auto])) by (service_name)" + } + ], + "timeRange": { + "to": "2025-02-13T11:31:20.536Z", + "from": "2025-02-13T11:16:20.536Z", + "raw": { + "from": "now-15m", + "to": "now" + } + }, + "datasource": { + "uid": "fe9k7u07b1a0wc" + }, + "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", + "id": "LABEL_BREAKDOWN_VALUES_service_name", + "title": "service_name", + "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", + "createdAt": "2025-02-13T11:31:41.507Z" + }, + { + "origin": "Explore Logs", + "type": "timeseries", + "queries": [ + { + "refId": "LABEL_BREAKDOWN_VALUES", + "queryType": "range", + "editorMode": "code", + "supportingQueryType": "grafana-lokiexplore-app", + "legendFormat": "{{service}}", + "expr": "sum(count_over_time({service_name=\"web_app_1\",service != \"\"} [$__auto])) by (service)" + } + ], + "timeRange": { + "to": "2025-02-13T11:31:20.536Z", + "from": "2025-02-13T11:16:20.536Z", + "raw": { + "from": "now-15m", + "to": "now" + } + }, + "datasource": { + "uid": "fe9k7u07b1a0wc" + }, + "url": "http://localhost:3000/a/grafana-lokiexplore-app/explore/service/web_app_1/labels?patterns=%5B%5D&from=now-15m&to=now&var-ds=fe9k7u07b1a0wc&var-filters=service_name%7C%3D%7Cweb_app_1&var-fields=&var-levels=&var-metadata=&var-patterns=&var-lineFilterV2=&var-lineFilters=&urlColumns=%5B%5D&visualizationType=%22logs%22&displayedFields=%5B%5D&timezone=browser&var-all-fields=&var-labelBy=$__all", + "id": "LABEL_BREAKDOWN_VALUES_service", + "title": "service", + "logoPath": "public/plugins/grafana-lokiexplore-app/img/img/logo.svg", + "createdAt": "2025-02-13T11:31:43.698Z" + } + ], + "createdAt": "2025-02-13T11:31:23.637Z", + "updatedAt": "2025-02-13T11:31:43.698Z", + "viewMode": { + "mode": "compact", + "showComments": true, + "showTooltips": false + } + } +] diff --git a/apps/investigation/go.mod b/apps/investigations/go.mod similarity index 60% rename from apps/investigation/go.mod rename to apps/investigations/go.mod index de0d3fa2621..645f323e800 100644 --- a/apps/investigation/go.mod +++ b/apps/investigations/go.mod @@ -1,10 +1,10 @@ -module github.com/grafana/grafana/apps/investigation +module github.com/grafana/grafana/apps/investigations -go 1.23.4 +go 1.23.7 require ( - github.com/grafana/grafana-app-sdk v0.30.0 - k8s.io/apimachinery v0.32.0 + github.com/grafana/grafana-app-sdk v0.31.0 + k8s.io/apimachinery v0.32.1 k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f ) @@ -18,7 +18,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.128.0 // indirect + github.com/getkin/kin-openapi v0.129.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -27,15 +27,14 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect @@ -44,40 +43,44 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect + github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect + github.com/onsi/gomega v1.36.1 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.21.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/grpc v1.69.4 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect + google.golang.org/grpc v1.70.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.32.0 // indirect - k8s.io/apiextensions-apiserver v0.32.0 // indirect - k8s.io/client-go v0.32.0 // indirect + k8s.io/api v0.32.1 // indirect + k8s.io/apiextensions-apiserver v0.32.1 // indirect + k8s.io/client-go v0.32.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect diff --git a/apps/investigation/go.sum b/apps/investigations/go.sum similarity index 72% rename from apps/investigation/go.sum rename to apps/investigations/go.sum index 858c73dd4b4..88d0fa45e79 100644 --- a/apps/investigation/go.sum +++ b/apps/investigations/go.sum @@ -16,8 +16,8 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= -github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30= +github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -40,8 +40,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -49,19 +49,17 @@ github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/Z github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/grafana-app-sdk v0.30.0 h1:Hqn2pETu2mQ4RpWkZYEQfu01P7xd1Z1Gj+HX/8aB0tw= -github.com/grafana/grafana-app-sdk v0.30.0/go.mod h1:jhfqNIovb+Mes2vdMf9iMCWQkp1GTNtyNuExONtiNuk= -github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4= -github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= +github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME= +github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= -github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -87,10 +85,14 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU= +github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8= +github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc= +github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -98,20 +100,20 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= +github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -124,22 +126,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -153,26 +155,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -187,14 +189,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= -google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= -google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -204,14 +206,14 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= -k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= -k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw= +k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= diff --git a/apps/investigations/kinds/collectable.cue b/apps/investigations/kinds/collectable.cue new file mode 100644 index 00000000000..6844c0a8cae --- /dev/null +++ b/apps/investigations/kinds/collectable.cue @@ -0,0 +1,51 @@ +package investigations + +// Collectable represents an item collected during investigation +#Collectable: { + id: string + createdAt: string + + title: string + origin: string + type: string + queries: [...#Query] // +listType=atomic + timeRange: #TimeRange + datasource: #DatasourceRef + url: string + logoPath?: string + + note: string + noteUpdatedAt: string +} + +#CollectableSummary: { + id: string + title: string + logoPath: string + origin: string +} + +// Query represents a data query +#Query: { + refId: string + queryType: string + editorMode: string + supportingQueryType: string + legendFormat: string + expr: string +} + +// TimeRange represents a time range with both absolute and relative values +#TimeRange: { + from: string + to: string + raw: { + from: string + to: string + } +} + +// DatasourceRef is a reference to a datasource +#DatasourceRef: { + uid: string +} diff --git a/apps/investigations/kinds/cue.mod/module.cue b/apps/investigations/kinds/cue.mod/module.cue new file mode 100644 index 00000000000..55fe474ed5f --- /dev/null +++ b/apps/investigations/kinds/cue.mod/module.cue @@ -0,0 +1 @@ +module: "github.com/grafana/grafana/apps/investigations" diff --git a/apps/investigations/kinds/investigation.cue b/apps/investigations/kinds/investigation.cue new file mode 100644 index 00000000000..f1e9a69027f --- /dev/null +++ b/apps/investigations/kinds/investigation.cue @@ -0,0 +1,64 @@ +package investigations + +// This is our Investigation definition, which contains metadata about the kind, and the kind's schema +investigation: { + kind: "Investigation" + group: "investigations.grafana.app" + apiResource: { + groupOverride: "investigations.grafana.app" + } + pluralName: "Investigations" + current: "v0alpha1" + versions: { + "v0alpha1": { + codegen: { + frontend: true + backend: true + options: { + generateObjectMeta: true + generateClient: true + k8sLike: true + package: "github.com/grafana/grafana/apps/investigations" + } + } + schema: { + // spec is the schema of our resource + spec: { + title: string + createdByProfile: #Person + hasCustomName: bool + isFavorite: bool + overviewNote: string + overviewNoteUpdatedAt: string + collectables: [...#Collectable] // +listType=atomic + viewMode: #ViewMode + } + } + } + } +} + +// Type definition for investigation summaries +#InvestigationSummary: { + title: string + createdByProfile: #Person + hasCustomName: bool + isFavorite: bool + overviewNote: string + overviewNoteUpdatedAt: string + viewMode: #ViewMode + collectableSummaries: [...#CollectableSummary] // +listType=atomic +} + +// Person represents a user profile with basic information +#Person: { + uid: string // Unique identifier for the user + name: string // Display name of the user + gravatarUrl: string // URL to user's Gravatar image +} + +#ViewMode: { + mode: "compact" | "full" + showComments: bool + showTooltips: bool +} diff --git a/apps/investigations/kinds/investigationindex.cue b/apps/investigations/kinds/investigationindex.cue new file mode 100644 index 00000000000..447e156be4f --- /dev/null +++ b/apps/investigations/kinds/investigationindex.cue @@ -0,0 +1,37 @@ +package investigations + +investigationIndex: { + kind: "InvestigationIndex" + group: "investigations.grafana.app" + apiResource: { + groupOverride: "investigations.grafana.app" + } + pluralName: "InvestigationIndexes" + current: "v0alpha1" + versions: { + "v0alpha1": { + codegen: { + frontend: true + backend: true + options: { + generateObjectMeta: true + generateClient: true + k8sLike: true + package: "github.com/grafana/grafana/apps/investigations" + } + } + schema: { + spec: { + // Title of the index, e.g. 'Favorites' or 'My Investigations' + title: string + + // The Person who owns this investigation index + owner: #Person + + // Array of investigation summaries + investigationSummaries: [...#InvestigationSummary] // +listType=atomic + } + } + } + } +} diff --git a/apps/investigations/kinds/manifest.cue b/apps/investigations/kinds/manifest.cue new file mode 100644 index 00000000000..d9e93b00061 --- /dev/null +++ b/apps/investigations/kinds/manifest.cue @@ -0,0 +1,10 @@ +package investigations + +manifest: { + appName: "investigations" + groupOverride: "investigations.grafana.app" + kinds: [ + investigation, + investigationIndex, + ] +} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/constants.go b/apps/investigations/pkg/apis/investigations/v0alpha1/constants.go new file mode 100644 index 00000000000..288c15885ce --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/constants.go @@ -0,0 +1,18 @@ +package v0alpha1 + +import "k8s.io/apimachinery/pkg/runtime/schema" + +const ( + // Group is the API group used by all kinds in this package + Group = "investigations.grafana.app" + // Version is the API version used by all kinds in this package + Version = "v0alpha1" +) + +var ( + // GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package + GroupVersion = schema.GroupVersion{ + Group: Group, + Version: Version, + } +) diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_codec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go similarity index 97% rename from apps/investigation/pkg/apis/investigation/v1alpha1/investigation_codec_gen.go rename to apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go index 73e2232d045..6bde81b50d3 100644 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_codec_gen.go +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_codec_gen.go @@ -2,7 +2,7 @@ // Code generated by grafana-app-sdk. DO NOT EDIT. // -package v1alpha1 +package v0alpha1 import ( "encoding/json" diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go new file mode 100644 index 00000000000..e0d2756f194 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type InvestigationMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewInvestigationMetadata creates a new InvestigationMetadata object. +func NewInvestigationMetadata() *InvestigationMetadata { + return &InvestigationMetadata{} +} diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_object_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go similarity index 94% rename from apps/investigation/pkg/apis/investigation/v1alpha1/investigation_object_gen.go rename to apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go index c97fc75eec1..21c8d760fe6 100644 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_object_gen.go +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_object_gen.go @@ -2,7 +2,7 @@ // Code generated by grafana-app-sdk. DO NOT EDIT. // -package v1alpha1 +package v0alpha1 import ( "fmt" @@ -16,10 +16,10 @@ import ( // +k8s:openapi-gen=true type Investigation struct { - metav1.TypeMeta `json:",inline"` - metav1.ObjectMeta `json:"metadata"` - Spec InvestigationSpec `json:"spec"` - InvestigationStatus InvestigationStatus `json:"status"` + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + Spec InvestigationSpec `json:"spec" yaml:"spec"` + InvestigationStatus InvestigationStatus `json:"status" yaml:"status"` } func (o *Investigation) GetSpec() any { @@ -224,9 +224,9 @@ var _ resource.Object = &Investigation{} // +k8s:openapi-gen=true type InvestigationList struct { - metav1.TypeMeta `json:",inline"` - metav1.ListMeta `json:"metadata"` - Items []Investigation `json:"items"` + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []Investigation `json:"items" yaml:"items"` } func (o *InvestigationList) DeepCopyObject() runtime.Object { diff --git a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_schema_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go similarity index 81% rename from apps/investigation/pkg/apis/investigation/v1alpha1/investigation_schema_gen.go rename to apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go index c20995f0981..2a1f03c884a 100644 --- a/apps/investigation/pkg/apis/investigation/v1alpha1/investigation_schema_gen.go +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_schema_gen.go @@ -2,7 +2,7 @@ // Code generated by grafana-app-sdk. DO NOT EDIT. // -package v1alpha1 +package v0alpha1 import ( "github.com/grafana/grafana-app-sdk/resource" @@ -10,7 +10,7 @@ import ( // schema is unexported to prevent accidental overwrites var ( - schemaInvestigation = resource.NewSimpleSchema("investigation.grafana.app", "v1alpha1", &Investigation{}, &InvestigationList{}, resource.WithKind("Investigation"), + schemaInvestigation = resource.NewSimpleSchema("investigations.grafana.app", "v0alpha1", &Investigation{}, &InvestigationList{}, resource.WithKind("Investigation"), resource.WithPlural("investigations"), resource.WithScope(resource.NamespacedScope)) kindInvestigation = resource.Kind{ Schema: schemaInvestigation, diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go new file mode 100644 index 00000000000..3bca90e4579 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_spec_gen.go @@ -0,0 +1,140 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// Person represents a user profile with basic information +// +k8s:openapi-gen=true +type InvestigationPerson struct { + // Unique identifier for the user + Uid string `json:"uid"` + // Display name of the user + Name string `json:"name"` + // URL to user's Gravatar image + GravatarUrl string `json:"gravatarUrl"` +} + +// NewInvestigationPerson creates a new InvestigationPerson object. +func NewInvestigationPerson() *InvestigationPerson { + return &InvestigationPerson{} +} + +// Collectable represents an item collected during investigation +// +k8s:openapi-gen=true +type InvestigationCollectable struct { + Id string `json:"id"` + CreatedAt string `json:"createdAt"` + Title string `json:"title"` + Origin string `json:"origin"` + Type string `json:"type"` + // +listType=atomic + Queries []InvestigationQuery `json:"queries"` + TimeRange InvestigationTimeRange `json:"timeRange"` + Datasource InvestigationDatasourceRef `json:"datasource"` + Url string `json:"url"` + LogoPath *string `json:"logoPath,omitempty"` + Note string `json:"note"` + NoteUpdatedAt string `json:"noteUpdatedAt"` +} + +// NewInvestigationCollectable creates a new InvestigationCollectable object. +func NewInvestigationCollectable() *InvestigationCollectable { + return &InvestigationCollectable{ + TimeRange: *NewInvestigationTimeRange(), + Datasource: *NewInvestigationDatasourceRef(), + } +} + +// Query represents a data query +// +k8s:openapi-gen=true +type InvestigationQuery struct { + RefId string `json:"refId"` + QueryType string `json:"queryType"` + EditorMode string `json:"editorMode"` + SupportingQueryType string `json:"supportingQueryType"` + LegendFormat string `json:"legendFormat"` + Expr string `json:"expr"` +} + +// NewInvestigationQuery creates a new InvestigationQuery object. +func NewInvestigationQuery() *InvestigationQuery { + return &InvestigationQuery{} +} + +// TimeRange represents a time range with both absolute and relative values +// +k8s:openapi-gen=true +type InvestigationTimeRange struct { + From string `json:"from"` + To string `json:"to"` + Raw InvestigationV0alpha1TimeRangeRaw `json:"raw"` +} + +// NewInvestigationTimeRange creates a new InvestigationTimeRange object. +func NewInvestigationTimeRange() *InvestigationTimeRange { + return &InvestigationTimeRange{ + Raw: *NewInvestigationV0alpha1TimeRangeRaw(), + } +} + +// DatasourceRef is a reference to a datasource +// +k8s:openapi-gen=true +type InvestigationDatasourceRef struct { + Uid string `json:"uid"` +} + +// NewInvestigationDatasourceRef creates a new InvestigationDatasourceRef object. +func NewInvestigationDatasourceRef() *InvestigationDatasourceRef { + return &InvestigationDatasourceRef{} +} + +// +k8s:openapi-gen=true +type InvestigationViewMode struct { + Mode InvestigationViewModeMode `json:"mode"` + ShowComments bool `json:"showComments"` + ShowTooltips bool `json:"showTooltips"` +} + +// NewInvestigationViewMode creates a new InvestigationViewMode object. +func NewInvestigationViewMode() *InvestigationViewMode { + return &InvestigationViewMode{} +} + +// spec is the schema of our resource +// +k8s:openapi-gen=true +type InvestigationSpec struct { + Title string `json:"title"` + CreatedByProfile InvestigationPerson `json:"createdByProfile"` + HasCustomName bool `json:"hasCustomName"` + IsFavorite bool `json:"isFavorite"` + OverviewNote string `json:"overviewNote"` + OverviewNoteUpdatedAt string `json:"overviewNoteUpdatedAt"` + // +listType=atomic + Collectables []InvestigationCollectable `json:"collectables"` + ViewMode InvestigationViewMode `json:"viewMode"` +} + +// NewInvestigationSpec creates a new InvestigationSpec object. +func NewInvestigationSpec() *InvestigationSpec { + return &InvestigationSpec{ + CreatedByProfile: *NewInvestigationPerson(), + ViewMode: *NewInvestigationViewMode(), + } +} + +// +k8s:openapi-gen=true +type InvestigationV0alpha1TimeRangeRaw struct { + From string `json:"from"` + To string `json:"to"` +} + +// NewInvestigationV0alpha1TimeRangeRaw creates a new InvestigationV0alpha1TimeRangeRaw object. +func NewInvestigationV0alpha1TimeRangeRaw() *InvestigationV0alpha1TimeRangeRaw { + return &InvestigationV0alpha1TimeRangeRaw{} +} + +// +k8s:openapi-gen=true +type InvestigationViewModeMode string + +const ( + InvestigationViewModeModeCompact InvestigationViewModeMode = "compact" + InvestigationViewModeModeFull InvestigationViewModeMode = "full" +) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go new file mode 100644 index 00000000000..c70224b96e4 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigation_status_gen.go @@ -0,0 +1,44 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type InvestigationstatusOperatorState struct { + // lastEvaluation is the ResourceVersion last evaluated + LastEvaluation string `json:"lastEvaluation"` + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + State InvestigationStatusOperatorStateState `json:"state"` + // descriptiveState is an optional more descriptive state field which has no requirements on format + DescriptiveState *string `json:"descriptiveState,omitempty"` + // details contains any extra information that is operator-specific + Details map[string]interface{} `json:"details,omitempty"` +} + +// NewInvestigationstatusOperatorState creates a new InvestigationstatusOperatorState object. +func NewInvestigationstatusOperatorState() *InvestigationstatusOperatorState { + return &InvestigationstatusOperatorState{} +} + +// +k8s:openapi-gen=true +type InvestigationStatus struct { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + OperatorStates map[string]InvestigationstatusOperatorState `json:"operatorStates,omitempty"` + // additionalFields is reserved for future use + AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` +} + +// NewInvestigationStatus creates a new InvestigationStatus object. +func NewInvestigationStatus() *InvestigationStatus { + return &InvestigationStatus{} +} + +// +k8s:openapi-gen=true +type InvestigationStatusOperatorStateState string + +const ( + InvestigationStatusOperatorStateStateSuccess InvestigationStatusOperatorStateState = "success" + InvestigationStatusOperatorStateStateInProgress InvestigationStatusOperatorStateState = "in_progress" + InvestigationStatusOperatorStateStateFailed InvestigationStatusOperatorStateState = "failed" +) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go new file mode 100644 index 00000000000..0496ce4af6f --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_codec_gen.go @@ -0,0 +1,28 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "encoding/json" + "io" + + "github.com/grafana/grafana-app-sdk/resource" +) + +// InvestigationIndexJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding +type InvestigationIndexJSONCodec struct{} + +// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into` +func (*InvestigationIndexJSONCodec) Read(reader io.Reader, into resource.Object) error { + return json.NewDecoder(reader).Decode(into) +} + +// Write writes JSON-encoded bytes into `writer` marshaled from `from` +func (*InvestigationIndexJSONCodec) Write(writer io.Writer, from resource.Object) error { + return json.NewEncoder(writer).Encode(from) +} + +// Interface compliance checks +var _ resource.Codec = &InvestigationIndexJSONCodec{} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go new file mode 100644 index 00000000000..67e97598a93 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_metadata_gen.go @@ -0,0 +1,28 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +import ( + time "time" +) + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +type InvestigationIndexMetadata struct { + UpdateTimestamp time.Time `json:"updateTimestamp"` + CreatedBy string `json:"createdBy"` + Uid string `json:"uid"` + CreationTimestamp time.Time `json:"creationTimestamp"` + DeletionTimestamp *time.Time `json:"deletionTimestamp,omitempty"` + Finalizers []string `json:"finalizers"` + ResourceVersion string `json:"resourceVersion"` + Generation int64 `json:"generation"` + UpdatedBy string `json:"updatedBy"` + Labels map[string]string `json:"labels"` +} + +// NewInvestigationIndexMetadata creates a new InvestigationIndexMetadata object. +func NewInvestigationIndexMetadata() *InvestigationIndexMetadata { + return &InvestigationIndexMetadata{} +} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go new file mode 100644 index 00000000000..cc3c33964ed --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_object_gen.go @@ -0,0 +1,266 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "fmt" + "github.com/grafana/grafana-app-sdk/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/types" + "time" +) + +// +k8s:openapi-gen=true +type InvestigationIndex struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ObjectMeta `json:"metadata" yaml:"metadata"` + Spec InvestigationIndexSpec `json:"spec" yaml:"spec"` + InvestigationIndexStatus InvestigationIndexStatus `json:"status" yaml:"status"` +} + +func (o *InvestigationIndex) GetSpec() any { + return o.Spec +} + +func (o *InvestigationIndex) SetSpec(spec any) error { + cast, ok := spec.(InvestigationIndexSpec) + if !ok { + return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec) + } + o.Spec = cast + return nil +} + +func (o *InvestigationIndex) GetSubresources() map[string]any { + return map[string]any{ + "status": o.InvestigationIndexStatus, + } +} + +func (o *InvestigationIndex) GetSubresource(name string) (any, bool) { + switch name { + case "status": + return o.InvestigationIndexStatus, true + default: + return nil, false + } +} + +func (o *InvestigationIndex) SetSubresource(name string, value any) error { + switch name { + case "status": + cast, ok := value.(InvestigationIndexStatus) + if !ok { + return fmt.Errorf("cannot set status type %#v, not of type InvestigationIndexStatus", value) + } + o.InvestigationIndexStatus = cast + return nil + default: + return fmt.Errorf("subresource '%s' does not exist", name) + } +} + +func (o *InvestigationIndex) GetStaticMetadata() resource.StaticMetadata { + gvk := o.GroupVersionKind() + return resource.StaticMetadata{ + Name: o.ObjectMeta.Name, + Namespace: o.ObjectMeta.Namespace, + Group: gvk.Group, + Version: gvk.Version, + Kind: gvk.Kind, + } +} + +func (o *InvestigationIndex) SetStaticMetadata(metadata resource.StaticMetadata) { + o.Name = metadata.Name + o.Namespace = metadata.Namespace + o.SetGroupVersionKind(schema.GroupVersionKind{ + Group: metadata.Group, + Version: metadata.Version, + Kind: metadata.Kind, + }) +} + +func (o *InvestigationIndex) GetCommonMetadata() resource.CommonMetadata { + dt := o.DeletionTimestamp + var deletionTimestamp *time.Time + if dt != nil { + deletionTimestamp = &dt.Time + } + // Legacy ExtraFields support + extraFields := make(map[string]any) + if o.Annotations != nil { + extraFields["annotations"] = o.Annotations + } + if o.ManagedFields != nil { + extraFields["managedFields"] = o.ManagedFields + } + if o.OwnerReferences != nil { + extraFields["ownerReferences"] = o.OwnerReferences + } + return resource.CommonMetadata{ + UID: string(o.UID), + ResourceVersion: o.ResourceVersion, + Generation: o.Generation, + Labels: o.Labels, + CreationTimestamp: o.CreationTimestamp.Time, + DeletionTimestamp: deletionTimestamp, + Finalizers: o.Finalizers, + UpdateTimestamp: o.GetUpdateTimestamp(), + CreatedBy: o.GetCreatedBy(), + UpdatedBy: o.GetUpdatedBy(), + ExtraFields: extraFields, + } +} + +func (o *InvestigationIndex) SetCommonMetadata(metadata resource.CommonMetadata) { + o.UID = types.UID(metadata.UID) + o.ResourceVersion = metadata.ResourceVersion + o.Generation = metadata.Generation + o.Labels = metadata.Labels + o.CreationTimestamp = metav1.NewTime(metadata.CreationTimestamp) + if metadata.DeletionTimestamp != nil { + dt := metav1.NewTime(*metadata.DeletionTimestamp) + o.DeletionTimestamp = &dt + } else { + o.DeletionTimestamp = nil + } + o.Finalizers = metadata.Finalizers + if o.Annotations == nil { + o.Annotations = make(map[string]string) + } + if !metadata.UpdateTimestamp.IsZero() { + o.SetUpdateTimestamp(metadata.UpdateTimestamp) + } + if metadata.CreatedBy != "" { + o.SetCreatedBy(metadata.CreatedBy) + } + if metadata.UpdatedBy != "" { + o.SetUpdatedBy(metadata.UpdatedBy) + } + // Legacy support for setting Annotations, ManagedFields, and OwnerReferences via ExtraFields + if metadata.ExtraFields != nil { + if annotations, ok := metadata.ExtraFields["annotations"]; ok { + if cast, ok := annotations.(map[string]string); ok { + o.Annotations = cast + } + } + if managedFields, ok := metadata.ExtraFields["managedFields"]; ok { + if cast, ok := managedFields.([]metav1.ManagedFieldsEntry); ok { + o.ManagedFields = cast + } + } + if ownerReferences, ok := metadata.ExtraFields["ownerReferences"]; ok { + if cast, ok := ownerReferences.([]metav1.OwnerReference); ok { + o.OwnerReferences = cast + } + } + } +} + +func (o *InvestigationIndex) GetCreatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/createdBy"] +} + +func (o *InvestigationIndex) SetCreatedBy(createdBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy +} + +func (o *InvestigationIndex) GetUpdateTimestamp() time.Time { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + parsed, _ := time.Parse(time.RFC3339, o.ObjectMeta.Annotations["grafana.com/updateTimestamp"]) + return parsed +} + +func (o *InvestigationIndex) SetUpdateTimestamp(updateTimestamp time.Time) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updateTimestamp"] = updateTimestamp.Format(time.RFC3339) +} + +func (o *InvestigationIndex) GetUpdatedBy() string { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + return o.ObjectMeta.Annotations["grafana.com/updatedBy"] +} + +func (o *InvestigationIndex) SetUpdatedBy(updatedBy string) { + if o.ObjectMeta.Annotations == nil { + o.ObjectMeta.Annotations = make(map[string]string) + } + + o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy +} + +func (o *InvestigationIndex) Copy() resource.Object { + return resource.CopyObject(o) +} + +func (o *InvestigationIndex) DeepCopyObject() runtime.Object { + return o.Copy() +} + +// Interface compliance compile-time check +var _ resource.Object = &InvestigationIndex{} + +// +k8s:openapi-gen=true +type InvestigationIndexList struct { + metav1.TypeMeta `json:",inline" yaml:",inline"` + metav1.ListMeta `json:"metadata" yaml:"metadata"` + Items []InvestigationIndex `json:"items" yaml:"items"` +} + +func (o *InvestigationIndexList) DeepCopyObject() runtime.Object { + return o.Copy() +} + +func (o *InvestigationIndexList) Copy() resource.ListObject { + cpy := &InvestigationIndexList{ + TypeMeta: o.TypeMeta, + Items: make([]InvestigationIndex, len(o.Items)), + } + o.ListMeta.DeepCopyInto(&cpy.ListMeta) + for i := 0; i < len(o.Items); i++ { + if item, ok := o.Items[i].Copy().(*InvestigationIndex); ok { + cpy.Items[i] = *item + } + } + return cpy +} + +func (o *InvestigationIndexList) GetItems() []resource.Object { + items := make([]resource.Object, len(o.Items)) + for i := 0; i < len(o.Items); i++ { + items[i] = &o.Items[i] + } + return items +} + +func (o *InvestigationIndexList) SetItems(items []resource.Object) { + o.Items = make([]InvestigationIndex, len(items)) + for i := 0; i < len(items); i++ { + o.Items[i] = *items[i].(*InvestigationIndex) + } +} + +// Interface compliance compile-time check +var _ resource.ListObject = &InvestigationIndexList{} diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go new file mode 100644 index 00000000000..3a0041dc6b8 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_schema_gen.go @@ -0,0 +1,34 @@ +// +// Code generated by grafana-app-sdk. DO NOT EDIT. +// + +package v0alpha1 + +import ( + "github.com/grafana/grafana-app-sdk/resource" +) + +// schema is unexported to prevent accidental overwrites +var ( + schemaInvestigationIndex = resource.NewSimpleSchema("investigations.grafana.app", "v0alpha1", &InvestigationIndex{}, &InvestigationIndexList{}, resource.WithKind("InvestigationIndex"), + resource.WithPlural("investigationindexes"), resource.WithScope(resource.NamespacedScope)) + kindInvestigationIndex = resource.Kind{ + Schema: schemaInvestigationIndex, + Codecs: map[resource.KindEncoding]resource.Codec{ + resource.KindEncodingJSON: &InvestigationIndexJSONCodec{}, + }, + } +) + +// Kind returns a resource.Kind for this Schema with a JSON codec +func InvestigationIndexKind() resource.Kind { + return kindInvestigationIndex +} + +// Schema returns a resource.SimpleSchema representation of InvestigationIndex +func InvestigationIndexSchema() *resource.SimpleSchema { + return schemaInvestigationIndex +} + +// Interface compliance checks +var _ resource.Schema = kindInvestigationIndex diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go new file mode 100644 index 00000000000..4180a63a326 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_spec_gen.go @@ -0,0 +1,92 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// Person represents a user profile with basic information +// +k8s:openapi-gen=true +type InvestigationIndexPerson struct { + // Unique identifier for the user + Uid string `json:"uid"` + // Display name of the user + Name string `json:"name"` + // URL to user's Gravatar image + GravatarUrl string `json:"gravatarUrl"` +} + +// NewInvestigationIndexPerson creates a new InvestigationIndexPerson object. +func NewInvestigationIndexPerson() *InvestigationIndexPerson { + return &InvestigationIndexPerson{} +} + +// Type definition for investigation summaries +// +k8s:openapi-gen=true +type InvestigationIndexInvestigationSummary struct { + Title string `json:"title"` + CreatedByProfile InvestigationIndexPerson `json:"createdByProfile"` + HasCustomName bool `json:"hasCustomName"` + IsFavorite bool `json:"isFavorite"` + OverviewNote string `json:"overviewNote"` + OverviewNoteUpdatedAt string `json:"overviewNoteUpdatedAt"` + ViewMode InvestigationIndexViewMode `json:"viewMode"` + // +listType=atomic + CollectableSummaries []InvestigationIndexCollectableSummary `json:"collectableSummaries"` +} + +// NewInvestigationIndexInvestigationSummary creates a new InvestigationIndexInvestigationSummary object. +func NewInvestigationIndexInvestigationSummary() *InvestigationIndexInvestigationSummary { + return &InvestigationIndexInvestigationSummary{ + CreatedByProfile: *NewInvestigationIndexPerson(), + ViewMode: *NewInvestigationIndexViewMode(), + } +} + +// +k8s:openapi-gen=true +type InvestigationIndexViewMode struct { + Mode InvestigationIndexViewModeMode `json:"mode"` + ShowComments bool `json:"showComments"` + ShowTooltips bool `json:"showTooltips"` +} + +// NewInvestigationIndexViewMode creates a new InvestigationIndexViewMode object. +func NewInvestigationIndexViewMode() *InvestigationIndexViewMode { + return &InvestigationIndexViewMode{} +} + +// +k8s:openapi-gen=true +type InvestigationIndexCollectableSummary struct { + Id string `json:"id"` + Title string `json:"title"` + LogoPath string `json:"logoPath"` + Origin string `json:"origin"` +} + +// NewInvestigationIndexCollectableSummary creates a new InvestigationIndexCollectableSummary object. +func NewInvestigationIndexCollectableSummary() *InvestigationIndexCollectableSummary { + return &InvestigationIndexCollectableSummary{} +} + +// +k8s:openapi-gen=true +type InvestigationIndexSpec struct { + // Title of the index, e.g. 'Favorites' or 'My Investigations' + Title string `json:"title"` + // The Person who owns this investigation index + Owner InvestigationIndexPerson `json:"owner"` + // Array of investigation summaries + // +listType=atomic + InvestigationSummaries []InvestigationIndexInvestigationSummary `json:"investigationSummaries"` +} + +// NewInvestigationIndexSpec creates a new InvestigationIndexSpec object. +func NewInvestigationIndexSpec() *InvestigationIndexSpec { + return &InvestigationIndexSpec{ + Owner: *NewInvestigationIndexPerson(), + } +} + +// +k8s:openapi-gen=true +type InvestigationIndexViewModeMode string + +const ( + InvestigationIndexViewModeModeCompact InvestigationIndexViewModeMode = "compact" + InvestigationIndexViewModeModeFull InvestigationIndexViewModeMode = "full" +) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go new file mode 100644 index 00000000000..455d39bdb48 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/investigationindex_status_gen.go @@ -0,0 +1,44 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +package v0alpha1 + +// +k8s:openapi-gen=true +type InvestigationIndexstatusOperatorState struct { + // lastEvaluation is the ResourceVersion last evaluated + LastEvaluation string `json:"lastEvaluation"` + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + State InvestigationIndexStatusOperatorStateState `json:"state"` + // descriptiveState is an optional more descriptive state field which has no requirements on format + DescriptiveState *string `json:"descriptiveState,omitempty"` + // details contains any extra information that is operator-specific + Details map[string]interface{} `json:"details,omitempty"` +} + +// NewInvestigationIndexstatusOperatorState creates a new InvestigationIndexstatusOperatorState object. +func NewInvestigationIndexstatusOperatorState() *InvestigationIndexstatusOperatorState { + return &InvestigationIndexstatusOperatorState{} +} + +// +k8s:openapi-gen=true +type InvestigationIndexStatus struct { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + OperatorStates map[string]InvestigationIndexstatusOperatorState `json:"operatorStates,omitempty"` + // additionalFields is reserved for future use + AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"` +} + +// NewInvestigationIndexStatus creates a new InvestigationIndexStatus object. +func NewInvestigationIndexStatus() *InvestigationIndexStatus { + return &InvestigationIndexStatus{} +} + +// +k8s:openapi-gen=true +type InvestigationIndexStatusOperatorStateState string + +const ( + InvestigationIndexStatusOperatorStateStateSuccess InvestigationIndexStatusOperatorStateState = "success" + InvestigationIndexStatusOperatorStateStateInProgress InvestigationIndexStatusOperatorStateState = "in_progress" + InvestigationIndexStatusOperatorStateStateFailed InvestigationIndexStatusOperatorStateState = "failed" +) diff --git a/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go b/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go new file mode 100644 index 00000000000..36648cfcd11 --- /dev/null +++ b/apps/investigations/pkg/apis/investigations/v0alpha1/zz_openapi_gen.go @@ -0,0 +1,1061 @@ +//go:build !ignore_autogenerated +// +build !ignore_autogenerated + +// Code generated by grafana-app-sdk. DO NOT EDIT. + +package v0alpha1 + +import ( + common "k8s.io/kube-openapi/pkg/common" + spec "k8s.io/kube-openapi/pkg/validation/spec" +) + +func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { + return map[string]common.OpenAPIDefinition{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation": schema_pkg_apis_investigations_v0alpha1_Investigation(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable": schema_pkg_apis_investigations_v0alpha1_InvestigationCollectable(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef": schema_pkg_apis_investigations_v0alpha1_InvestigationDatasourceRef(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex": schema_pkg_apis_investigations_v0alpha1_InvestigationIndex(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexCollectableSummary(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexInvestigationSummary(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexList": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexList(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexPerson(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexSpec(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexStatus(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexViewMode(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState": schema_pkg_apis_investigations_v0alpha1_InvestigationIndexstatusOperatorState(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationList": schema_pkg_apis_investigations_v0alpha1_InvestigationList(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson": schema_pkg_apis_investigations_v0alpha1_InvestigationPerson(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationQuery": schema_pkg_apis_investigations_v0alpha1_InvestigationQuery(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec": schema_pkg_apis_investigations_v0alpha1_InvestigationSpec(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus": schema_pkg_apis_investigations_v0alpha1_InvestigationStatus(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange": schema_pkg_apis_investigations_v0alpha1_InvestigationTimeRange(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw": schema_pkg_apis_investigations_v0alpha1_InvestigationV0alpha1TimeRangeRaw(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode": schema_pkg_apis_investigations_v0alpha1_InvestigationViewMode(ref), + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState": schema_pkg_apis_investigations_v0alpha1_InvestigationstatusOperatorState(ref), + } +} + +func schema_pkg_apis_investigations_v0alpha1_Investigation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus"), + }, + }, + }, + Required: []string{"metadata", "spec", "status"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationSpec", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationCollectable(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Collectable represents an item collected during investigation", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "createdAt": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "origin": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "type": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "queries": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationQuery"), + }, + }, + }, + }, + }, + "timeRange": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange"), + }, + }, + "datasource": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef"), + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "logoPath": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "note": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "noteUpdatedAt": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"id", "createdAt", "title", "origin", "type", "queries", "timeRange", "datasource", "url", "note", "noteUpdatedAt"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationDatasourceRef", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationQuery", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationTimeRange"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationDatasourceRef(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatasourceRef is a reference to a datasource", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "uid": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"uid"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndex(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus"), + }, + }, + }, + Required: []string{"metadata", "spec", "status"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexSpec", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexCollectableSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "logoPath": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "origin": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"id", "title", "logoPath", "origin"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexInvestigationSummary(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Type definition for investigation summaries", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "createdByProfile": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"), + }, + }, + "hasCustomName": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "isFavorite": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "overviewNote": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "overviewNoteUpdatedAt": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "viewMode": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode"), + }, + }, + "collectableSummaries": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary"), + }, + }, + }, + }, + }, + }, + Required: []string{"title", "createdByProfile", "hasCustomName", "isFavorite", "overviewNote", "overviewNoteUpdatedAt", "viewMode", "collectableSummaries"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexCollectableSummary", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexViewMode"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndex", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexPerson(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Person represents a user profile with basic information", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "Unique identifier for the user", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Display name of the user", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "gravatarUrl": { + SchemaProps: spec.SchemaProps{ + Description: "URL to user's Gravatar image", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"uid", "name", "gravatarUrl"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Description: "Title of the index, e.g. 'Favorites' or 'My Investigations'", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "owner": { + SchemaProps: spec.SchemaProps{ + Description: "The Person who owns this investigation index", + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"), + }, + }, + "investigationSummaries": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Array of investigation summaries", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary"), + }, + }, + }, + }, + }, + }, + Required: []string{"title", "owner", "investigationSummaries"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexInvestigationSummary", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexPerson"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "operatorStates": { + SchemaProps: spec.SchemaProps{ + Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState"), + }, + }, + }, + }, + }, + "additionalFields": { + SchemaProps: spec.SchemaProps{ + Description: "additionalFields is reserved for future use", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationIndexstatusOperatorState"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexViewMode(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "showComments": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "showTooltips": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"mode", "showComments", "showTooltips"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationIndexstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "lastEvaluation": { + SchemaProps: spec.SchemaProps{ + Description: "lastEvaluation is the ResourceVersion last evaluated", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "state": { + SchemaProps: spec.SchemaProps{ + Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "descriptiveState": { + SchemaProps: spec.SchemaProps{ + Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", + Type: []string{"string"}, + Format: "", + }, + }, + "details": { + SchemaProps: spec.SchemaProps{ + Description: "details contains any extra information that is operator-specific", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"lastEvaluation", "state"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation"), + }, + }, + }, + }, + }, + }, + Required: []string{"metadata", "items"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.Investigation", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationPerson(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Person represents a user profile with basic information", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "uid": { + SchemaProps: spec.SchemaProps{ + Description: "Unique identifier for the user", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Display name of the user", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "gravatarUrl": { + SchemaProps: spec.SchemaProps{ + Description: "URL to user's Gravatar image", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"uid", "name", "gravatarUrl"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationQuery(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Query represents a data query", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "refId": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "queryType": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "editorMode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "supportingQueryType": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "legendFormat": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "expr": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"refId", "queryType", "editorMode", "supportingQueryType", "legendFormat", "expr"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "spec is the schema of our resource", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "title": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "createdByProfile": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson"), + }, + }, + "hasCustomName": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "isFavorite": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "overviewNote": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "overviewNoteUpdatedAt": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "collectables": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable"), + }, + }, + }, + }, + }, + "viewMode": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode"), + }, + }, + }, + Required: []string{"title", "createdByProfile", "hasCustomName", "isFavorite", "overviewNote", "overviewNoteUpdatedAt", "collectables", "viewMode"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationCollectable", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationPerson", "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationViewMode"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "operatorStates": { + SchemaProps: spec.SchemaProps{ + Description: "operatorStates is a map of operator ID to operator state evaluations. Any operator which consumes this kind SHOULD add its state evaluation information to this field.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState"), + }, + }, + }, + }, + }, + "additionalFields": { + SchemaProps: spec.SchemaProps{ + Description: "additionalFields is reserved for future use", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationstatusOperatorState"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationTimeRange(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "TimeRange represents a time range with both absolute and relative values", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "from": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "to": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "raw": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw"), + }, + }, + }, + Required: []string{"from", "to", "raw"}, + }, + }, + Dependencies: []string{ + "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1.InvestigationV0alpha1TimeRangeRaw"}, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationV0alpha1TimeRangeRaw(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "from": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "to": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"from", "to"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationViewMode(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "mode": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "showComments": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + "showTooltips": { + SchemaProps: spec.SchemaProps{ + Default: false, + Type: []string{"boolean"}, + Format: "", + }, + }, + }, + Required: []string{"mode", "showComments", "showTooltips"}, + }, + }, + } +} + +func schema_pkg_apis_investigations_v0alpha1_InvestigationstatusOperatorState(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "lastEvaluation": { + SchemaProps: spec.SchemaProps{ + Description: "lastEvaluation is the ResourceVersion last evaluated", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "state": { + SchemaProps: spec.SchemaProps{ + Description: "state describes the state of the lastEvaluation. It is limited to three possible states for machine evaluation.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "descriptiveState": { + SchemaProps: spec.SchemaProps{ + Description: "descriptiveState is an optional more descriptive state field which has no requirements on format", + Type: []string{"string"}, + Format: "", + }, + }, + "details": { + SchemaProps: spec.SchemaProps{ + Description: "details contains any extra information that is operator-specific", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Format: "", + }, + }, + }, + }, + }, + }, + Required: []string{"lastEvaluation", "state"}, + }, + }, + } +} diff --git a/apps/investigations/pkg/apis/investigations_manifest.go b/apps/investigations/pkg/apis/investigations_manifest.go new file mode 100644 index 00000000000..eed596424bc --- /dev/null +++ b/apps/investigations/pkg/apis/investigations_manifest.go @@ -0,0 +1,65 @@ +// +// This file is generated by grafana-app-sdk +// DO NOT EDIT +// + +package apis + +import ( + "encoding/json" + + "github.com/grafana/grafana-app-sdk/app" +) + +var ( + rawSchemaInvestigationv0alpha1 = []byte(`{"spec":{"description":"spec is the schema of our resource","properties":{"collectables":{"items":{"properties":{"createdAt":{"type":"string"},"datasource":{"properties":{"uid":{"type":"string"}},"required":["uid"],"type":"object"},"id":{"type":"string"},"logoPath":{"type":"string"},"note":{"type":"string"},"noteUpdatedAt":{"type":"string"},"origin":{"type":"string"},"queries":{"items":{"properties":{"editorMode":{"type":"string"},"expr":{"type":"string"},"legendFormat":{"type":"string"},"queryType":{"type":"string"},"refId":{"type":"string"},"supportingQueryType":{"type":"string"}},"required":["refId","queryType","editorMode","supportingQueryType","legendFormat","expr"],"type":"object"},"type":"array"},"timeRange":{"properties":{"from":{"type":"string"},"raw":{"properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"],"type":"object"},"to":{"type":"string"}},"required":["from","to","raw"],"type":"object"},"title":{"type":"string"},"type":{"type":"string"},"url":{"type":"string"}},"required":["id","createdAt","title","origin","type","queries","timeRange","datasource","url","note","noteUpdatedAt"],"type":"object"},"type":"array"},"createdByProfile":{"properties":{"gravatarUrl":{"type":"string"},"name":{"type":"string"},"uid":{"type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","collectables","viewMode"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) + versionSchemaInvestigationv0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaInvestigationv0alpha1, &versionSchemaInvestigationv0alpha1) + rawSchemaInvestigationIndexv0alpha1 = []byte(`{"spec":{"properties":{"investigationSummaries":{"description":"Array of investigation summaries","items":{"properties":{"collectableSummaries":{"items":{"properties":{"id":{"type":"string"},"logoPath":{"type":"string"},"origin":{"type":"string"},"title":{"type":"string"}},"required":["id","title","logoPath","origin"],"type":"object"},"type":"array"},"createdByProfile":{"properties":{"gravatarUrl":{"type":"string"},"name":{"type":"string"},"uid":{"type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"hasCustomName":{"type":"boolean"},"isFavorite":{"type":"boolean"},"overviewNote":{"type":"string"},"overviewNoteUpdatedAt":{"type":"string"},"title":{"type":"string"},"viewMode":{"properties":{"mode":{"enum":["compact","full"],"type":"string"},"showComments":{"type":"boolean"},"showTooltips":{"type":"boolean"}},"required":["mode","showComments","showTooltips"],"type":"object"}},"required":["title","createdByProfile","hasCustomName","isFavorite","overviewNote","overviewNoteUpdatedAt","viewMode","collectableSummaries"],"type":"object"},"type":"array"},"owner":{"description":"The Person who owns this investigation index","properties":{"gravatarUrl":{"type":"string"},"name":{"type":"string"},"uid":{"type":"string"}},"required":["uid","name","gravatarUrl"],"type":"object"},"title":{"description":"Title of the index, e.g. 'Favorites' or 'My Investigations'","type":"string"}},"required":["title","owner","investigationSummaries"],"type":"object"},"status":{"properties":{"additionalFields":{"description":"additionalFields is reserved for future use","type":"object","x-kubernetes-preserve-unknown-fields":true},"operatorStates":{"additionalProperties":{"properties":{"descriptiveState":{"description":"descriptiveState is an optional more descriptive state field which has no requirements on format","type":"string"},"details":{"description":"details contains any extra information that is operator-specific","type":"object","x-kubernetes-preserve-unknown-fields":true},"lastEvaluation":{"description":"lastEvaluation is the ResourceVersion last evaluated","type":"string"},"state":{"description":"state describes the state of the lastEvaluation.\nIt is limited to three possible states for machine evaluation.","enum":["success","in_progress","failed"],"type":"string"}},"required":["lastEvaluation","state"],"type":"object"},"description":"operatorStates is a map of operator ID to operator state evaluations.\nAny operator which consumes this kind SHOULD add its state evaluation information to this field.","type":"object"}},"type":"object","x-kubernetes-preserve-unknown-fields":true}}`) + versionSchemaInvestigationIndexv0alpha1 app.VersionSchema + _ = json.Unmarshal(rawSchemaInvestigationIndexv0alpha1, &versionSchemaInvestigationIndexv0alpha1) +) + +var appManifestData = app.ManifestData{ + AppName: "investigations", + Group: "investigations.grafana.app", + Kinds: []app.ManifestKind{ + { + Kind: "Investigation", + Scope: "Namespaced", + Conversion: false, + Versions: []app.ManifestKindVersion{ + { + Name: "v0alpha1", + Schema: &versionSchemaInvestigationv0alpha1, + }, + }, + }, + + { + Kind: "InvestigationIndex", + Scope: "Namespaced", + Conversion: false, + Versions: []app.ManifestKindVersion{ + { + Name: "v0alpha1", + Schema: &versionSchemaInvestigationIndexv0alpha1, + }, + }, + }, + }, +} + +func jsonToMap(j string) map[string]any { + m := make(map[string]any) + json.Unmarshal([]byte(j), &j) + return m +} + +func LocalManifest() app.Manifest { + return app.NewEmbeddedManifest(appManifestData) +} + +func RemoteManifest() app.Manifest { + return app.NewAPIServerManifest("investigations") +} diff --git a/apps/investigation/pkg/app/app.go b/apps/investigations/pkg/app/investigations_app.go similarity index 66% rename from apps/investigation/pkg/app/app.go rename to apps/investigations/pkg/app/investigations_app.go index 539b7241540..8ec35c1ed19 100644 --- a/apps/investigation/pkg/app/app.go +++ b/apps/investigations/pkg/app/investigations_app.go @@ -9,7 +9,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/klog/v2" - investigationv1alpha1 "github.com/grafana/grafana/apps/investigation/pkg/apis/investigation/v1alpha1" + investigationsv0alpha1 "github.com/grafana/grafana/apps/investigations/pkg/apis/investigations/v0alpha1" ) func New(cfg app.Config) (app.App, error) { @@ -24,7 +24,10 @@ func New(cfg app.Config) (app.App, error) { }, ManagedKinds: []simple.AppManagedKind{ { - Kind: investigationv1alpha1.InvestigationKind(), + Kind: investigationsv0alpha1.InvestigationKind(), + }, + { + Kind: investigationsv0alpha1.InvestigationIndexKind(), }, }, } @@ -44,10 +47,13 @@ func New(cfg app.Config) (app.App, error) { func GetKinds() map[schema.GroupVersion][]resource.Kind { gv := schema.GroupVersion{ - Group: investigationv1alpha1.InvestigationKind().Group(), - Version: investigationv1alpha1.InvestigationKind().Version(), + Group: investigationsv0alpha1.InvestigationKind().Group(), + Version: investigationsv0alpha1.InvestigationKind().Version(), } return map[schema.GroupVersion][]resource.Kind{ - gv: {investigationv1alpha1.InvestigationKind()}, + gv: { + investigationsv0alpha1.InvestigationKind(), + investigationsv0alpha1.InvestigationIndexKind(), + }, } } diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts b/apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts new file mode 100644 index 00000000000..b355ebaca05 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigation/v0alpha1/investigation_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface Investigation { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.metadata.gen.ts b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..c2a128284bc --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.spec.gen.ts @@ -0,0 +1,132 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// Person represents a user profile with basic information +export interface Person { + // Unique identifier for the user + uid: string; + // Display name of the user + name: string; + // URL to user's Gravatar image + gravatarUrl: string; +} + +export const defaultPerson = (): Person => ({ + uid: "", + name: "", + gravatarUrl: "", +}); + +// Collectable represents an item collected during investigation +export interface Collectable { + id: string; + createdAt: string; + title: string; + origin: string; + type: string; + // +listType=atomic + queries: Query[]; + timeRange: TimeRange; + datasource: DatasourceRef; + url: string; + logoPath?: string; + note: string; + noteUpdatedAt: string; +} + +export const defaultCollectable = (): Collectable => ({ + id: "", + createdAt: "", + title: "", + origin: "", + type: "", + queries: [], + timeRange: defaultTimeRange(), + datasource: defaultDatasourceRef(), + url: "", + note: "", + noteUpdatedAt: "", +}); + +// Query represents a data query +export interface Query { + refId: string; + queryType: string; + editorMode: string; + supportingQueryType: string; + legendFormat: string; + expr: string; +} + +export const defaultQuery = (): Query => ({ + refId: "", + queryType: "", + editorMode: "", + supportingQueryType: "", + legendFormat: "", + expr: "", +}); + +// TimeRange represents a time range with both absolute and relative values +export interface TimeRange { + from: string; + to: string; + raw: { + from: string; + to: string; + }; +} + +export const defaultTimeRange = (): TimeRange => ({ + from: "", + to: "", + raw: { + from: "", + to: "", +}, +}); + +// DatasourceRef is a reference to a datasource +export interface DatasourceRef { + uid: string; +} + +export const defaultDatasourceRef = (): DatasourceRef => ({ + uid: "", +}); + +export interface ViewMode { + mode: "compact" | "full"; + showComments: boolean; + showTooltips: boolean; +} + +export const defaultViewMode = (): ViewMode => ({ + mode: "compact", + showComments: false, + showTooltips: false, +}); + +// spec is the schema of our resource +export interface Spec { + title: string; + createdByProfile: Person; + hasCustomName: boolean; + isFavorite: boolean; + overviewNote: string; + overviewNoteUpdatedAt: string; + // +listType=atomic + collectables: Collectable[]; + viewMode: ViewMode; +} + +export const defaultSpec = (): Spec => ({ + title: "", + createdByProfile: defaultPerson(), + hasCustomName: false, + isFavorite: false, + overviewNote: "", + overviewNoteUpdatedAt: "", + collectables: [], + viewMode: defaultViewMode(), +}); + diff --git a/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.status.gen.ts b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.status.gen.ts new file mode 100644 index 00000000000..01be8df7961 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigation/v0alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface OperatorState { + // lastEvaluation is the ResourceVersion last evaluated + lastEvaluation: string; + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + state: "success" | "in_progress" | "failed"; + // descriptiveState is an optional more descriptive state field which has no requirements on format + descriptiveState?: string; + // details contains any extra information that is operator-specific + details?: Record; +} + +export const defaultOperatorState = (): OperatorState => ({ + lastEvaluation: "", + state: "success", +}); + +export interface Status { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + operatorStates?: Record; + // additionalFields is reserved for future use + additionalFields?: Record; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts new file mode 100644 index 00000000000..399b25f3878 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/investigationindex_object_gen.ts @@ -0,0 +1,49 @@ +/* + * This file was generated by grafana-app-sdk. DO NOT EDIT. + */ +import { Spec } from './types.spec.gen'; +import { Status } from './types.status.gen'; + +export interface Metadata { + name: string; + namespace: string; + generateName?: string; + selfLink?: string; + uid?: string; + resourceVersion?: string; + generation?: number; + creationTimestamp?: string; + deletionTimestamp?: string; + deletionGracePeriodSeconds?: number; + labels?: Record; + annotations?: Record; + ownerReferences?: OwnerReference[]; + finalizers?: string[]; + managedFields?: ManagedFieldsEntry[]; +} + +export interface OwnerReference { + apiVersion: string; + kind: string; + name: string; + uid: string; + controller?: boolean; + blockOwnerDeletion?: boolean; +} + +export interface ManagedFieldsEntry { + manager?: string; + operation?: string; + apiVersion?: string; + time?: string; + fieldsType?: string; + subresource?: string; +} + +export interface InvestigationIndex { + kind: string; + apiVersion: string; + metadata: Metadata; + spec: Spec; + status: Status; +} diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.metadata.gen.ts b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.metadata.gen.ts new file mode 100644 index 00000000000..4377f3c1d08 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.metadata.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// metadata contains embedded CommonMetadata and can be extended with custom string fields +// TODO: use CommonMetadata instead of redefining here; currently needs to be defined here +// without external reference as using the CommonMetadata reference breaks thema codegen. +export interface Metadata { + updateTimestamp: string; + createdBy: string; + uid: string; + creationTimestamp: string; + deletionTimestamp?: string; + finalizers: string[]; + resourceVersion: string; + generation: number; + updatedBy: string; + labels: Record; +} + +export const defaultMetadata = (): Metadata => ({ + updateTimestamp: "", + createdBy: "", + uid: "", + creationTimestamp: "", + finalizers: [], + resourceVersion: "", + generation: 0, + updatedBy: "", + labels: {}, +}); + diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts new file mode 100644 index 00000000000..f0d2f25d96b --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.spec.gen.ts @@ -0,0 +1,84 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +// Person represents a user profile with basic information +export interface Person { + // Unique identifier for the user + uid: string; + // Display name of the user + name: string; + // URL to user's Gravatar image + gravatarUrl: string; +} + +export const defaultPerson = (): Person => ({ + uid: "", + name: "", + gravatarUrl: "", +}); + +// Type definition for investigation summaries +export interface InvestigationSummary { + title: string; + createdByProfile: Person; + hasCustomName: boolean; + isFavorite: boolean; + overviewNote: string; + overviewNoteUpdatedAt: string; + viewMode: ViewMode; + // +listType=atomic + collectableSummaries: CollectableSummary[]; +} + +export const defaultInvestigationSummary = (): InvestigationSummary => ({ + title: "", + createdByProfile: defaultPerson(), + hasCustomName: false, + isFavorite: false, + overviewNote: "", + overviewNoteUpdatedAt: "", + viewMode: defaultViewMode(), + collectableSummaries: [], +}); + +export interface ViewMode { + mode: "compact" | "full"; + showComments: boolean; + showTooltips: boolean; +} + +export const defaultViewMode = (): ViewMode => ({ + mode: "compact", + showComments: false, + showTooltips: false, +}); + +export interface CollectableSummary { + id: string; + title: string; + logoPath: string; + origin: string; +} + +export const defaultCollectableSummary = (): CollectableSummary => ({ + id: "", + title: "", + logoPath: "", + origin: "", +}); + +export interface Spec { + // Title of the index, e.g. 'Favorites' or 'My Investigations' + title: string; + // The Person who owns this investigation index + owner: Person; + // Array of investigation summaries + // +listType=atomic + investigationSummaries: InvestigationSummary[]; +} + +export const defaultSpec = (): Spec => ({ + title: "", + owner: defaultPerson(), + investigationSummaries: [], +}); + diff --git a/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.status.gen.ts b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.status.gen.ts new file mode 100644 index 00000000000..01be8df7961 --- /dev/null +++ b/apps/investigations/plugin/src/generated/investigationindex/v0alpha1/types.status.gen.ts @@ -0,0 +1,30 @@ +// Code generated - EDITING IS FUTILE. DO NOT EDIT. + +export interface OperatorState { + // lastEvaluation is the ResourceVersion last evaluated + lastEvaluation: string; + // state describes the state of the lastEvaluation. + // It is limited to three possible states for machine evaluation. + state: "success" | "in_progress" | "failed"; + // descriptiveState is an optional more descriptive state field which has no requirements on format + descriptiveState?: string; + // details contains any extra information that is operator-specific + details?: Record; +} + +export const defaultOperatorState = (): OperatorState => ({ + lastEvaluation: "", + state: "success", +}); + +export interface Status { + // operatorStates is a map of operator ID to operator state evaluations. + // Any operator which consumes this kind SHOULD add its state evaluation information to this field. + operatorStates?: Record; + // additionalFields is reserved for future use + additionalFields?: Record; +} + +export const defaultStatus = (): Status => ({ +}); + diff --git a/apps/playlist/Makefile b/apps/playlist/Makefile index 926f5a2840f..7a5f1c99365 100644 --- a/apps/playlist/Makefile +++ b/apps/playlist/Makefile @@ -1,8 +1,3 @@ .PHONY: generate generate: - @grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess - # HACK: Clean up generated CRD files. - # TODO: The SDK currently omits generating the manifest Go file with `--defencoding=none`, - # which we would normally use here to skip generating the CRD files. - # This needs to be addressed. - @rm -rf definitions + @grafana-app-sdk generate -g ./pkg/apis --grouping=group --postprocess --defencoding=none diff --git a/apps/playlist/go.mod b/apps/playlist/go.mod index f7304ea395c..6214b9ae328 100644 --- a/apps/playlist/go.mod +++ b/apps/playlist/go.mod @@ -1,11 +1,11 @@ module github.com/grafana/grafana/apps/playlist -go 1.23.4 +go 1.23.7 require ( - github.com/grafana/grafana-app-sdk v0.30.0 - k8s.io/apimachinery v0.32.0 - k8s.io/client-go v0.32.0 + github.com/grafana/grafana-app-sdk v0.31.0 + k8s.io/apimachinery v0.32.1 + k8s.io/client-go v0.32.1 k8s.io/klog/v2 v2.130.1 k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f ) @@ -19,7 +19,7 @@ require ( github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.6.0+incompatible // indirect github.com/fxamacker/cbor/v2 v2.7.0 // indirect - github.com/getkin/kin-openapi v0.128.0 // indirect + github.com/getkin/kin-openapi v0.129.0 // indirect github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect @@ -28,15 +28,14 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/gofuzz v1.2.0 // indirect github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect github.com/google/uuid v1.6.0 // indirect - github.com/grafana/grafana-app-sdk/logging v0.29.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 // indirect + github.com/grafana/grafana-app-sdk/logging v0.30.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/invopop/yaml v0.3.1 // indirect github.com/josharian/intern v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/klauspost/compress v1.17.11 // indirect @@ -45,39 +44,43 @@ require ( github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 // indirect + github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 // indirect + github.com/onsi/ginkgo/v2 v2.22.0 // indirect + github.com/onsi/gomega v1.36.1 // indirect github.com/perimeterx/marshmallow v1.1.5 // indirect - github.com/prometheus/client_golang v1.20.5 // indirect + github.com/prometheus/client_golang v1.21.0 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.61.0 // indirect + github.com/prometheus/common v0.62.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect github.com/puzpuzpuz/xsync/v2 v2.5.1 // indirect - github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/pflag v1.0.6 // indirect github.com/x448/float16 v0.8.4 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect - go.opentelemetry.io/otel v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 // indirect - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 // indirect - go.opentelemetry.io/otel/metric v1.33.0 // indirect - go.opentelemetry.io/otel/sdk v1.33.0 // indirect - go.opentelemetry.io/otel/trace v1.33.0 // indirect + go.opentelemetry.io/otel v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 // indirect + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect + go.opentelemetry.io/otel/metric v1.34.0 // indirect + go.opentelemetry.io/otel/sdk v1.34.0 // indirect + go.opentelemetry.io/otel/trace v1.34.0 // indirect go.opentelemetry.io/proto/otlp v1.5.0 // indirect - golang.org/x/net v0.34.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.29.0 // indirect - golang.org/x/term v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/net v0.36.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sync v0.11.0 // indirect + golang.org/x/sys v0.30.0 // indirect + golang.org/x/term v0.29.0 // indirect + golang.org/x/text v0.22.0 // indirect golang.org/x/time v0.9.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d // indirect - google.golang.org/grpc v1.69.4 // indirect - google.golang.org/protobuf v1.36.1 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 // indirect + google.golang.org/grpc v1.70.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.32.0 // indirect - k8s.io/apiextensions-apiserver v0.32.0 // indirect + k8s.io/api v0.32.1 // indirect + k8s.io/apiextensions-apiserver v0.32.1 // indirect k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect sigs.k8s.io/structured-merge-diff/v4 v4.5.0 // indirect diff --git a/apps/playlist/go.sum b/apps/playlist/go.sum index 858c73dd4b4..88d0fa45e79 100644 --- a/apps/playlist/go.sum +++ b/apps/playlist/go.sum @@ -16,8 +16,8 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= -github.com/getkin/kin-openapi v0.128.0 h1:jqq3D9vC9pPq1dGcOCv7yOp1DaEe7c/T1vzcLbITSp4= -github.com/getkin/kin-openapi v0.128.0/go.mod h1:OZrfXzUfGrNbsKj+xmFBx6E5c6yH3At/tAKSc2UszXM= +github.com/getkin/kin-openapi v0.129.0 h1:QGYTNcmyP5X0AtFQ2Dkou9DGBJsUETeLH9rFrJXZh30= +github.com/getkin/kin-openapi v0.129.0/go.mod h1:gmWI+b/J45xqpyK5wJmRRZse5wefA5H0RDMK46kLUtI= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= @@ -40,8 +40,8 @@ github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6 github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -49,19 +49,17 @@ github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/Z github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/grafana/grafana-app-sdk v0.30.0 h1:Hqn2pETu2mQ4RpWkZYEQfu01P7xd1Z1Gj+HX/8aB0tw= -github.com/grafana/grafana-app-sdk v0.30.0/go.mod h1:jhfqNIovb+Mes2vdMf9iMCWQkp1GTNtyNuExONtiNuk= -github.com/grafana/grafana-app-sdk/logging v0.29.0 h1:mgbXaAf33aFwqwGVeaX30l8rkeAJH0iACgX5Rn6YkN4= -github.com/grafana/grafana-app-sdk/logging v0.29.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1 h1:VNqngBF40hVlDloBruUehVYC3ArSgIyScOAyMRqBxRg= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.25.1/go.mod h1:RBRO7fro65R6tjKzYgLAFo0t1QEXY1Dp+i/bvpRiqiQ= +github.com/grafana/grafana-app-sdk v0.31.0 h1:/mFCcx+YqG8cWAi9hePDJQxIdtXDClDIDRgZwHkksFk= +github.com/grafana/grafana-app-sdk v0.31.0/go.mod h1:Xw00NL7qpRLo5r3Gn48Bl1Xn2n4eUDI5pYf/wMufKWs= +github.com/grafana/grafana-app-sdk/logging v0.30.0 h1:K/P/bm7Cp7Di4tqIJ3EQz2+842JozQGRaz62r95ApME= +github.com/grafana/grafana-app-sdk/logging v0.30.0/go.mod h1:xy6ZyVXl50Z3DBDLybvBPphbykPhuVNed/VNmen9DQM= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 h1:e9Rjr40Z98/clHv5Yg79Is0NtosR5LXRvdr7o/6NwbA= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1/go.mod h1:tIxuGz/9mpox++sgp9fJjHO0+q1X9/UOWd798aAm22M= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/invopop/yaml v0.3.1 h1:f0+ZpmhfBSS4MhG+4HYseMdJhoeeopbSKbq5Rpeelso= -github.com/invopop/yaml v0.3.1/go.mod h1:PMOp3nn4/12yEZUFfmOuNHJsZToEEOwoWsT+D81KkeA= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= @@ -87,10 +85,14 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= -github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= -github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= -github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80 h1:nZspmSkneBbtxU9TopEAE0CY+SBJLxO8LPUlw2vG4pU= +github.com/oasdiff/yaml v0.0.0-20241210131133-6b86fb107d80/go.mod h1:7tFDb+Y51LcDpn26GccuUgQXUk6t0CXZsivKjyimYX8= +github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+7OIuqDwXbhl32HiZGpLy26BAPc= +github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o= +github.com/onsi/ginkgo/v2 v2.22.0 h1:Yed107/8DjTr0lKCNt7Dn8yQ6ybuDRQoMGrNFKzMfHg= +github.com/onsi/ginkgo/v2 v2.22.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.36.1 h1:bJDPBO7ibjxcbHMgSCoo4Yj18UWbKDlLwX1x9sybDcw= +github.com/onsi/gomega v1.36.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= github.com/perimeterx/marshmallow v1.1.5 h1:a2LALqQ1BlHM8PZblsDdidgv1mWi1DgC2UmX50IvK2s= github.com/perimeterx/marshmallow v1.1.5/go.mod h1:dsXbUu8CRzfYP5a87xpp0xq9S3u0Vchtcl8we9tYaXw= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -98,20 +100,20 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= -github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= +github.com/prometheus/client_golang v1.21.0 h1:DIsaGmiaBkSangBgMtWdNfxbMNdku5IK6iNhrEqWvdA= +github.com/prometheus/client_golang v1.21.0/go.mod h1:U9NM32ykUErtVBxdvD3zfi+EuFkkaBvMb09mIfe0Zgg= github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= -github.com/prometheus/common v0.61.0 h1:3gv/GThfX0cV2lpO7gkTUwZru38mxevy90Bj8YFSRQQ= -github.com/prometheus/common v0.61.0/go.mod h1:zr29OCN/2BsJRaFwG8QOBr41D6kkchKbpeNH7pAjb/s= +github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ2Io= +github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I= github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/puzpuzpuz/xsync/v2 v2.5.1 h1:mVGYAvzDSu52+zaGyNjC+24Xw2bQi3kTr4QJ6N9pIIU= github.com/puzpuzpuz/xsync/v2 v2.5.1/go.mod h1:gD2H2krq/w52MfPLE+Uy64TzJDVY7lP2znR9qmR35kU= github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= -github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= @@ -124,22 +126,22 @@ github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= -go.opentelemetry.io/otel v1.33.0 h1:/FerN9bax5LoK51X/sI0SVYrjSE0/yUL7DpxW4K3FWw= -go.opentelemetry.io/otel v1.33.0/go.mod h1:SUUkR6csvUQl+yjReHu5uM3EtVV7MBm5FHKRlNx4I8I= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0 h1:Vh5HayB/0HHfOQA7Ctx69E/Y/DcQSMPpKANYVMQ7fBA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.33.0/go.mod h1:cpgtDBaqD/6ok/UG0jT15/uKjAY8mRA53diogHBg3UI= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0 h1:5pojmb1U1AogINhN3SurB+zm/nIcusopeBNp42f45QM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.33.0/go.mod h1:57gTHJSE5S1tqg+EKsLPlTWhpHMsWlVmer+LA926XiA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0 h1:wpMfgF8E1rkrT1Z6meFh1NDtownE9Ii3n3X2GJYjsaU= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.33.0/go.mod h1:wAy0T/dUbs468uOlkT31xjvqQgEVXv58BRFWEgn5v/0= -go.opentelemetry.io/otel/metric v1.33.0 h1:r+JOocAyeRVXD8lZpjdQjzMadVZp2M4WmQ+5WtEnklQ= -go.opentelemetry.io/otel/metric v1.33.0/go.mod h1:L9+Fyctbp6HFTddIxClbQkjtubW6O9QS3Ann/M82u6M= -go.opentelemetry.io/otel/sdk v1.33.0 h1:iax7M131HuAm9QkZotNHEfstof92xM+N8sr3uHXc2IM= -go.opentelemetry.io/otel/sdk v1.33.0/go.mod h1:A1Q5oi7/9XaMlIWzPSxLRWOI8nG3FnzHJNbiENQuihM= -go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= -go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/trace v1.33.0 h1:cCJuF7LRjUFso9LPnEAHJDB2pqzp+hbO8eu1qqW2d/s= -go.opentelemetry.io/otel/trace v1.33.0/go.mod h1:uIcdVUZMpTAmz0tI1z04GoVSezK37CbGV4fr1f2nBck= +go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY= +go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 h1:OeNbIYk/2C15ckl7glBlOBp5+WlYsOElzTNmiPW/x60= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0/go.mod h1:7Bept48yIeqxP2OZ9/AqIpYS94h2or0aB4FypJTc8ZM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0 h1:tgJ0uaNS4c98WRNUEx5U3aDlrDOI5Rs+1Vifcw4DJ8U= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.34.0/go.mod h1:U7HYyW0zt/a9x5J1Kjs+r1f/d4ZHnYFclhYY2+YbeoE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 h1:BEj3SPM81McUZHYjRS5pEgNgnmzGJ5tRpU5krWnV8Bs= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0/go.mod h1:9cKLGBDzI/F3NoHLQGm4ZrYdIHsvGt6ej6hUowxY0J4= +go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ= +go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE= +go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A= +go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU= +go.opentelemetry.io/otel/sdk/metric v1.32.0 h1:rZvFnvmvawYb0alrYkjraqJq0Z4ZUJAiyYCU9snn1CU= +go.opentelemetry.io/otel/sdk/metric v1.32.0/go.mod h1:PWeZlq0zt9YkYAp3gjKZ0eicRYvOh1Gd+X99x6GHpCQ= +go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k= +go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE= go.opentelemetry.io/proto/otlp v1.5.0 h1:xJvq7gMzB31/d406fB8U5CBdyQGw4P399D1aQWU/3i4= go.opentelemetry.io/proto/otlp v1.5.0/go.mod h1:keN8WnHxOy8PG0rQZjJJ5A2ebUoafqWp0eVQ4yIXvJ4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -153,26 +155,26 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= -golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= -golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/net v0.36.0 h1:vWF2fRbw4qslQsQzgFqZff+BItCvGFQqKzKIzx1rmoA= +golang.org/x/net v0.36.0/go.mod h1:bFmbeoIPfrw4sMHNhb4J9f6+tPziuGjq7Jk/38fxi1I= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= -golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg= -golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -187,14 +189,14 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d h1:H8tOf8XM88HvKqLTxe755haY6r1fqqzLbEnfrmLXlSA= -google.golang.org/genproto/googleapis/api v0.0.0-20250102185135-69823020774d/go.mod h1:2v7Z7gP2ZUOGsaFyxATQSRoBnKygqVq2Cwnvom7QiqY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d h1:xJJRGY7TJcvIlpSrN3K6LAWgNFUILlO+OMAqtg9aqnw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250102185135-69823020774d/go.mod h1:3ENsm/5D1mzDyhpzeRi1NR784I0BcofWBoSc5QqqMK4= -google.golang.org/grpc v1.69.4 h1:MF5TftSMkd8GLw/m0KM6V8CMOCY6NZ1NQDPGFgbTt4A= -google.golang.org/grpc v1.69.4/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= -google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk= -google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489 h1:fCuMM4fowGzigT89NCIsW57Pk9k2D12MMi2ODn+Nk+o= +google.golang.org/genproto/googleapis/api v0.0.0-20250204164813-702378808489/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6 h1:2duwAxN2+k0xLNpjnHTXoMUgnv6VPSp5fiqTuwSxjmI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250207221924-e9438ea467c6/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= +google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= +google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -204,14 +206,14 @@ gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.32.0 h1:OL9JpbvAU5ny9ga2fb24X8H6xQlVp+aJMFlgtQjR9CE= -k8s.io/api v0.32.0/go.mod h1:4LEwHZEf6Q/cG96F3dqR965sYOfmPM7rq81BLgsE0p0= -k8s.io/apiextensions-apiserver v0.32.0 h1:S0Xlqt51qzzqjKPxfgX1xh4HBZE+p8KKBq+k2SWNOE0= -k8s.io/apiextensions-apiserver v0.32.0/go.mod h1:86hblMvN5yxMvZrZFX2OhIHAuFIMJIZ19bTvzkP+Fmw= -k8s.io/apimachinery v0.32.0 h1:cFSE7N3rmEEtv4ei5X6DaJPHHX0C+upp+v5lVPiEwpg= -k8s.io/apimachinery v0.32.0/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= -k8s.io/client-go v0.32.0 h1:DimtMcnN/JIKZcrSrstiwvvZvLjG0aSxy8PxN8IChp8= -k8s.io/client-go v0.32.0/go.mod h1:boDWvdM1Drk4NJj/VddSLnx59X3OPgwrOo0vGbtq9+8= +k8s.io/api v0.32.1 h1:f562zw9cy+GvXzXf0CKlVQ7yHJVYzLfL6JAS4kOAaOc= +k8s.io/api v0.32.1/go.mod h1:/Yi/BqkuueW1BgpoePYBRdDYfjPF5sgTr5+YqDZra5k= +k8s.io/apiextensions-apiserver v0.32.1 h1:hjkALhRUeCariC8DiVmb5jj0VjIc1N0DREP32+6UXZw= +k8s.io/apiextensions-apiserver v0.32.1/go.mod h1:sxWIGuGiYov7Io1fAS2X06NjMIk5CbRHc2StSmbaQto= +k8s.io/apimachinery v0.32.1 h1:683ENpaCBjma4CYqsmZyhEzrGz6cjn1MY/X2jB2hkZs= +k8s.io/apimachinery v0.32.1/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE= +k8s.io/client-go v0.32.1 h1:otM0AxdhdBIaQh7l1Q0jQpmo7WOFIk5FFa4bg6YMdUU= +k8s.io/client-go v0.32.1/go.mod h1:aTTKZY7MdxUaJ/KiUs8D+GssR9zJZi77ZqtzcGXIiDg= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f h1:GA7//TjRY9yWGy1poLzYYJJ4JRdzg3+O6e8I+e+8T5Y= diff --git a/conf/defaults.ini b/conf/defaults.ini index 91e7af25442..a216bb0792a 100644 --- a/conf/defaults.ini +++ b/conf/defaults.ini @@ -130,6 +130,13 @@ password = # Example: mysql://user:secret@host:port/database url = +# Set to true or false to enable or disable high availability mode. +# When it's set to false some functions will be simplified and only run in-process +# instead of relying on the database. +# +# Only set it to false if you run only a single instance of Grafana. +high_availability = true + # Max idle conn setting default is 2 max_idle_conn = 2 @@ -354,6 +361,9 @@ disable_brute_force_login_protection = false # max number of failed login attempts before user gets locked brute_force_login_protection_max_attempts = 5 +# disable protection against brute force login attempts by IP address +disable_ip_address_login_protection = true + # set to true if you host Grafana behind HTTPS. default is false. cookie_secure = false @@ -452,6 +462,9 @@ min_refresh_interval = 5s # Path to the default home dashboard. If this value is empty, then Grafana uses StaticRootPath + "dashboards/home.json" default_home_dashboard_path = +# Dashboards UIDs to report performance metrics for. * can be used to report metrics for all dashboards +dashboard_performance_metrics = + ################################### Data sources ######################### [datasources] # Upper limit of data sources that Grafana will return. This limit is a temporary configuration and it will be deprecated when pagination will be introduced on the list data sources API. @@ -521,9 +534,11 @@ external_manage_link_url = external_manage_link_name = external_manage_info = +# Deprecated: Assign your viewers to editors. # Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard. viewers_can_edit = false +# Deprecated: Assign your editors to admins. # Editors can administrate dashboard, folders and teams they create editors_can_admin = false @@ -922,6 +937,7 @@ auto_sign_up = false url_login = false allow_assign_grafana_admin = false skip_org_role_sync = false +tls_skip_verify_insecure = false #################################### Auth LDAP ########################### [auth.ldap] @@ -1013,6 +1029,10 @@ user_identity_fallback_credentials_enabled = true # By default is the same as token URL configured for AAD authentication settings user_identity_token_url = +# Override client authentication method for Azure Active Directory +# By default is the same as client authentication method configured for AAD authentication settings +user_identity_client_authentication = + # Override ADD application ID which would be used to exchange users token to an access token for the datasource # By default is the same as used in AAD authentication or can be set to another application (for OBO flow) user_identity_client_id = @@ -1021,6 +1041,14 @@ user_identity_client_id = # By default is the same as used in AAD authentication or can be set to another application (for OBO flow) user_identity_client_secret = +# Override the AAD managed identity client ID +# By default is the same as used in AAD authentication or can be set to another managed identity (for OBO flow) +user_identity_managed_identity_client_id = + +# Override the AAD federated credential audience +# By default is the same as used in AAD authentication or can be set to another audience (for OBO flow) +user_identity_federated_credential_audience = + # Allows the usage of a custom token request assertion when Grafana is behind an authentication proxy # In most cases this will not need to be used. To enable this set the value to "username" # The default is empty and any other value will not enable this functionality @@ -1495,6 +1523,13 @@ basic_auth_password = # Request timeout for recording rule writes. timeout = 10s +# Default data source UID to write to if not specified in the rule definition. +# Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled. +default_datasource_uid = + +# Suffix to apply to the data source URL for remote write requests. +remote_write_path_suffix = /push + # Optional custom headers to include in recording rule write requests. [recording_rules.custom_headers] # exampleHeader = exampleValue @@ -1559,6 +1594,9 @@ enabled = true # set the default offset for the time picker defaultTimeOffset = 1h +# hides the download logs button in Explore +hide_logs_download = false + #################################### Help ############################# [help] # Enable the Help section @@ -1723,6 +1761,7 @@ sas_token_expiration_days = # URL to a remote HTTP image renderer service, e.g. http://localhost:8081/render, will enable Grafana to render panels and dashboards to PNG-images using HTTP requests to an external service. server_url = # If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, e.g. http://grafana.domain/. +# The `callback_url` can also be configured to support usage of the image renderer running as a plugin with support for SSL / HTTPS. For example https://localhost:3000/. callback_url = # An auth token that will be sent to and verified by the renderer. The renderer will deny any request without an auth token matching the one configured on the renderer side. renderer_token = - @@ -1785,6 +1824,10 @@ preinstall_disabled = false # tuning. 0 disables Live, -1 means unlimited connections. max_connections = 100 +# message_size_limit is the maximum size in bytes of Websocket messages from clients. Defaults to 64KB. +# The limit can be disabled by setting it to -1. +message_size_limit = 65536 + # allowed_origins is a comma-separated list of origins that can establish connection with Grafana Live. # If not set then origin will be matched over root_url. Supports wildcard symbol "*". allowed_origins = @@ -1839,6 +1882,9 @@ rendering_dumpio = # This can be useful to enable (true) when optimizing the rendering mode settings to improve the plugin performance or when troubleshooting. rendering_timing_metrics = +# This is a configuration for OTLP exporter with HTTP protocol, set this URL to enable tracing (ex: http://localhost:4318/v1/traces). Default to empty (tracing disabled). +rendering_tracing_url = + # Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found # here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character. rendering_args = @@ -1892,6 +1938,15 @@ enable = # feature1 = true # feature2 = false +[feature_toggles.openfeature] +# This is EXPERIMENTAL. Please, do not use this section +provider = static + +[feature_toggles.openfeature.context] +# This is EXPERIMENTAL. Please, do not use this section +# instance = "grafana" +# version = 11.0.0 + [date_formats] # For information on what formatting patterns that are supported https://momentjs.com/docs/#/displaying/ diff --git a/conf/sample.ini b/conf/sample.ini index d1a06d9c331..21ef0ad88c6 100644 --- a/conf/sample.ini +++ b/conf/sample.ini @@ -129,6 +129,13 @@ # Example: mysql://user:secret@host:port/database ;url = +# Set to true or false to enable or disable high availability mode. +# When it's set to false some functions will be simplified and only run in-process +# instead of relying on the database. +# +# Only set it to false if you run only a single instance of Grafana. +;high_availability = true + # Max idle conn setting default is 2 ;max_idle_conn = 2 @@ -353,6 +360,9 @@ # max number of failed login attempts before user gets locked ;brute_force_login_protection_max_attempts = 5 +# disable protection against brute force login attempts by IP address +; disable_ip_address_login_protection = true + # set to true if you host Grafana behind HTTPS. default is false. ;cookie_secure = false @@ -525,9 +535,12 @@ ;external_manage_link_name = ;external_manage_info = + +# Deprecated: Assign your viewers to editors. # Viewers can edit/inspect dashboard settings in the browser. But not save the dashboard. ;viewers_can_edit = false +# Deprecated: Assign your editors to admins. # Editors can administrate dashboard, folders and teams they create ;editors_can_admin = false @@ -894,6 +907,7 @@ ;allow_assign_grafana_admin = false ;skip_org_role_sync = false ;signout_redirect_url = +;tls_skip_verify_insecure = false #################################### Auth LDAP ########################## [auth.ldap] @@ -998,6 +1012,10 @@ # By default is the same as token URL configured for AAD authentication settings ;user_identity_token_url = +# Override client authentication method for Azure Active Directory +# By default is the same as client authentication method configured for AAD authentication settings +;user_identity_client_authentication = + # Override ADD application ID which would be used to exchange users token to an access token for the datasource # By default is the same as used in AAD authentication or can be set to another application (for OBO flow) ;user_identity_client_id = @@ -1006,6 +1024,14 @@ # By default is the same as used in AAD authentication or can be set to another application (for OBO flow) ;user_identity_client_secret = +# Override the AAD managed identity client ID +# By default is the same as used in AAD authentication or can be set to another managed identity (for OBO flow) +;user_identity_managed_identity_client_id = + +# Override the AAD federated credential audience +# By default is the same as used in AAD authentication or can be set to another audience (for OBO flow) +;user_identity_federated_credential_audience = + # Allows the usage of a custom token request assertion when Grafana is behind an authentication proxy # In most cases this will not need to be used. To enable this set the value to "username" # The default is empty and any other value will not enable this functionality @@ -1391,12 +1417,6 @@ # For example: `disabled_labels=grafana_folder` disabled_labels = - -[unified_alerting.reserved_labels] -# Comma-separated list of reserved labels added by the Grafana Alerting engine that should be disabled. -# For example: `disabled_labels=grafana_folder` -;disabled_labels = - [unified_alerting.state_history] # Enable the state history functionality in Unified Alerting. The previous states of alert rules will be visible in panels and in the UI. ; enabled = true @@ -1485,6 +1505,13 @@ basic_auth_password = # Request timeout for recording rule writes. timeout = 30s +# Default data source UID to write to if not specified in the rule definition. +# Only has effect if the grafanaManagedRecordRulesDatasources feature toggle is enabled. +default_datasource_uid = + +# Suffix to apply to the data source URL for remote write requests. +remote_write_path_suffix = /push + # Optional custom headers to include in recording rule write requests. [recording_rules.custom_headers] # exampleHeader = exampleValue @@ -1789,6 +1816,9 @@ timeout = 30s # This can be useful to enable (true) when optimizing the rendering mode settings to improve the plugin performance or when troubleshooting. ;rendering_timing_metrics = +# This is a configuration for OTLP exporter with HTTP protocol, set this URL to enable tracing (ex: http://localhost:4318/v1/traces). Default to empty (tracing disabled). +;rendering_tracing_url = + # Additional arguments to pass to the headless browser instance. Default is --no-sandbox. The list of Chromium flags can be found # here (https://peter.sh/experiments/chromium-command-line-switches/). Multiple arguments is separated with comma-character. ;rendering_args = diff --git a/contribute/developer-guide.md b/contribute/developer-guide.md index 9a4d98d8003..da3669615ab 100644 --- a/contribute/developer-guide.md +++ b/contribute/developer-guide.md @@ -318,7 +318,7 @@ Previously, Grafana used Yarn PnP to install frontend dependencies, which requir ### Too many open files when running `make run` -Depending on your environment, you may have to increase the maximum number of open files allowed. For the rest of this section, we will assume you are on a UNIX-like OS (for example, Linux or macOS), where you can control the maximum number of open files through the [ulimit](https://ss64.com/bash/ulimit.html) shell command. +Depending on your environment, you may need to increase the maximum number of open files allowed. For the rest of this section, we will assume you are on a UNIX-like OS (for example, Linux or macOS), where you can control the maximum number of open files through the [ulimit](https://ss64.com/bash/ulimit.html) shell command. To see how many open files are allowed, run: @@ -361,6 +361,58 @@ ulimit: open files: cannot modify limit: Operation not permitted If that happens to you, chances are you've already set a lower limit and your shell won't let you set a higher one. Try looking in your shell initialization files (`~/.bashrc`, typically), to see if there's already an `ulimit` command that you can tweak. +### System limit for number of file watchers reached while running `yarn start` + +Depending on your environment, you may need to increase the number of file watchers allowed by `inotify` package to monitor filesystem changes. You may encounter an error `Error: ENOSPC: System limit for number of file watchers reached` otherwise. + +Edit the system config file to insert the new value for file watchers limit: + +On Linux: + +```bash +echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p +``` + +On macOS: + +```bash +sudo sysctl -w kern.maxfiles=524288 +``` + +Check if the new value was applied. It must output `524288`: + +On Linux: + +```bash +cat /proc/sys/fs/inotify/max_user_watches +``` + +On macOS: + +```bash +sysctl kern.maxfiles +``` + +### JavaScript heap out of memory while running `yarn start` + +Running `yarn start` requires a substantial amount of memory space. You may check the currently allocated heap space to `node` by running the command: + +```bash +node -e 'console.log(v8.getHeapStatistics().heap_size_limit/(1024*1024))' +``` + +Increase the default heap memory to something greater than the currently allocated memory. Make sure the value is a multiple of `1024`. + +```bash +export NODE_OPTIONS="--max-old-space-size=8192" +``` + +Or on Windows: + +``` +Set NODE_OPTIONS="--max-old-space-size=8192" +``` + ### Getting `AggregateError` when building frontend tests If you encounter an `AggregateError` when building new tests, this is probably due to a call to our client [backend service](https://github.com/grafana/grafana/blob/main/public/app/core/services/backend_srv.ts) not being mocked. Our backend service anticipates multiple responses being returned and was built to return errors as an array. A test encountering errors from the service will group those errors as an `AggregateError` without breaking down the individual errors within. `backend_srv.processRequestError` is called once per error and is a great place to return information on what the individual errors might contain. diff --git a/contribute/style-guides/themes.md b/contribute/style-guides/themes.md index 61c01764429..e4608ec55f1 100644 --- a/contribute/style-guides/themes.md +++ b/contribute/style-guides/themes.md @@ -96,11 +96,12 @@ Example use cases: ### Background colors -| Property | When to use | -| --------------------------------- | ------------------------------------------------------------------------------------------------ | -| theme.colors.background.canvas | Dashboard background. A background surface for panels and panes that use primary background | -| theme.colors.background.primary | The default content background for content panes and panels | -| theme.colors.background.secondary | For cards and other surfaces that need to stand out when placed on top of the primary background | +| Property | When to use | +| --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| theme.colors.background.canvas | Dashboard background. A background surface for panels and panes that use primary background | +| theme.colors.background.primary | The default content background for content panes and panels | +| theme.colors.background.secondary | For cards and other surfaces that need to stand out when placed on top of the primary background | +| theme.colors.background.elevated | For popovers and menu backgrounds. This is the same color as primary in most light themes but in dark themes it has a brighter shade to help give it contrast against the primary background | ### Borders diff --git a/devenv/bulk-dashboards/bulkdash.jsonnet b/devenv/bulk-dashboards/bulkdash.jsonnet index 1a77d8abd70..05e396df2d6 100644 --- a/devenv/bulk-dashboards/bulkdash.jsonnet +++ b/devenv/bulk-dashboards/bulkdash.jsonnet @@ -1118,18 +1118,6 @@ "1d" ], "status": "Stable", - "time_options": [ - "5m", - "15m", - "1h", - "2h", - " 6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ], "type": "timepicker" }, "timezone": "browser", diff --git a/devenv/datasources.yaml b/devenv/datasources.yaml index 452d2d3d1bc..00efa243c1c 100644 --- a/devenv/datasources.yaml +++ b/devenv/datasources.yaml @@ -136,6 +136,14 @@ datasources: tsdbResolution: 1 tsdbVersion: 3 + - name: gdev-opentsdb-v2.4 + type: opentsdb + access: proxy + url: http://localhost:4242 + jsonData: + tsdbResolution: 1 + tsdbVersion: 4 + - name: gdev-elasticsearch type: elasticsearch uid: gdev-elasticsearch diff --git a/devenv/dev-dashboards-without-uid/panel_tests_graph.json b/devenv/dev-dashboards-without-uid/panel_tests_graph.json index b5d50f4f7b7..6bba1d9ae02 100644 --- a/devenv/dev-dashboards-without-uid/panel_tests_graph.json +++ b/devenv/dev-dashboards-without-uid/panel_tests_graph.json @@ -1639,8 +1639,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "browser", "title": "Panel Tests - Graph", diff --git a/devenv/dev-dashboards-without-uid/panel_tests_graph_time_regions.json b/devenv/dev-dashboards-without-uid/panel_tests_graph_time_regions.json index 3ff76d12df2..98d49958aaf 100644 --- a/devenv/dev-dashboards-without-uid/panel_tests_graph_time_regions.json +++ b/devenv/dev-dashboards-without-uid/panel_tests_graph_time_regions.json @@ -490,17 +490,6 @@ "1h", "2h", "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" ] }, "timezone": "browser", diff --git a/devenv/dev-dashboards-without-uid/panel_tests_polystat.json b/devenv/dev-dashboards-without-uid/panel_tests_polystat.json index 951bb780017..25b1f7154e5 100644 --- a/devenv/dev-dashboards-without-uid/panel_tests_polystat.json +++ b/devenv/dev-dashboards-without-uid/panel_tests_polystat.json @@ -3408,8 +3408,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Polystat", diff --git a/devenv/dev-dashboards/datasource-influxdb/influxdb-templated.json b/devenv/dev-dashboards/datasource-influxdb/influxdb-templated.json index 97719e82251..f46ccc2042f 100644 --- a/devenv/dev-dashboards/datasource-influxdb/influxdb-templated.json +++ b/devenv/dev-dashboards/datasource-influxdb/influxdb-templated.json @@ -312,7 +312,6 @@ "now": true, "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], "status": "Stable", - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"], "type": "timepicker" }, "timezone": "browser", diff --git a/devenv/dev-dashboards/datasource-mssql/mssql_fakedata.json b/devenv/dev-dashboards/datasource-mssql/mssql_fakedata.json index 19c5e1d0718..8fda3e8e714 100644 --- a/devenv/dev-dashboards/datasource-mssql/mssql_fakedata.json +++ b/devenv/dev-dashboards/datasource-mssql/mssql_fakedata.json @@ -537,8 +537,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - MSSQL", diff --git a/devenv/dev-dashboards/datasource-mssql/mssql_unittest.json b/devenv/dev-dashboards/datasource-mssql/mssql_unittest.json index 0137001067c..40f9d55e5ca 100644 --- a/devenv/dev-dashboards/datasource-mssql/mssql_unittest.json +++ b/devenv/dev-dashboards/datasource-mssql/mssql_unittest.json @@ -2831,8 +2831,7 @@ "to": "2018-03-15T13:55:01.000Z" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - MSSQL (unit test)", diff --git a/devenv/dev-dashboards/datasource-mysql/mysql_fakedata.json b/devenv/dev-dashboards/datasource-mysql/mysql_fakedata.json index 96e4688f7bd..cd1a24fb5bd 100644 --- a/devenv/dev-dashboards/datasource-mysql/mysql_fakedata.json +++ b/devenv/dev-dashboards/datasource-mysql/mysql_fakedata.json @@ -541,8 +541,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - MySQL", diff --git a/devenv/dev-dashboards/datasource-mysql/mysql_unittest.json b/devenv/dev-dashboards/datasource-mysql/mysql_unittest.json index b68c9db97ec..2f2a42c1175 100644 --- a/devenv/dev-dashboards/datasource-mysql/mysql_unittest.json +++ b/devenv/dev-dashboards/datasource-mysql/mysql_unittest.json @@ -2643,8 +2643,7 @@ "to": "2018-03-15T13:55:01.000Z" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - MySQL (unittest)", diff --git a/devenv/dev-dashboards/datasource-postgres/postgres_fakedata.json b/devenv/dev-dashboards/datasource-postgres/postgres_fakedata.json index d7d9514e639..750b3284517 100644 --- a/devenv/dev-dashboards/datasource-postgres/postgres_fakedata.json +++ b/devenv/dev-dashboards/datasource-postgres/postgres_fakedata.json @@ -577,8 +577,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - Postgres", diff --git a/devenv/dev-dashboards/datasource-postgres/postgres_unittest.json b/devenv/dev-dashboards/datasource-postgres/postgres_unittest.json index a114ed1b7ef..acec0d08a44 100644 --- a/devenv/dev-dashboards/datasource-postgres/postgres_unittest.json +++ b/devenv/dev-dashboards/datasource-postgres/postgres_unittest.json @@ -2621,8 +2621,7 @@ "to": "2018-03-15T13:55:01.000Z" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Datasource tests - Postgres (unittest)", diff --git a/devenv/dev-dashboards/datasource-testdata/demo1.json b/devenv/dev-dashboards/datasource-testdata/demo1.json index abe39ffeb55..6d8034f81e6 100644 --- a/devenv/dev-dashboards/datasource-testdata/demo1.json +++ b/devenv/dev-dashboards/datasource-testdata/demo1.json @@ -1092,7 +1092,6 @@ "now": true, "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], "status": "Stable", - "time_options": ["5m", "15m", "1h", "2h", " 6h", "12h", "24h", "2d", "7d", "30d"], "type": "timepicker" }, "timezone": "browser", diff --git a/devenv/dev-dashboards/datasource-testdata/new_features_in_v62.json b/devenv/dev-dashboards/datasource-testdata/new_features_in_v62.json index 4b9535ecbbd..a002a208f85 100644 --- a/devenv/dev-dashboards/datasource-testdata/new_features_in_v62.json +++ b/devenv/dev-dashboards/datasource-testdata/new_features_in_v62.json @@ -1326,8 +1326,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "New Features in v6.2", diff --git a/devenv/dev-dashboards/home.json b/devenv/dev-dashboards/home.json index 9c3d65d4add..840d32919ea 100644 --- a/devenv/dev-dashboards/home.json +++ b/devenv/dev-dashboards/home.json @@ -240,17 +240,6 @@ "1h", "2h", "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" ] }, "timezone": "", diff --git a/devenv/dev-dashboards/panel-bargauge/bar_gauge_demo.json b/devenv/dev-dashboards/panel-bargauge/bar_gauge_demo.json index a708467d7be..eda6ccfe996 100644 --- a/devenv/dev-dashboards/panel-bargauge/bar_gauge_demo.json +++ b/devenv/dev-dashboards/panel-bargauge/bar_gauge_demo.json @@ -654,8 +654,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["2s", "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["2s", "5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Bar Gauge Demo", diff --git a/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge.json b/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge.json index 29a6929cf8f..3dfa360c740 100644 --- a/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge.json +++ b/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge.json @@ -1423,17 +1423,6 @@ "1h", "2h", "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" ] }, "timezone": "", diff --git a/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge2.json b/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge2.json index 0f36c203cd0..06fc26e382d 100644 --- a/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge2.json +++ b/devenv/dev-dashboards/panel-bargauge/panel_tests_bar_gauge2.json @@ -519,8 +519,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Bar Gauge 2", diff --git a/devenv/dev-dashboards/panel-common/lazy_loading.json b/devenv/dev-dashboards/panel-common/lazy_loading.json index 859eede4b4f..960c466124c 100644 --- a/devenv/dev-dashboards/panel-common/lazy_loading.json +++ b/devenv/dev-dashboards/panel-common/lazy_loading.json @@ -2202,8 +2202,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Lazy Loading", diff --git a/devenv/dev-dashboards/panel-common/panels_without_title.json b/devenv/dev-dashboards/panel-common/panels_without_title.json index 44bd210e73b..8f62c9cca5e 100644 --- a/devenv/dev-dashboards/panel-common/panels_without_title.json +++ b/devenv/dev-dashboards/panel-common/panels_without_title.json @@ -893,8 +893,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - With & Without title", diff --git a/devenv/dev-dashboards/panel-gauge/gauge-multi-series.json b/devenv/dev-dashboards/panel-gauge/gauge-multi-series.json index 09b72e5c030..f7ff80edc12 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge-multi-series.json +++ b/devenv/dev-dashboards/panel-gauge/gauge-multi-series.json @@ -254,8 +254,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Gauge Multi Series", diff --git a/devenv/dev-dashboards/panel-gauge/gauge_tests.json b/devenv/dev-dashboards/panel-gauge/gauge_tests.json index 458f53dbc08..309a255fcc7 100644 --- a/devenv/dev-dashboards/panel-gauge/gauge_tests.json +++ b/devenv/dev-dashboards/panel-gauge/gauge_tests.json @@ -1319,8 +1319,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Gauge", diff --git a/devenv/dev-dashboards/panel-geomap/geomap-route-layer.json b/devenv/dev-dashboards/panel-geomap/geomap-route-layer.json index f91036ace8b..c6b1752bd2a 100644 --- a/devenv/dev-dashboards/panel-geomap/geomap-route-layer.json +++ b/devenv/dev-dashboards/panel-geomap/geomap-route-layer.json @@ -29,20 +29,22 @@ "liveNow": false, "panels": [ { - "datasource": { - "type": "testdata", - "uid": "PD8C576611E62080A" + "id": 2, + "type": "geomap", + "title": "Multiple Layer Types", + "gridPos": { + "x": 0, + "y": 0, + "h": 16, + "w": 18 }, "fieldConfig": { "defaults": { - "color": { - "mode": "continuous-RdYlGr" - }, "custom": { "hideFrom": { - "legend": false, "tooltip": false, - "viz": false + "viz": false, + "legend": false } }, "mappings": [], @@ -51,7 +53,7 @@ "steps": [ { "color": "dark-red", - "value": 0 + "value": null }, { "color": "yellow", @@ -62,18 +64,59 @@ "value": 100 } ] + }, + "color": { + "mode": "continuous-RdYlGr" } }, "overrides": [] }, - "gridPos": { - "h": 16, - "w": 18, - "x": 0, - "y": 0 + "pluginVersion": "11.6.0-pre", + "targets": [ + { + "csvContent": "lat,lon,val\n-5,2,0\n1,5,25\n6,10,50\n9,15,75\n10,20,100", + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" + }, + "refId": "A", + "scenarioId": "csv_content" + }, + { + "scenarioId": "csv_content", + "refId": "B", + "datasource": { + "uid": "PD8C576611E62080A", + "type": "grafana-testdata-datasource" + }, + "csvContent": "lat,lon,alt\n45,0,0\n40,5,5\n35,10,10\n30,15, 15\n25,20,20" + } + ], + "datasource": { + "type": "testdata", + "uid": "PD8C576611E62080A" }, - "id": 2, "options": { + "view": { + "allLayers": true, + "id": "fit", + "lat": 2.359794, + "lon": 8.135816, + "zoom": 15, + "lastOnly": false, + "layer": "markers" + }, + "controls": { + "showZoom": true, + "mouseWheelZoom": true, + "showAttribution": true, + "showScale": false, + "showMeasure": false, + "showDebug": false + }, + "tooltip": { + "mode": "details" + }, "basemap": { "config": { "server": "streets" @@ -81,14 +124,6 @@ "name": "Layer 0", "type": "esri-xyz" }, - "controls": { - "mouseWheelZoom": true, - "showAttribution": true, - "showDebug": false, - "showMeasure": false, - "showScale": false, - "showZoom": true - }, "layers": [ { "config": { @@ -128,36 +163,108 @@ "location": { "mode": "auto" }, - "name": "Layer 2", + "name": "route", "tooltip": true, "type": "route" - } - ], - "tooltip": { - "mode": "details" - }, - "view": { - "allLayers": true, - "id": "coords", - "lat": 2.359794, - "lon": 8.135816, - "zoom": 4.45 - } - }, - "pluginVersion": "9.4.0-pre", - "targets": [ - { - "csvContent": "lat,lon,val\n-5,2,0\n1,5,25\n6,10,50\n9,15,75\n10,20,100", - "datasource": { - "type": "testdata", - "uid": "PD8C576611E62080A" }, - "refId": "A", - "scenarioId": "csv_content" - } - ], - "title": "Route with Colors", - "type": "geomap" + { + "type": "geojson", + "name": "geojson", + "config": { + "src": "public/maps/example-with-style.geojson", + "rules": [], + "style": { + "size": { + "fixed": 5, + "min": 2, + "max": 15 + }, + "color": { + "fixed": "dark-green" + }, + "opacity": 0.4, + "symbol": { + "mode": "fixed", + "fixed": "img/icons/marker/circle.svg" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "textAlign": "center", + "textBaseline": "middle", + "offsetX": 0, + "offsetY": 0 + }, + "rotation": { + "fixed": 0, + "mode": "mod", + "min": -360, + "max": 360 + } + } + }, + "location": { + "mode": "auto" + }, + "tooltip": true, + "filterData": { + "id": "byRefId", + "options": "B" + } + }, + { + "type": "markers", + "name": "markers", + "config": { + "style": { + "size": { + "fixed": 5, + "min": 2, + "max": 15 + }, + "color": { + "fixed": "dark-green", + "field": "alt" + }, + "opacity": 0.4, + "symbol": { + "mode": "fixed", + "fixed": "img/icons/marker/circle.svg" + }, + "symbolAlign": { + "horizontal": "center", + "vertical": "center" + }, + "textConfig": { + "fontSize": 12, + "textAlign": "center", + "textBaseline": "middle", + "offsetX": 0, + "offsetY": 0 + }, + "rotation": { + "fixed": 0, + "mode": "mod", + "min": -360, + "max": 360 + } + }, + "showLegend": true + }, + "location": { + "mode": "auto" + }, + "tooltip": true, + "filterData": { + "id": "byRefId", + "options": "B" + } + } + ] + } } ], "schemaVersion": 37, @@ -171,7 +278,7 @@ }, "timepicker": {}, "timezone": "", - "title": "Panel Tests - Geomap Route Layer", + "title": "Panel Tests - Geomap Fit to Data - Multiple Layer Types", "uid": "OYTKK3DVk", "version": 25, "weekStart": "" diff --git a/devenv/dev-dashboards/panel-graph/graph-gradient-area-fills.json b/devenv/dev-dashboards/panel-graph/graph-gradient-area-fills.json index 01e9e8c2f43..c2d27efd469 100644 --- a/devenv/dev-dashboards/panel-graph/graph-gradient-area-fills.json +++ b/devenv/dev-dashboards/panel-graph/graph-gradient-area-fills.json @@ -372,8 +372,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Graph - Gradient Area Fills", diff --git a/devenv/dev-dashboards/panel-graph/graph-time-regions.json b/devenv/dev-dashboards/panel-graph/graph-time-regions.json index 2031788ae3f..a4e03148536 100644 --- a/devenv/dev-dashboards/panel-graph/graph-time-regions.json +++ b/devenv/dev-dashboards/panel-graph/graph-time-regions.json @@ -569,8 +569,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "browser", "title": "Panel Tests - Graph Time Regions", diff --git a/devenv/dev-dashboards/panel-graph/graph_tests.json b/devenv/dev-dashboards/panel-graph/graph_tests.json index 4d01c2cb534..bd1fc95d3d6 100644 --- a/devenv/dev-dashboards/panel-graph/graph_tests.json +++ b/devenv/dev-dashboards/panel-graph/graph_tests.json @@ -1639,8 +1639,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "browser", "title": "Panel Tests - Graph", diff --git a/devenv/dev-dashboards/panel-polystat/polystat_test.json b/devenv/dev-dashboards/panel-polystat/polystat_test.json index 6be355ebd99..faa84463019 100644 --- a/devenv/dev-dashboards/panel-polystat/polystat_test.json +++ b/devenv/dev-dashboards/panel-polystat/polystat_test.json @@ -3408,8 +3408,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Polystat", diff --git a/devenv/dev-dashboards/panel-table/table_tests.json b/devenv/dev-dashboards/panel-table/table_tests.json index 8582ef068d7..b8ca436e110 100644 --- a/devenv/dev-dashboards/panel-table/table_tests.json +++ b/devenv/dev-dashboards/panel-table/table_tests.json @@ -440,8 +440,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "browser", "title": "Panel Tests - Table", diff --git a/devenv/dev-dashboards/panel-timeseries/timeseries-gradient-area.json b/devenv/dev-dashboards/panel-timeseries/timeseries-gradient-area.json index a7389cc6ed6..8f3267a62d7 100644 --- a/devenv/dev-dashboards/panel-timeseries/timeseries-gradient-area.json +++ b/devenv/dev-dashboards/panel-timeseries/timeseries-gradient-area.json @@ -562,8 +562,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel Tests - Graph NG - Gradient Area Fills", diff --git a/devenv/dev-dashboards/scenarios/slow_queries_and_annotations.json b/devenv/dev-dashboards/scenarios/slow_queries_and_annotations.json index a7cc41acd8f..8966137b55e 100644 --- a/devenv/dev-dashboards/scenarios/slow_queries_and_annotations.json +++ b/devenv/dev-dashboards/scenarios/slow_queries_and_annotations.json @@ -1132,8 +1132,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "", "title": "Panel tests - Slow Queries & Annotations", diff --git a/devenv/dev-dashboards/scenarios/time_zone_support.json b/devenv/dev-dashboards/scenarios/time_zone_support.json index feb317f917e..cc1f81ee221 100644 --- a/devenv/dev-dashboards/scenarios/time_zone_support.json +++ b/devenv/dev-dashboards/scenarios/time_zone_support.json @@ -684,8 +684,7 @@ "to": "now" }, "timepicker": { - "refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"], - "time_options": ["5m", "15m", "1h", "6h", "12h", "24h", "2d", "7d", "30d"] + "refresh_intervals": ["10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"] }, "timezone": "utc", "title": "Panel Tests - Time zone support", diff --git a/devenv/docker/blocks/elasticstack/docker-compose.yaml b/devenv/docker/blocks/elasticstack/docker-compose.yaml index ad8a0d5e7f0..35b4254ac63 100644 --- a/devenv/docker/blocks/elasticstack/docker-compose.yaml +++ b/devenv/docker/blocks/elasticstack/docker-compose.yaml @@ -5,6 +5,8 @@ - "discovery.type=single-node" - "xpack.license.self_generated.type=basic" - "xpack.security.enabled=false" + - 'ES_JAVA_OPTS=-XX:UseSVE=0' + - 'CLI_JAVA_OPTS=-XX:UseSVE=0' ports: - 9200:9200 diff --git a/devenv/docker/blocks/prometheus/recording.yml b/devenv/docker/blocks/prometheus/recording.yml index f45cdbeddf2..2b8ae3e477a 100644 --- a/devenv/docker/blocks/prometheus/recording.yml +++ b/devenv/docker/blocks/prometheus/recording.yml @@ -1,4 +1,18 @@ groups: + - name: TESTING_RULES + rules: + - record: test:rate5m + expr: rate(ismail_prometheus_tsdb_reloads_total{job="prometheus"}[5m]) + labels: + identifier: special_idx + - record: agent:test:rate5m + expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m]) + labels: + identifier: special_idx + - record: agent:test:rate5m_agg_ + expr: rate(prometheus_tsdb_reloads_total_agg_{job="aggregated"}[5m]) + labels: + identifier: special_idx - name: RECORDING_RULES rules: - record: instance_path:requests:rate5m @@ -9,6 +23,14 @@ groups: expr: rate(prometheus_tsdb_reloads_failures_total{job="prometheus"}[5m]) - record: instance_path:reloads:rate5m expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m]) + - record: test:rate5m + expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m]) + - record: test:rate5m_agg_ + expr: rate(prometheus_tsdb_reloads_total_agg_{job="aggregated"}[5m]) + - record: agent:test:rate5m + expr: rate(prometheus_tsdb_reloads_total{job="prometheus"}[5m]) + - record: agent:test:rate5m_agg_ + expr: rate(prometheus_tsdb_reloads_total_agg_{job="aggregated"}[5m]) - record: instance_path:request_failures_per_requests:ratio_rate5m expr: |2 instance_path:reloads_failures:rate5m{job="prometheus"} diff --git a/devenv/docker/blocks/prometheus_high_card/go.mod b/devenv/docker/blocks/prometheus_high_card/go.mod index be940ff6862..8dda4f5d7e2 100644 --- a/devenv/docker/blocks/prometheus_high_card/go.mod +++ b/devenv/docker/blocks/prometheus_high_card/go.mod @@ -1,6 +1,6 @@ module high-card -go 1.22.4 +go 1.23.7 require ( github.com/prometheus/client_golang v1.20.2 @@ -15,6 +15,6 @@ require ( github.com/prometheus/client_model v0.6.1 // indirect github.com/prometheus/common v0.55.0 // indirect github.com/prometheus/procfs v0.15.1 // indirect - golang.org/x/sys v0.22.0 // indirect + golang.org/x/sys v0.30.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/devenv/docker/blocks/prometheus_high_card/go.sum b/devenv/docker/blocks/prometheus_high_card/go.sum index 742cb8092ff..93dcce3f212 100644 --- a/devenv/docker/blocks/prometheus_high_card/go.sum +++ b/devenv/docker/blocks/prometheus_high_card/go.sum @@ -20,7 +20,7 @@ github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0leargg github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= diff --git a/devenv/docker/blocks/prometheus_random_data/Dockerfile b/devenv/docker/blocks/prometheus_random_data/Dockerfile index c4ebc8cb0ec..41f90677409 100644 --- a/devenv/docker/blocks/prometheus_random_data/Dockerfile +++ b/devenv/docker/blocks/prometheus_random_data/Dockerfile @@ -7,7 +7,7 @@ RUN CGO_ENABLED=0 GOOS=linux go install -tags netgo -ldflags '-w' github.com/pro # Final image. FROM scratch -LABEL maintainer "The Prometheus Authors " +LABEL maintainer="The Prometheus Authors " COPY --from=builder /go/bin/random . EXPOSE 8080 ENTRYPOINT ["/random"] diff --git a/devenv/docker/blocks/prometheus_utf8/go.mod b/devenv/docker/blocks/prometheus_utf8/go.mod index 706d2d12e81..1202be94ed6 100644 --- a/devenv/docker/blocks/prometheus_utf8/go.mod +++ b/devenv/docker/blocks/prometheus_utf8/go.mod @@ -1,9 +1,10 @@ module utf8-support -go 1.22.4 +go 1.23.7 require ( github.com/prometheus/client_golang v1.20.5 + github.com/prometheus/common v0.60.1 golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 ) @@ -13,8 +14,7 @@ require ( github.com/klauspost/compress v1.17.9 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/prometheus/client_model v0.6.1 // indirect - github.com/prometheus/common v0.60.1 // indirect github.com/prometheus/procfs v0.15.1 // indirect - golang.org/x/sys v0.25.0 // indirect + golang.org/x/sys v0.30.0 // indirect google.golang.org/protobuf v1.34.2 // indirect ) diff --git a/devenv/docker/blocks/prometheus_utf8/go.sum b/devenv/docker/blocks/prometheus_utf8/go.sum index 5b2f91420df..be3770f9e3f 100644 --- a/devenv/docker/blocks/prometheus_utf8/go.sum +++ b/devenv/docker/blocks/prometheus_utf8/go.sum @@ -26,8 +26,8 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948 h1:kx6Ds3MlpiUHKj7syVnbp57++8WpuKPcR5yjLBjvLEA= golang.org/x/exp v0.0.0-20240823005443-9b4947da3948/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= -golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= -golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/devenv/docker/blocks/stateful_webhook/Dockerfile b/devenv/docker/blocks/stateful_webhook/Dockerfile new file mode 100644 index 00000000000..4b671c20410 --- /dev/null +++ b/devenv/docker/blocks/stateful_webhook/Dockerfile @@ -0,0 +1,12 @@ +FROM golang:1.23.7 + +ADD main.go /go/src/webhook/main.go + +WORKDIR /go/src/webhook + +RUN mkdir /tmp/logs +RUN go build -o /bin main.go + +ENV PORT=8080 + +ENTRYPOINT [ "/bin/main" ] diff --git a/devenv/docker/blocks/stateful_webhook/docker-compose.yaml b/devenv/docker/blocks/stateful_webhook/docker-compose.yaml new file mode 100644 index 00000000000..7217516c4e9 --- /dev/null +++ b/devenv/docker/blocks/stateful_webhook/docker-compose.yaml @@ -0,0 +1,5 @@ + stateful_webhook: + build: + context: docker/blocks/stateful_webhook + ports: + - "8080:8080" diff --git a/devenv/docker/blocks/stateful_webhook/main.go b/devenv/docker/blocks/stateful_webhook/main.go new file mode 100644 index 00000000000..926cf4e593e --- /dev/null +++ b/devenv/docker/blocks/stateful_webhook/main.go @@ -0,0 +1,149 @@ +package main + +import ( + "encoding/json" + "io" + "log" + "net/http" + "strings" + "sync" + "time" +) + +type Event struct { + Status string `json:"status"` + TimeNow time.Time `json:"timeNow"` + StartsAt time.Time `json:"startsAt"` + Node string `json:"node"` + DeltaLastSeconds float64 `json:"deltaLastSeconds"` + DeltaStartSeconds float64 `json:"deltaStartSeconds"` +} + +type Notification struct { + Alerts []Alert `json:"alerts"` + CommonAnnotations map[string]string `json:"commonAnnotations"` + CommonLabels map[string]string `json:"commonLabels"` + ExternalURL string `json:"externalURL"` + GroupKey string `json:"groupKey"` + GroupLabels map[string]string `json:"groupLabels"` + Message string `json:"message"` + OrgID int `json:"orgId"` + Receiver string `json:"receiver"` + State string `json:"state"` + Status string `json:"status"` + Title string `json:"title"` + TruncatedAlerts int `json:"truncatedAlerts"` + Version string `json:"version"` +} + +type Alert struct { + Annotations map[string]string `json:"annotations"` + DashboardURL string `json:"dashboardURL"` + StartsAt time.Time `json:"startsAt"` + EndsAt time.Time `json:"endsAt"` + Fingerprint string `json:"fingerprint"` + GeneratorURL string `json:"generatorURL"` + Labels map[string]string `json:"labels"` + PanelURL string `json:"panelURL"` + SilenceURL string `json:"silenceURL"` + Status string `json:"status"` + ValueString string `json:"valueString"` + Values map[string]any `json:"values"` +} + +type NotificationHandler struct { + startedAt time.Time + stats map[string]int + hist []Event + m sync.Mutex +} + +func NewNotificationHandler() *NotificationHandler { + return &NotificationHandler{ + startedAt: time.Now(), + stats: make(map[string]int), + hist: make([]Event, 0), + } +} + +func (ah *NotificationHandler) Notify(w http.ResponseWriter, r *http.Request) { + b, err := io.ReadAll(r.Body) + if err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + n := Notification{} + if err := json.Unmarshal(b, &n); err != nil { + log.Println(err) + w.WriteHeader(http.StatusBadRequest) + return + } + log.Printf("got notification from: %s. a: %v", r.RemoteAddr, n) + + ah.m.Lock() + defer ah.m.Unlock() + + addr := r.RemoteAddr + if split := strings.Split(r.RemoteAddr, ":"); len(split) > 0 { + addr = split[0] + } + + a := n.Alerts[0] + + timeNow := time.Now() + + ah.stats[n.Status]++ + + var d time.Duration + if len(ah.hist) > 0 { + last := ah.hist[len(ah.hist)-1] + d = timeNow.Sub(last.TimeNow) + } + + ah.hist = append(ah.hist, Event{ + Status: n.Status, + StartsAt: a.StartsAt, + TimeNow: timeNow, + Node: addr, + DeltaLastSeconds: d.Seconds(), + DeltaStartSeconds: timeNow.Sub(ah.startedAt).Seconds(), + }) +} + +func (ah *NotificationHandler) GetNotifications(w http.ResponseWriter, _ *http.Request) { + ah.m.Lock() + defer ah.m.Unlock() + w.Header().Set("Content-Type", "application/json") + + res, err := json.MarshalIndent(map[string]any{"stats": ah.stats, "history": ah.hist}, "", "\t") + if err != nil { + w.WriteHeader(http.StatusInternalServerError) + //nolint:errcheck + w.Write([]byte(`{"error":"failed to marshal alerts"}`)) + log.Printf("failed to marshal alerts: %v\n", err) + return + } + + log.Printf("requested current state\n%v\n", string(res)) + + _, err = w.Write(res) + if err != nil { + log.Printf("failed to write response: %v\n", err) + } +} + +func main() { + ah := NewNotificationHandler() + + http.HandleFunc("/ready", func(w http.ResponseWriter, _ *http.Request) { + w.WriteHeader(http.StatusOK) + }) + + http.HandleFunc("/notify", ah.Notify) + http.HandleFunc("/notifications", ah.GetNotifications) + + log.Println("Listening") + //nolint:errcheck + http.ListenAndServe("0.0.0.0:8080", nil) +} diff --git a/devenv/docker/blocks/tempo/tempo.yaml b/devenv/docker/blocks/tempo/tempo.yaml index 7cfb1230a3f..b1130a6e27c 100644 --- a/devenv/docker/blocks/tempo/tempo.yaml +++ b/devenv/docker/blocks/tempo/tempo.yaml @@ -6,15 +6,23 @@ distributor: jaeger: # the receives all come from the OpenTelemetry collector. more configuration information can protocols: # be found there: https://github.com/open-telemetry/opentelemetry-collector/tree/main/receiver thrift_http: # - grpc: # for a production deployment you should only enable the receivers you need! + endpoint: "tempo:14268" # for a production deployment you should only enable the receivers you need! + grpc: + endpoint: "tempo:14250" thrift_binary: + endpoint: "tempo:6832" thrift_compact: + endpoint: "tempo:6831" zipkin: + endpoint: "tempo:9411" otlp: protocols: - http: grpc: + endpoint: "tempo:4317" + http: + endpoint: "tempo:4318" opencensus: + endpoint: "tempo:55678" compactor: compaction: diff --git a/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/alerts/overview.json b/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/alerts/overview.json index b4946cfb6b3..0357c3d10f1 100644 --- a/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/alerts/overview.json +++ b/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/alerts/overview.json @@ -151,17 +151,6 @@ "1h", "2h", "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" ] }, "timezone": "", diff --git a/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/mysql/overview.json b/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/mysql/overview.json index 7643250ec28..2bf789366cc 100644 --- a/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/mysql/overview.json +++ b/devenv/docker/ha-test-unified-alerting/grafana/provisioning/dashboards/mysql/overview.json @@ -5376,17 +5376,6 @@ "1d" ], "status": "Stable", - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ], "type": "timepicker" }, "timezone": "browser", diff --git a/devenv/docker/ha_test/grafana/provisioning/dashboards/alerts/overview.json b/devenv/docker/ha_test/grafana/provisioning/dashboards/alerts/overview.json index b4946cfb6b3..0357c3d10f1 100644 --- a/devenv/docker/ha_test/grafana/provisioning/dashboards/alerts/overview.json +++ b/devenv/docker/ha_test/grafana/provisioning/dashboards/alerts/overview.json @@ -151,17 +151,6 @@ "1h", "2h", "1d" - ], - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" ] }, "timezone": "", diff --git a/devenv/docker/ha_test/grafana/provisioning/dashboards/mysql/overview.json b/devenv/docker/ha_test/grafana/provisioning/dashboards/mysql/overview.json index 7643250ec28..2bf789366cc 100644 --- a/devenv/docker/ha_test/grafana/provisioning/dashboards/mysql/overview.json +++ b/devenv/docker/ha_test/grafana/provisioning/dashboards/mysql/overview.json @@ -5376,17 +5376,6 @@ "1d" ], "status": "Stable", - "time_options": [ - "5m", - "15m", - "1h", - "6h", - "12h", - "24h", - "2d", - "7d", - "30d" - ], "type": "timepicker" }, "timezone": "browser", diff --git a/docs/Makefile b/docs/Makefile index 36b7e4f41be..7bdbe026293 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -9,6 +9,6 @@ include docs.mk .PHONY: sources/panels-visualizations/query-transform-data/transform-data/index.md sources/panels-visualizations/query-transform-data/transform-data/index.md: ## Generate the Transform Data page source. - cd $(CURDIR)/.. && npx tsc ./scripts/docs/generate-transformations.ts && \ - node -e "require('./scripts/docs/generate-transformations').buildMarkdownContent()" && \ + cd $(CURDIR)/.. && \ + npx tsx ./scripts/docs/generate-transformations.ts && \ npx prettier -w $(CURDIR)/$@ diff --git a/docs/README.md b/docs/README.md index 4bea7d788e7..0bf4e8446b5 100644 --- a/docs/README.md +++ b/docs/README.md @@ -48,18 +48,6 @@ Only use [reference style links](https://grafana.com/docs/writers-toolkit/write/ ### [Contributing](/contribute/documentation/README.md) -### Using `relref` for internal links - -Use the Hugo shortcode [relref](https://gohugo.io/content-management/cross-references/#use-ref-and-relref) any time you are linking to other internal docs pages. - -Syntax is: - -``` -{{< relref "example.md" >}} -``` - -You might need to add more context for the link (containing folders and so on, `folder/example.md`) if Hugo says the relref is ambiguous. - ### Managing redirects When moving content around or removing pages it's important that users following old links are properly redirected to the new location. We do this using the [aliases](https://gohugo.io/content-management/urls/#aliases) feature in Hugo. diff --git a/docs/docs.mk b/docs/docs.mk index c0aae10ba50..09308dc8604 100644 --- a/docs/docs.mk +++ b/docs/docs.mk @@ -120,3 +120,12 @@ update: ## Fetch the latest version of this Makefile and the `make-docs` script curl -s -LO https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/docs.mk curl -s -LO https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs chmod +x make-docs + +# ls static/templates/ | sed 's/-template\.md//' | xargs +TOPIC_TYPES := concept multiple-tasks reference section task tutorial visualization +.PHONY: $(patsubst %,topic/%,$(TOPIC_TYPES)) +topic/%: ## Create a topic from the Writers' Toolkit template. Specify the topic type as the target, for example, `make topic/task TOPIC_PATH=sources/my-new-topic.md`. +$(patsubst %,topic/%,$(TOPIC_TYPES)): + $(if $(TOPIC_PATH),,$(error "You must set the TOPIC_PATH variable to the path where the $(@F) topic will be created. For example: make $(@) TOPIC_PATH=sources/my-new-topic.md")) + mkdir -p $(dir $(TOPIC_PATH)) + curl -s -o $(TOPIC_PATH) https://raw.githubusercontent.com/grafana/writers-toolkit/refs/heads/main/docs/static/templates/$(@F)-template.md diff --git a/docs/make-docs b/docs/make-docs index ba448ce0727..f6d72f905dc 100755 --- a/docs/make-docs +++ b/docs/make-docs @@ -1,4 +1,6 @@ #!/bin/sh +# shellcheck disable=SC2034 +# # The source of this file is https://raw.githubusercontent.com/grafana/writers-toolkit/main/docs/make-docs. # # `make-docs` procedure changelog # @@ -6,6 +8,30 @@ # [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. # +# ## 8.5.2 (2025-02-28) +# +# ### Fixed +# +# - topic/ targets are no longer no-ops as a result of 8.5.1. +# +# ## 8.5.1 (2025-02-18) +# +# ### Fixed +# +# - PHONY declaration for topic/ targets. +# +# ## 8.5.0 (2025-02-13) +# +# ### Added +# +# - make topic/ TOPIC_PATH= target to create a new topic from the Writers' Toolkit templates. +# +# ## 8.4.0 (2025-01-27) +# +# ### Fixed +# +# - Correct mount for the /docs/grafana-cloud/send-data/fleet-management/ project. +# # ## 8.3.0 (2024-12-27) # # ### Added @@ -304,6 +330,7 @@ PODMAN="$(if command -v podman >/dev/null 2>&1; then echo podman; else echo dock if ! command -v curl >/dev/null 2>&1; then if ! command -v wget >/dev/null 2>&1; then + # shellcheck disable=SC2016 errr 'either `curl` or `wget` must be installed for this script to work.' exit 1 @@ -311,6 +338,7 @@ if ! command -v curl >/dev/null 2>&1; then fi if ! command -v "${PODMAN}" >/dev/null 2>&1; then + # shellcheck disable=SC2016 errr 'either `podman` or `docker` must be installed for this script to work.' exit 1 @@ -357,6 +385,10 @@ EOF exit 1 fi +# The following variables comprise a pseudo associative array of project names to source repositories. +# You only need to set a SOURCES variable if the project name does not match the source repository name. +# You can get a key identifier using the `identifier` function. +# To look up the value of any pseudo associative array, use the `aget` function. SOURCES_as_code='as-code-docs' SOURCES_enterprise_metrics='backend-enterprise' SOURCES_enterprise_metrics_='backend-enterprise' @@ -366,11 +398,16 @@ SOURCES_grafana_cloud_alerting_and_irm_slo='slo' SOURCES_grafana_cloud_k6='k6-docs' SOURCES_grafana_cloud_data_configuration_integrations='cloud-onboarding' SOURCES_grafana_cloud_frontend_observability_faro_web_sdk='faro-web-sdk' +SOURCES_grafana_cloud_send_data_fleet_management='fleet-management' SOURCES_helm_charts_mimir_distributed='mimir' SOURCES_helm_charts_tempo_distributed='tempo' SOURCES_opentelemetry='opentelemetry-docs' SOURCES_resources='website' +# The following variables comprise a pseudo associative array of project names to versions. +# You only need to set a VERSIONS variable if it is not the default of 'latest'. +# You can get a key identifier using the `identifier` function. +# To look up the value of any pseudo associative array, use the `aget` function. VERSIONS_as_code='UNVERSIONED' VERSIONS_grafana_cloud='UNVERSIONED' VERSIONS_grafana_cloud_alerting_and_irm_machine_learning='UNVERSIONED' @@ -378,12 +415,17 @@ VERSIONS_grafana_cloud_alerting_and_irm_slo='UNVERSIONED' VERSIONS_grafana_cloud_k6='UNVERSIONED' VERSIONS_grafana_cloud_data_configuration_integrations='UNVERSIONED' VERSIONS_grafana_cloud_frontend_observability_faro_web_sdk='UNVERSIONED' +VERSIONS_grafana_cloud_send_data_fleet_management='UNVERSIONED' VERSIONS_opentelemetry='UNVERSIONED' VERSIONS_resources='UNVERSIONED' VERSIONS_technical_documentation='UNVERSIONED' VERSIONS_website='UNVERSIONED' VERSIONS_writers_toolkit='UNVERSIONED' +# The following variables comprise a pseudo associative array of project names to source repository paths. +# You only need to set a PATHS variable if it is not the default of 'docs/sources'. +# You can get a key identifier using the `identifier` function. +# To look up the value of any pseudo associative array, use the `aget` function. PATHS_grafana_cloud='content/docs/grafana-cloud' PATHS_helm_charts_mimir_distributed='docs/sources/helm-charts/mimir-distributed' PATHS_helm_charts_tempo_distributed='docs/sources/helm-charts/tempo-distributed' @@ -816,7 +858,9 @@ EOF case "${OUTPUT_FORMAT}" in human) if ! command -v jq >/dev/null 2>&1; then + # shellcheck disable=SC2016 errr '`jq` must be installed for the `doc-validator` target to work.' + # shellcheck disable=SC2016 note 'To install `jq`, refer to https://jqlang.github.io/jq/download/,' exit 1 diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 989ceddad50..c64772641e4 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -4,7 +4,9 @@ aliases: - /docs/grafana/v3.1/ - guides/reference/admin/ cascade: + LOKI_VERSION: latest TEMPO_VERSION: latest + ONCALL_VERSION: latest PYROSCOPE_VERSION: latest description: Find answers to your technical questions and learn how to use Grafana OSS and Enterprise products. keywords: diff --git a/docs/sources/administration/correlations/_index.md b/docs/sources/administration/correlations/_index.md index 3a61b1800b5..36e0badf5f5 100644 --- a/docs/sources/administration/correlations/_index.md +++ b/docs/sources/administration/correlations/_index.md @@ -14,23 +14,23 @@ weight: 900 You can create interactive links for Explore visualizations by setting up Correlations. These links can either run queries or generate external URLs related to presented data. -A correlation defines how data in one [data source]({{< relref "../../datasources" >}}) is used to query data in another data source or to generate an external URL. +A correlation defines how data in one [data source](../../datasources/) is used to query data in another data source or to generate an external URL. Some examples: - an application name returned in a logs data source can be used to query metrics related to that application in a metrics data source, or - a user name returned by an SQL data source can be used to query logs related to that particular user in a logs data source - a customer ID in a logs data source can link to a different platform that has a profile on that customer. -[Explore]({{< relref "../../explore" >}}) takes user-defined correlations to display links inside the visualizations. -If a correlation links to a query, you can click on that link to run the related query and see results in [Explore Split View]({{< relref "../../explore#split-and-compare" >}}). +[Explore](../../explore/) takes user-defined correlations to display links inside the visualizations. +If a correlation links to a query, you can click on that link to run the related query and see results in [Explore Split View](../../explore/#split-and-compare). If a correlation links to an external URL, you can click on the link to open the URL in a new tab in your browser. Explore visualizations that currently support showing links based on correlations: -- [Logs Panel]({{< relref "./use-correlations-in-visualizations#correlations-in-logs-panel">}}) -- [Table]({{< relref "./use-correlations-in-visualizations#correlations-in-table">}}) +- [Logs Panel](use-correlations-in-visualizations/#correlations-in-logs-panel) +- [Table](use-correlations-in-visualizations/#correlations-in-table) -You can configure correlations using [provisioning]({{< relref "../provisioning" >}}), the **Administration > Plugins and data > Correlations** page in Grafana or directly in [Explore]({{< relref "../../explore/correlations-editor-in-explore" >}}). +You can configure correlations using [provisioning](../provisioning/), the **Administration > Plugins and data > Correlations** page in Grafana or directly in [Explore](../../explore/correlations-editor-in-explore/). ## Example of how links work in Explore once set up diff --git a/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md b/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md index 8dbca454cac..f232f26189c 100644 --- a/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md +++ b/docs/sources/administration/correlations/add-permissions-to-create-new-correlations/index.md @@ -12,7 +12,7 @@ weight: 30 ## Before you begin -Adding access to create correlations for [Viewers and Editors]({{< relref "../../../administration/roles-and-permissions" >}}) is available with [Role-based access control]({{< relref "../../../administration/roles-and-permissions/access-control" >}}). +Adding access to create correlations for [Viewers and Editors](../../roles-and-permissions/) is available with [Role-based access control](../../roles-and-permissions/access-control/). ## Add permissions to create correlations diff --git a/docs/sources/administration/correlations/correlation-configuration/index.md b/docs/sources/administration/correlations/correlation-configuration/index.md index 56c21d89bc0..f01ef51d670 100644 --- a/docs/sources/administration/correlations/correlation-configuration/index.md +++ b/docs/sources/administration/correlations/correlation-configuration/index.md @@ -29,13 +29,13 @@ Each correlation is configured with the following options: **Transformations** : Optional manipulations to the source data included passed to the target query -Learn how to create correlations using the [Administration page]({{< relref "./create-a-new-correlation#create-a-correlation-in-administration-page" >}}) or with [provisioning]({{< relref "./create-a-new-correlation#create-a-correlation-with-provisioning" >}}). +Learn how to create correlations using the [Administration page](../create-a-new-correlation/#create-a-correlation-in-administration-page) or with [provisioning](../create-a-new-correlation/#create-a-correlation-with-provisioning). ## Source data source and result field Links are shown in Explore visualizations for the results from the correlation’s source data source. A link is assigned to one of the fields from the result provided in the correlation configuration (the results field). -Each visualization displays fields with links in a different way ([Correlations in Logs Panel]({{< relref "./use-correlations-in-visualizations#correlations-in-logs-panel">}}) and see [Correlations in Table]({{< relref "./use-correlations-in-visualizations#correlations-in-table">}})). +Each visualization displays fields with links in a different way ([Correlations in Logs Panel](../use-correlations-in-visualizations/#correlations-in-logs-panel) and see [Correlations in Table](../use-correlations-in-visualizations/#correlations-in-table)). ## Target query @@ -44,10 +44,10 @@ The target query is run when a link is clicked in the visualization. You can use ### Correlation Variables You can use variables inside the target query to access the source data related to the query. -Correlations use [Grafana variable syntax]({{< relref "../../../dashboards/variables/variable-syntax" >}}). +Correlations use [Grafana variable syntax](../../../dashboards/variables/variable-syntax/). Variables are filled with values from the source results when the link is clicked. There are two types of variables you can use: -- [field variables]({{< relref "../../../panels-visualizations/configure-data-links#field-variables" >}}) (allows to access field values and labels) +- [field variables](../../../panels-visualizations/configure-data-links/#field-variables) (allows to access field values and labels) - correlation variables (allows to access field values and transformations) Example: If source results contain a field called “employee”, the value of the field can be accessed with: @@ -57,9 +57,9 @@ Example: If source results contain a field called “employee”, the value of t In addition to mapping field values to shorter variable names, more correlation variables can be created by applying transformations to existing fields -For more details, please see the example in [Use variables and transformations in a correlation]({{< relref "./use-variables-and-transformations" >}}). +For more details, please see the example in [Use variables and transformations in a correlation](../use-variables-and-transformations/). -Correlation creates a data link only if all variables have values in the selected data row. [Global variables]({{< relref "/docs/grafana/latest/dashboards/variables/add-template-variables#global-variables" >}}) are exception to this rule and are not required to be filled in from the returned data. These variables are interpolated automatically by data sources. +Correlation creates a data link only if all variables have values in the selected data row. [Global variables](/docs/grafana/latest/dashboards/variables/add-template-variables/#global-variables) are exception to this rule and are not required to be filled in from the returned data. These variables are interpolated automatically by data sources. ### Correlation Transformations @@ -69,7 +69,7 @@ There are two types of transformations: logfmt and regular expression. Each transformation uses a selected field value as the input. The output of a transformation is a set of new variables based on the type and options of the transformation. -For more details, please see the example in [Use variables and transformations in a correlation]({{< relref "./use-variables-and-transformations" >}}) for more details. +For more details, please see the example in [Use variables and transformations in a correlation](../use-variables-and-transformations/) for more details. ### Logfmt transformation diff --git a/docs/sources/administration/correlations/correlation-permissions/index.md b/docs/sources/administration/correlations/correlation-permissions/index.md index ee228d844fa..30984472c20 100644 --- a/docs/sources/administration/correlations/correlation-permissions/index.md +++ b/docs/sources/administration/correlations/correlation-permissions/index.md @@ -9,11 +9,11 @@ weight: 20 # Permissions -Users with [Viewer base role]({{< relref "../../../administration/roles-and-permissions" >}}) or with [datasources:query RBAC role]({{< relref "../../../administration/roles-and-permissions/access-control" >}}) can: +Users with [Viewer base role](../../roles-and-permissions/) or with [datasources:query RBAC role](../../roles-and-permissions/access-control/) can: - Use correlations in Explore’s visualizations. - List all available correlations in read-only mode. -Users with [Admin base role]({{< relref "../../../administration/roles-and-permissions" >}}) or with [datasources:write RBAC role]({{< relref "../../../administration/roles-and-permissions/access-control" >}}) can: +Users with [Admin base role](../../roles-and-permissions/) or with [datasources:write RBAC role](../../roles-and-permissions/access-control/) can: - Add, edit and delete correlations. diff --git a/docs/sources/administration/correlations/create-a-new-correlation/index.md b/docs/sources/administration/correlations/create-a-new-correlation/index.md index 225d6ca8e1c..2ea3bb0b447 100644 --- a/docs/sources/administration/correlations/create-a-new-correlation/index.md +++ b/docs/sources/administration/correlations/create-a-new-correlation/index.md @@ -15,7 +15,7 @@ Make sure you have permission to add new correlations. Only users with write per ## Create a correlation in Explore's correlations editor -To learn more, refer to Explore's [documentation]({{< relref "../../../explore/correlations-editor-in-explore" >}}) about building correlations in Explore. +To learn more, refer to Explore's [documentation](../../../explore/correlations-editor-in-explore/) about building correlations in Explore. ## Create a correlation in Administration page diff --git a/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md b/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md index 4c98948ee3a..07070f27741 100644 --- a/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md +++ b/docs/sources/administration/correlations/use-correlations-in-visualizations/index.md @@ -27,7 +27,7 @@ weight: 70 1. Open Explore. 1. Select a data source that you chose as the source data source of the correlation. 1. Run a query that results in data containing fields required to build variables in the target query. -1. Links are added to cell rows in the column representing the field with the assigned link ([the results field]({{< relref "../correlation-configuration#source-data-source-and-result-field" >}}). +1. Links are added to cell rows in the column representing the field with the assigned link ([the results field](../correlation-configuration/#source-data-source-and-result-field). 1. Cells containing multiple links accessible with a context menu. {{< figure src="/static/img/docs/correlations/correlations-in-table-10-0.png" max-width="600px" caption="Correlations links in table" >}} diff --git a/docs/sources/administration/correlations/use-variables-and-transformations/index.md b/docs/sources/administration/correlations/use-variables-and-transformations/index.md index 6bc3668f9d8..6251d537352 100644 --- a/docs/sources/administration/correlations/use-variables-and-transformations/index.md +++ b/docs/sources/administration/correlations/use-variables-and-transformations/index.md @@ -73,7 +73,7 @@ Instructions below show how to set up a link that can run metrics query for the - Required correlation type (query) - Target query matching test data source model - “App metrics” correlation contains the following configuration: - - Alias is set to ${application} variable (note that in provisioning files $ is used to access environment variables so it has to be [escaped]({{< relref "../../../administration/provisioning#using-environment-variables" >}})). + - Alias is set to ${application} variable (note that in provisioning files $ is used to access environment variables so it has to be [escaped](../../provisioning/#using-environment-variables)). - Regular expression transformation is created to extract values from “msg” field - Regular expression transformation is used to capture the application name from the full name of the service stored in the log line. - The output of the transformation is mapped to a variable called “application”. diff --git a/docs/sources/administration/data-source-management/_index.md b/docs/sources/administration/data-source-management/_index.md index 71c5d87d625..9eab6986e11 100644 --- a/docs/sources/administration/data-source-management/_index.md +++ b/docs/sources/administration/data-source-management/_index.md @@ -18,10 +18,10 @@ weight: 100 # Data source management Grafana supports many different storage backends for your time series data (data source). -Refer to [data sources]({{< relref "../../datasources" >}}) for more information about using data sources in Grafana. +Refer to [data sources](../../datasources/) for more information about using data sources in Grafana. Only users with the organization admin role can add data sources. -For links to data source-specific documentation, see [Data sources]({{< relref "../../datasources" >}}). +For links to data source-specific documentation, see [Data sources](../../datasources/). ## Data source permissions @@ -32,7 +32,7 @@ You can configure data source permissions to allow or deny certain users the abi - The `admin` permission allows users to query and edit the data source, change permissions on the data source and enable or disable query caching for the data source. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise/" >}}) and [Grafana Cloud](/docs/grafana-cloud). +Available in [Grafana Enterprise](../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). {{% /admonition %}} By default, data sources in an organization can be queried by any user in that organization. For example, a user with the `Viewer` role can issue any possible query to a data source, not just queries that exist on dashboards to which they have access. Additionally, by default, data sources can be edited by the user who created the data source, as well as users with the `Admin` role. @@ -80,10 +80,10 @@ When you enable query and resource caching, Grafana temporarily stores the resul When using Grafana, a query pertains to a request for data frames to be modified or displayed. A resource relates to any HTTP requests made by a plugin, such as the Amazon Timestream plugin requesting a list of available databases from AWS. For more information on data source queries and resources, please see the developers page on [backend plugins](https://grafana.com/developers/plugin-tools/key-concepts/backend-plugins/). -The caching feature works for **all** backend data sources. You can enable the cache globally in Grafana's [configuration]({{< relref "../../setup-grafana/configure-grafana/enterprise-configuration/#caching" >}}), and configure a cache duration (also called Time to Live, or TTL) for each data source individually. +The caching feature works for **all** backend data sources. You can enable the cache globally in Grafana's [configuration](../../setup-grafana/configure-grafana/enterprise-configuration/#caching), and configure a cache duration (also called Time to Live, or TTL) for each data source individually. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise/" >}}) and [Grafana Cloud](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud/). {{% /admonition %}} The following cache backend options are available: in-memory, Redis, and Memcached. @@ -94,9 +94,9 @@ Storing cached queries in-memory can increase Grafana's memory footprint. In pro When a panel queries a data source with cached data, it will either fetch fresh data or use cached data depending on the panel's **interval.** The interval is used to round the query time range to a nearby cached time range, increasing the likelihood of cache hits. Therefore, wider panels and dashboards with shorter time ranges fetch new data more often than narrower panels and dashboards with longer time ranges. -A panel's interval is visible in the [query options]({{< relref "../../panels-visualizations/query-transform-data/" >}}). It is calculated as follows: `time range / max data points`. Max data points are calculated based on the width of the panel. For example, a wide panel with `1000 data points` on a dashboard with a time range of `last 7 days` will retrieve fresh data every 10 minutes: `7d / 1000 = 10m`. In this example, cached data for this panel will be served for up to 10 minutes before Grafana needs to query the data source again for new data. +A panel's interval is visible in the [query options](../../panels-visualizations/query-transform-data/). It is calculated as follows: `time range / max data points`. Max data points are calculated based on the width of the panel. For example, a wide panel with `1000 data points` on a dashboard with a time range of `last 7 days` will retrieve fresh data every 10 minutes: `7d / 1000 = 10m`. In this example, cached data for this panel will be served for up to 10 minutes before Grafana needs to query the data source again for new data. -You can configure a panel to retrieve data more often by increasing the **Max data points** setting in the panel's [query options]({{< relref "../../panels-visualizations/query-transform-data/" >}}). +You can configure a panel to retrieve data more often by increasing the **Max data points** setting in the panel's [query options](../../panels-visualizations/query-transform-data/). ### Caching benefits @@ -108,7 +108,11 @@ By reducing the number of queries and requests sent to data sources, caching can ### Data sources that work with query caching -Query caching works for Grafana's [built-in data sources]({{< relref "../../datasources/#built-in-core-data-sources" >}}), and [backend data source plugins](https://grafana.com/grafana/plugins/?type=datasource) that extend the `DataSourceWithBackend` class in the plugins SDK. +Query caching works for Grafana's [built-in data sources](../../datasources/#built-in-core-data-sources), and [backend data source plugins](https://grafana.com/grafana/plugins/?type=datasource) that extend the `DataSourceWithBackend` class in the plugins SDK. + +{{% admonition type="note" %}} +Logs Insights for the CloudWatch data source does not support query caching due to the way logs are requested from AWS. +{{% /admonition %}} To verify that a data source works with query caching, follow the [instructions below](#enable-and-configure-query-caching) to **Enable and Configure query caching**. If caching is enabled in Grafana but the Caching tab is not visible for the given data source, then query caching is not available for that data source. @@ -118,7 +122,7 @@ Some data sources, such as Elasticsearch, Prometheus, and Loki, cache queries th ### Enable and configure query caching -You must be an Org admin or Grafana admin to enable query caching for a data source. For more information on Grafana roles and permissions, refer to [About users and permissions]({{< relref "../roles-and-permissions/" >}}). +You must be an Org admin or Grafana admin to enable query caching for a data source. For more information on Grafana roles and permissions, refer to [About users and permissions](../roles-and-permissions/). By default, data source queries are not cached. To enable query caching for a single data source: @@ -137,7 +141,7 @@ You can optionally override a data source's configured TTL for individual dashbo If query caching is enabled and the Cache tab is not visible in a data source's settings, then query caching is not available for that data source. {{% /admonition %}} -To configure global settings for query caching, refer to the `caching` section of [Configure Grafana Enterprise]({{< relref "../../setup-grafana/configure-grafana/enterprise-configuration/#caching" >}}). +To configure global settings for query caching, refer to the `caching` section of [Configure Grafana Enterprise](../../setup-grafana/configure-grafana/enterprise-configuration/#caching). ### Disable query caching @@ -148,7 +152,7 @@ To disable query caching for a single data source: 1. In the data source list, click the data source that you want to turn off caching for. 1. On the Cache tab, click **Disable**. -To disable query caching for an entire Grafana instance, set the `enabled` flag to `false` in the `caching` section of [Configure Grafana Enterprise]({{< relref "../../setup-grafana/configure-grafana/enterprise-configuration/#caching" >}}). You will no longer see the Cache tab on any data sources, and no data source queries will be cached. +To disable query caching for an entire Grafana instance, set the `enabled` flag to `false` in the `caching` section of [Configure Grafana Enterprise](../../setup-grafana/configure-grafana/enterprise-configuration/#caching). You will no longer see the Cache tab on any data sources, and no data source queries will be cached. ### Clear cache diff --git a/docs/sources/administration/data-source-management/teamlbac/_index.md b/docs/sources/administration/data-source-management/teamlbac/_index.md index ac801cf9d18..4bf449af022 100644 --- a/docs/sources/administration/data-source-management/teamlbac/_index.md +++ b/docs/sources/administration/data-source-management/teamlbac/_index.md @@ -20,7 +20,18 @@ Label-Based Access Control (LBAC) allows fine-grained access control to data sou ## Supported Data Sources -LBAC for data sources is currently available for `Loki, Prometheus` with basic authentication. Support for additional data sources may be added in future updates. +### Feature availability + +LBAC for data sources is currently generally available for `Loki` and in **experimental** for `Prometheus`. Support for additional data sources may be added in future updates. + +| Data source | [Grafana Cloud](/docs/grafana-cloud) | [Grafana Enterprise](../../../introduction/grafana-enterprise/) | +| ----------- | ------------------------------------ | --------------------------------------------------------------- | +| Loki | GA | GA | +| Prometheus | PrivatePreview | PrivatePreview | + +{{% admonition type="note" %}} +For enterprise this feature requires Grafana Enterprise Metrics (GEM) or Grafana Enterprise Logs (GEL) to function. +{{% /admonition %}} **LBAC for data sources offers:** @@ -28,11 +39,6 @@ LBAC for data sources is currently available for `Loki, Prometheus` with basic a - Simplified data source management by consolidating multiple sources into one. - Dashboard reuse across teams with tailored access. -{{< admonition type="note" >}} -LBAC rules is available for **private preview** in Grafana Cloud. -Report any unexpected behavior to the Grafana Support team. -{{< /admonition >}} - You can configure user access based upon team memberships using `LogQL`. LBAC for data sources controls access to logs or metrics depending on the rules set for each team. @@ -57,7 +63,7 @@ This flexibility allows teams to use the same data source for multiple use cases ## Before you begin -To be able to use LBAC for data sources, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. +To be able to use LBAC for data sources metrics, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. ## Limitations @@ -95,4 +101,4 @@ To set up LBAC for data sources for a data source, refer to [Configure LBAC for ## Provisioning of LBAC rules -We recommend using our Terraform provider to set up provisioning for [Resource data source config LBAC rules] (https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source_config_lbac_rules). Refer to our provider documentation to learn how to configure rules for a data source. +We recommend using our Terraform provider to set up provisioning for [Resource data source config LBAC rules](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/data_source_config_lbac_rules). Refer to our provider documentation to learn how to configure rules for a data source. diff --git a/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-loki/index.md b/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-loki/index.md index 0e5875eb26c..18a21b24ee8 100644 --- a/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-loki/index.md +++ b/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-loki/index.md @@ -19,8 +19,6 @@ You cannot configure LBAC rules for Grafana-provisioned data sources from the UI ## Before you begin -To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you. - - Be sure that you have the permission setup to create a Loki tenant in Grafana Cloud - Be sure that you have admin data source permissions for Grafana. diff --git a/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/index.md b/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/index.md index aa54d970e6f..fa08b2f47cc 100644 --- a/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/index.md +++ b/docs/sources/administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/index.md @@ -18,20 +18,26 @@ weight: 250 LBAC for data sources is available in private preview on Grafana Cloud for Prometheus created with basic authentication. Prometheus data sources for LBAC for data sources can only be created, provisioning is currently not available. -You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. Alternatively, you can replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for New Prometheus Data Source](https://grafana.com/docs/grafana/latest/administration/data-source-management/teamlbac/configure-teamlbac-for-Prometheus/#task-1-lbac-configuration-for-new-Prometheus-data-source) and then add the LBAC configuration to the new data source. +You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. Alternatively, you can replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for New Prometheus Data Source](#task-1-lbac-configuration-for-new-prometheus-data-source) and then add the LBAC configuration to the new data source. ## Before you begin -To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you. +To be able to use LBAC for Prometheus data sources, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. Contact support to enable the feature toggle for you. - Be sure that you have the permission setup to create a Prometheus tenant in Grafana Cloud - Be sure that you have admin data source permissions for Grafana. +## Grafana Cloud + +LBAC for data sources is available in private preview on Grafana Cloud for Prometheus created with basic authentication. Prometheus data sources for LBAC for data sources can only be created, provisioning is currently not available. + +You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. We recommend that you replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for New Prometheus Data Source](#task-1-lbac-configuration-for-new-prometheus-data-source) and then add the LBAC configuration to the new data source. + ### Permissions We recommend that you remove all permissions for roles and teams that are not required to access the data source. This will help to ensure that only the required teams have access to the data source. The recommended permissions are `Admin` permission and only add the teams `Query` permissions that you want to add LBAC for data sources rules for. -## Task 1: LBAC Configuration for New Prometheus Data Source +## Task 1: LBAC Configuration for new Prometheus data source 1. Access Prometheus data sources details for your stack through grafana.com 1. Copy Prometheus details and create a CAP @@ -53,11 +59,11 @@ For more information on how to setup LBAC for data sources rules for a Prometheu LBAC for data sources is available in Grafana Enterprise for Prometheus created with basic authentication. Prometheus data sources for LBAC for data sources can only be created. -You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. Alternatively, you can replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for New Prometheus Data Source](https://grafana.com/docs/grafana/latest/administration/data-source-management/teamlbac/configure-teamlbac-for-Prometheus/#task-1-lbac-configuration-for-new-Prometheus-data-source) and then add the LBAC configuration to the new data source. +You cannot configure LBAC rules for Grafana-provisioned data sources from the UI. Alternatively, you can replicate the setting of the provisioned data source in a new data source as described in [LBAC Configuration for new Prometheus data source](https://grafana.com/docs/grafana//administration/data-source-management/teamlbac/configure-teamlbac-for-prometheus/#task-1-lbac-configuration-for-new-prometheus-data-source) and then add the LBAC configuration to the new data source. ## Before you begin -To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you. +To be able to use LBAC for Prometheus data sources, you need to enable the feature toggle `teamHttpHeadersMimir` on your Grafana instance. Contact support to enable the feature toggle for you. - Be sure that you have the permission setup to create a cluster in your Grafana - Be sure that you have admin plugins permissions for Grafana. @@ -79,7 +85,7 @@ We recommend that you remove all permissions for roles and teams that are not re - Ensure the CAP does not include `labels` rules. - Store the `token` to be used as password for authentication. -## Task 1: LBAC Configuration for New Prometheus Data Source +## Task 1: LBAC Configuration for new Prometheus data source 1. Create a new Prometheus data source - In Grafana, proceed to add a new data source and select Prometheus as the type. diff --git a/docs/sources/administration/data-source-management/teamlbac/create-teamlbac-rules/index.md b/docs/sources/administration/data-source-management/teamlbac/create-teamlbac-rules/index.md index 3942490c0ff..f76dd3d64bb 100644 --- a/docs/sources/administration/data-source-management/teamlbac/create-teamlbac-rules/index.md +++ b/docs/sources/administration/data-source-management/teamlbac/create-teamlbac-rules/index.md @@ -17,8 +17,6 @@ LBAC for data sources is available for LBAC-supported data sources created with ## Before you begin -To be able to use LBAC for data sources rules, you need to enable the feature toggle `teamHttpHeaders` on your Grafana instance. Contact support to enable the feature toggle for you. - - Be sure that you have the permission setup to create a Loki tenant in Grafana Cloud. - Be sure that you have admin data source permissions for Grafana. - Be sure that you have a team setup in Grafana. diff --git a/docs/sources/administration/enterprise-licensing/_index.md b/docs/sources/administration/enterprise-licensing/_index.md index 131ec8d0f79..31fbf6027a3 100644 --- a/docs/sources/administration/enterprise-licensing/_index.md +++ b/docs/sources/administration/enterprise-licensing/_index.md @@ -23,11 +23,11 @@ weight: 500 # Grafana Enterprise license -When you become a Grafana Enterprise customer, you gain access to Grafana's premium observability features, including enterprise data source plugins, reporting, and role-based access control. In order to use these [enhanced features of Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}), you must purchase and activate a Grafana Enterprise license. +When you become a Grafana Enterprise customer, you gain access to Grafana's premium observability features, including enterprise data source plugins, reporting, and role-based access control. In order to use these [enhanced features of Grafana Enterprise](../../introduction/grafana-enterprise/), you must purchase and activate a Grafana Enterprise license. -To purchase a license directly from Grafana Labs, [Contact a Grafana Labs representative](/contact?about=grafana-enterprise). To activate an Enterprise license purchased from Grafana Labs, refer to [Activate an Enterprise license]({{< relref "#activate-an-enterprise-license" >}}). +To purchase a license directly from Grafana Labs, [Contact a Grafana Labs representative](/contact?about=grafana-enterprise). To activate an Enterprise license purchased from Grafana Labs, refer to [Activate an Enterprise license](#activate-an-enterprise-license). -You can also purchase a Grafana Enterprise license through the AWS Marketplace. To learn more about activating a license purchased through AWS, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace]({{< relref "./activate-aws-marketplace-license/" >}}). +You can also purchase a Grafana Enterprise license through the AWS Marketplace. To learn more about activating a license purchased through AWS, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace](activate-aws-marketplace-license/). {{< section >}} @@ -94,9 +94,9 @@ environment variable. ### Step 3. Ensure that the license file's root URL matches the root_url configuration option -Update the [`root_url`]({{< relref "../../setup-grafana/configure-grafana/#root_url" >}}) in your configuration. It should be the URL that users type in their browsers to access the frontend, not the node hostname(s). +Update the [`root_url`](../../setup-grafana/configure-grafana/#root_url) in your configuration. It should be the URL that users type in their browsers to access the frontend, not the node hostname(s). -This is important, because as part of the validation checks at startup, Grafana compares the license URL to the [`root_url`]({{< relref "../../setup-grafana/configure-grafana/#root_url" >}}) in your configuration. +This is important, because as part of the validation checks at startup, Grafana compares the license URL to the [`root_url`](../../setup-grafana/configure-grafana/#root_url) in your configuration. In your configuration file: @@ -113,7 +113,7 @@ GF_SERVER_ROOT_URL=https://grafana.example.com/ ### Step 4. Restart Grafana -To finalize the installation of Grafana Enterprise, restart Grafana to enable all Grafana Enterprise features. Refer to [restart Grafana]({{< relref "../../setup-grafana/start-restart-grafana/" >}}) for more information. +To finalize the installation of Grafana Enterprise, restart Grafana to enable all Grafana Enterprise features. Refer to [restart Grafana](../../setup-grafana/start-restart-grafana/) for more information. ## License expiration @@ -123,7 +123,7 @@ If your license has expired, most of Grafana keeps working as normal. Some enter ### Update your license -1. Locate your current `license.jwt` file. In a standard installation it is stored inside the Grafana data directory, which on a typical Linux installation is in `/var/lib/grafana/data`. This location might be overridden in the ini file [Configuration]({{< relref "../../setup-grafana/configure-grafana/" >}}). +1. Locate your current `license.jwt` file. In a standard installation it is stored inside the Grafana data directory, which on a typical Linux installation is in `/var/lib/grafana/data`. This location might be overridden in the ini file [Configuration](../../setup-grafana/configure-grafana/). ```ini [enterprise] @@ -135,7 +135,7 @@ If your license has expired, most of Grafana keeps working as normal. Some enter 2. Log in to your [Grafana Cloud Account](/login) and make sure you're in the correct organization in the dropdown at the top of the page. 3. Under the **Grafana Enterprise** section in the menu bar to the left, choose licenses and download the currently valid license with which you want to run Grafana. If you cannot see a valid license on Grafana.com, please contact your account manager at Grafana Labs to renew your subscription. 4. Replace the current `license.jwt`-file with the one you've just downloaded. -5. [Restart Grafana]({{< relref "../../setup-grafana/start-restart-grafana/" >}}). +5. [Restart Grafana](../../setup-grafana/start-restart-grafana/). ### If your license expires @@ -244,11 +244,19 @@ Your license is controlled by the following rules: **License expiration date:** The license includes an expiration date, which is the date when a license becomes inactive. -As the license expiration date approaches, you will see a banner in Grafana that encourages you to renew. To learn about how to renew your license and what happens in Grafana when a license expires, refer to [License expiration]({{< relref "#license-expiration" >}}). +As the license expiration date approaches, you will see a banner in Grafana that encourages you to renew. To learn about how to renew your license and what happens in Grafana when a license expires, refer to [License expiration](#license-expiration). + +**License token expiration:** Grafana Enterprise requires a valid token, which is automatically renewed. + +A license token is a digital key that activates your license. By default, the license token is renewed every 24 hours by calling the Grafana API. Short-lived license tokens enable more frequent validation that licenses are compliant, and allow for more frequent license updates - for example, adding users or invalidating a compromised license. + +To view the details of your license token, sign in to Grafana Enterprise as a Server Administrator and visit **Administration** > **General** > **Statistics and licensing**. Token details are in the Token section under License Details. + +License token renewal requires internet access, and requires that the `auto_refresh_license` [configuration setting](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/enterprise-configuration/#auto_refresh_license) be set to `true`. If your Grafana Enterprise instance cannot connect to the internet, contact your Grafana Labs account team for additional options for token renewal and license audit. **Grafana License URL:** Your license does not work with an instance of Grafana with a different root URL. -The License URL is the complete URL of your Grafana instance, for example `https://grafana.your-company.com/`. It is defined in the [root_url]({{< relref "../../setup-grafana/configure-grafana/#root_url" >}}) configuration setting. +The License URL is the complete URL of your Grafana instance, for example `https://grafana.your-company.com/`. It is defined in the [root_url](../../setup-grafana/configure-grafana/#root_url) configuration setting. **Concurrent sessions limit**: As of Grafana Enterprise 7.5, users can initiate up to three concurrent sessions of Grafana. @@ -256,14 +264,24 @@ The system creates a session when a user signs in to Grafana from a new device, When a user reaches the session limit, the fourth connection succeeds and the longest inactive session is signed out. -### Request usage billing - -You can request Grafana Labs to activate usage billing which allows an unlimited number of active users. When usage billing is enabled, Grafana does not enforce active user limits or display warning banners. Instead, you are charged for active users that exceed the limit, according to your customer contract. - -Usage billing involves a contractual agreement between you and Grafana Labs, and it is only available if Grafana Enterprise is configured to [automatically refresh its license token]({{< relref "../../setup-grafana/configure-grafana/enterprise-configuration/#auto_refresh_license" >}}). - ### Request a change to your license To increase the number of licensed users within Grafana, extend a license, or change your licensed URL, contact [Grafana support](/profile/org#support) or your Grafana Labs account team. They will update your license, which you can activate from within Grafana. -For instructions about how to activate your license after it is updated, refer to [Activate an Enterprise license]({{< relref "#activate-an-enterprise-license" >}}). +For instructions about how to activate your license after it is updated, refer to [Activate an Enterprise license](#activate-an-enterprise-license). + +## Usage billing + +Standard Grafana Enterprise licenses include a certain number of seats that can be used, and prevent more users logging into Grafana than have been licensed. This makes sense if you prefer a predictable bill. It can however be a problem if you anticipate uneven usage patterns over time or when it's critical that no user ever be prevented from logging in to Grafana due to capacity constraints. + +For those use-cases we support usage-based billing, where your license includes a certain number of included users and you are billed on a monthly basis for any excess active users during the month. + +Usage billing involves a contractual agreement between you and Grafana Labs and an update to your license, and it is only available if Grafana Enterprise version 10.0.0 or higher is configured to [automatically refresh its license token](../../setup-grafana/configure-grafana/enterprise-configuration/#auto_refresh_license). + +### User deduplication + +If your organization has multiple Grafana Enterprise instances with usage billing enabled, then each active user counts only once toward your license, regardless of how many instances that user signs into. Each Grafana Enterprise instance submits a hashed list of users to Grafana Labs via API every day. Each user email address or anonymous device ID is hashed using a one-way sha256 algorithm, and submitted to Grafana where the hashed users are deduplicated across instances. + +### Request usage billing + +To request usage billing, contact your Grafana Labs account team or [submit a support ticket](https://grafana.com/profile/org#support). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/_index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/_index.md index 2ecc592a76d..4ac9e4814be 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/_index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/_index.md @@ -30,7 +30,7 @@ You can deploy Grafana Enterprise in the following ways: - Using AWS services like ECS, EKS or EC2. - In an instance outside AWS. -In each case, you must activate the Grafana Enterprise license purchased in AWS Marketplace to take advantage of Grafana Enterprise observability features. Grafana Enterprise licenses purchased through AWS Marketplace are subject to the same [restrictions]({{< relref "../#license-restrictions" >}}) as Grafana Enterprise licensed purchased directly from Grafana Labs. +In each case, you must activate the Grafana Enterprise license purchased in AWS Marketplace to take advantage of Grafana Enterprise observability features. Grafana Enterprise licenses purchased through AWS Marketplace are subject to the same [restrictions](../#license-restrictions) as Grafana Enterprise licensed purchased directly from Grafana Labs. > To purchase a license directly from Grafana Labs or learn more about other Grafana offerings, [Contact a Grafana Labs representative](/contact?about=grafana-enterprise). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md index 5d3858c25cc..c9192e585e6 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-ecs/index.md @@ -48,7 +48,7 @@ Grafana requires that you configure a database to hold dashboards, users, and ot ### Before you begin - Ensure that you have a supported Grafana database available. - - For a list of supported databases, refer to [Supported databases]({{< relref "../../../../setup-grafana/installation/#supported-databases" >}}). + - For a list of supported databases, refer to [Supported databases](../../../../setup-grafana/installation/#supported-databases). - For information about creating a database, refer to [Creating an Amazon RDS DB instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html). - Review the information required to connect to the RDS DB instance. For more information, refer to [Connecting to an Amazon RDS DB instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_CommonTasks.Connect.html). @@ -56,7 +56,7 @@ To configure Grafana for high availability: 1. In AWS ECS, use environment variables to update the `database` parameters. - For a list of database parameters, refer to [Configuration]({{< relref "../../../../setup-grafana/configure-grafana/#database" >}}). + For a list of database parameters, refer to [Configuration](../../../../setup-grafana/configure-grafana/#database). 1. Create a revision of the task definition for the ECS Task that runs Grafana Enterprise. @@ -114,4 +114,4 @@ In this task you configure Grafana Enterprise to validate the license with AWS i 1. To restart Grafana and activate your license, update the service running Grafana to use the latest revision of the task definition that you created. 1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > General > Stats and license** to validate that your license is active. -For more information about validating that your license is active, refer to [Grafana Enterprise license restrictions]({{< relref "../../#grafana-enterprise-license-restrictions" >}}). +For more information about validating that your license is active, refer to [Grafana Enterprise license restrictions](../../#grafana-enterprise-license-restrictions). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md index a5698448447..5199690faa3 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-eks/index.md @@ -50,7 +50,7 @@ Grafana requires that you configure a database to hold dashboards, users, and ot ### Before you begin - Ensure that you have a supported Grafana database available. - - For a list of supported databases, refer to [Supported databases]({{< relref "../../../../setup-grafana/installation/#supported-databases" >}}). + - For a list of supported databases, refer to [Supported databases](../../../../setup-grafana/installation/#supported-databases). - For information about creating a database, refer to [Creating an Amazon RDS DB instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_CreateDBInstance.html). - Review the information required to connect to the RDS DB instance. For more information, refer to [Connecting to an Amazon RDS DB instance](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_CommonTasks.Connect.html). @@ -82,7 +82,7 @@ To configure Grafana for high availability, choose **one** of the following opti value: [database password] ``` -For more information on Grafana High Availability setup, refer to [Set up Grafana for high availability]({{< relref "../../../../setup-grafana/set-up-for-high-availability/" >}}). +For more information on Grafana High Availability setup, refer to [Set up Grafana for high availability](../../../../setup-grafana/set-up-for-high-availability/). ## Task 3: Configure Grafana Enterprise to validate its license with AWS @@ -99,7 +99,7 @@ In this task, you configure Grafana Enterprise to validate the license with AWS For more information about AWS license permissions, refer to [Actions, resources, and condition keys for AWS License Manager](https://docs.aws.amazon.com/service-authorization/latest/reference/list_awslicensemanager.html). -1. Choose **one** of the following options to update the [license_validation_type]({{< relref "../../../../setup-grafana/configure-grafana/enterprise-configuration/#license_validation_type" >}}) configuration to `aws`: +1. Choose **one** of the following options to update the [license_validation_type](../../../../setup-grafana/configure-grafana/enterprise-configuration/#license_validation_type) configuration to `aws`: - **Option 1:** Use `kubectl edit configmap grafana` to edit `grafana.ini` add the following section to the configuration: @@ -125,6 +125,6 @@ To restart Grafana on a Kubernetes cluster, 1. After you update the service, navigate to your Grafana instance, sign in with Grafana Admin credentials, and navigate to **Administration > General > Stats and license** to validate that your license is active. -For more information about restarting Grafana, refer to [Restart Grafana]({{< relref "../../../../setup-grafana/start-restart-grafana/" >}}). +For more information about restarting Grafana, refer to [Restart Grafana](../../../../setup-grafana/start-restart-grafana/). > If you experience issues when you update the EKS cluster, refer to [Amazon EKS troubleshooting](https://docs.aws.amazon.com/eks/latest/userguide/troubleshooting.html). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-instance-outside-aws/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-instance-outside-aws/index.md index a205673c676..9d1741d94a4 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-instance-outside-aws/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/activate-license-on-instance-outside-aws/index.md @@ -35,9 +35,9 @@ To activate a Grafana Enterprise license from AWS on a Grafana Enterprise instan To install Grafana, refer to the documentation specific to your implementation. -- [Install Grafana]({{< relref "../../../../setup-grafana/installation/" >}}). -- [Run Grafana Docker image]({{< relref "../../../../setup-grafana/installation/docker/" >}}). -- [Deploy Grafana on Kubernetes]({{< relref "../../../../setup-grafana/installation/kubernetes/#deploy-grafana-enterprise-on-kubernetes" >}}). +- [Install Grafana](../../../../setup-grafana/installation/). +- [Run Grafana Docker image](../../../../setup-grafana/installation/docker/). +- [Deploy Grafana on Kubernetes](../../../../setup-grafana/installation/kubernetes/#deploy-grafana-enterprise-on-kubernetes). ## Task 2: Create an AWS IAM user with access to your Grafana Enterprise license @@ -110,7 +110,7 @@ To retrieve your license, Grafana Enterprise requires access to your AWS account In this task you configure Grafana Enterprise to validate the license with AWS instead of Grafana Labs. -Choose one of the following options to update the [license_validation_type]({{< relref "../../../../setup-grafana/configure-grafana/enterprise-configuration/#license_validation_type" >}}) configuration to `aws`: +Choose one of the following options to update the [license_validation_type](../../../../setup-grafana/configure-grafana/enterprise-configuration/#license_validation_type) configuration to `aws`: - **Option 1:** In the `[enterprise]` section of the grafana.ini configuration file, add `license_validation_type=aws`. @@ -131,4 +131,4 @@ Choose one of the following options to update the [license_validation_type]({{< To activate Grafana Enterprise features, start (or restart) Grafana. -For information about restarting Grafana, refer to [Restart Grafana]({{< relref "../../../../setup-grafana/start-restart-grafana/" >}}). +For information about restarting Grafana, refer to [Restart Grafana](../../../../setup-grafana/start-restart-grafana/). diff --git a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md index 56ba176742d..47988bf8a14 100644 --- a/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md +++ b/docs/sources/administration/enterprise-licensing/activate-aws-marketplace-license/manage-license-in-aws-marketplace/index.md @@ -42,4 +42,4 @@ You can use AWS Marketplace to make the following modifications to your Grafana This action retrieves updated license information from AWS. -> To learn more about licensing and active users, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace]({{< relref "../" >}}). +> To learn more about licensing and active users, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace](../). diff --git a/docs/sources/administration/feature-toggles/index.md b/docs/sources/administration/feature-toggles/index.md index 90d08353bec..b79d62fbede 100644 --- a/docs/sources/administration/feature-toggles/index.md +++ b/docs/sources/administration/feature-toggles/index.md @@ -19,7 +19,7 @@ For detailed information about particular features and how they operate, refer t ## Manage feature toggles In the **Administration** page, the **Feature Management** section enables authorized users to view and edit the various features that are active in their Grafana environment. -Authorized users include administrators, and users with the [fixed roles]({{< relref "../roles-and-permissions/access-control#fixed-roles" >}}) `featuremgmt.read` and `featuremgmt.write`. +Authorized users include administrators, and users with the [fixed roles](../roles-and-permissions/access-control/#fixed-roles) `featuremgmt.read` and `featuremgmt.write`. There are different options for visibility and customization depending on the development stage of the feature. diff --git a/docs/sources/administration/migration-guide/_index.md b/docs/sources/administration/migration-guide/_index.md new file mode 100644 index 00000000000..deb7de8c533 --- /dev/null +++ b/docs/sources/administration/migration-guide/_index.md @@ -0,0 +1,23 @@ +--- +aliases: + - /docs/grafana-cloud/account-management/e2c-guide/ + - /docs/grafana-cloud/account-management/migration-guide/ +description: Migrate from Grafana OSS/Enterprise to Grafana Cloud +keywords: + - Grafana Cloud + - Grafana Enterprise + - Grafana OSS +menuTitle: Migrate from Grafana OSS/Enterprise to Grafana Cloud +title: Migrate from Grafana OSS/Enterprise to Grafana Cloud +--- + +# Migrate from Grafana OSS/Enterprise to Grafana Cloud + +When you decide to migrate from your self-managed Grafana instance to Grafana Cloud, you can benefit from the convenience of a managed observability platform, additional cloud-only features, and robust security. There are a couple of key approaches to help you transition to Grafana Cloud. + +| Migration type | Tools used | Availability | Migratable resources | +| :------------- | :-------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Manual |
  • Command line utilities
  • The Grafana HTTP API
| Generally available in all versions of Grafana OSS/Enterprise | The entire Grafana instance | +| Automated | The Grafana Cloud Migration Assistant | Available in public preview from Grafana v11.2 using the `onPremToCloudMigrations` feature toggle. This toggle is enabled by default in Grafana v11.5 and later. |
  • Dashboards
  • Folders
  • Data sources
  • App Plugins
  • Panel Plugins
  • Library Panels
  • Grafana Alerting resources
| + +Our detailed [migration guide](https://www.grafana.com/docs/grafana-cloud/account-management/migration-guide/manually-migrate-to-grafana-cloud/) explains the key steps and scripts to manually migrate your resources to Grafana Cloud, covering a comprehensive set of resources in your Grafana instance. Alternatively, the [Grafana Cloud Migration Assistant](https://www.grafana.com/docs/grafana-cloud/account-management/migration-guide/cloud-migration-assistant/), available in public preview in Grafana v11.2 and later, automates the migration process across a broad range of Grafana resources. You can use the migration assistant to migrate a large proportion of your Grafana resources and then, if needed, leverage the migration guide to migrate the rest. diff --git a/docs/sources/administration/migration-guide/cloud-migration-assistant.md b/docs/sources/administration/migration-guide/cloud-migration-assistant.md new file mode 100644 index 00000000000..5e1e1b0b423 --- /dev/null +++ b/docs/sources/administration/migration-guide/cloud-migration-assistant.md @@ -0,0 +1,201 @@ +--- +description: Migrate from Grafana OSS/Enterprise to Grafana Cloud using the Grafana Cloud Migration Assistant +keywords: + - Grafana Cloud + - Grafana Enterprise + - Grafana OSS +menuTitle: Migrate to Grafana Cloud using the Grafana Cloud Migration Assistant +title: Migrate from Grafana OSS/Enterprise to Grafana Cloud using the Grafana Cloud Migration Assistant +weight: 400 +--- + +# Grafana Cloud Migration Assistant + +The Grafana Cloud Migration Assistant is available in Grafana 11.2+ as a [public preview feature](https://grafana.com/docs/release-life-cycle/#public-preview) that automatically migrates resources from your Grafana OSS/Enterprise instance to Grafana Cloud. It provides the following functionalities: + +- Securely connect your self-managed instance to a Grafana Cloud instance. +- Seamlessly migrate resources such as dashboards, data sources, and folders to your cloud instance in a few easy steps. +- View the migration status of your resources in real-time. + +Some of the benefits of the migration assistant are: + +Ease of use +: Follow the steps provided by the UI to easily migrate all your resources to Grafana Cloud without using Grafana APIs or scripts. + +Security +: Encrypt and securely migrate your resources to your connected Grafana Cloud instance. + +Speed +: Migrate all of your resources in minutes and accelerate your transition to Grafana Cloud. + +## Supported resources + +The following resources are supported by the migration assistant: + +- Dashboards +- Folders +- Data sources +- App Plugins +- Panel Plugins +- Library Panels +- Grafana Alerting resources + +## Before you begin + +To use the Grafana migration assistant, you need: + +- Grafana v11.2 or above with the `onPremToCloudMigrations` feature toggle enabled. In Grafana 11.5, this is enabled by default. For more information on how to enable a feature toggle, refer to [Configure feature toggles](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles/#configure-feature-toggles). +- A [Grafana Cloud Stack](https://grafana.com/docs/grafana-cloud/get-started/) you intend to migrate your resources to. +- [`Admin`](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/cloud-roles/) access to the Grafana Cloud Stack. To check your access level, go to `https://grafana.com/orgs//members`. +- [Grafana server administrator](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/#grafana-server-administrators) access to your existing Grafana OSS/Enterprise instance. To check your access level, go to `https:///admin/users`. +- Internet access from your existing Grafana OSS/Enterprise instance. + +## Access the migration assistant + +In Grafana OSS, access to the migration assistant is limited to the server administrator. + +In Grafana Enterprise, the server administrator has access to the migration assistant by default. It is also possible to grant access to other Admins using a role-based access control (RBAC) role that enables other admins on the Grafana instance to view, build snapshots, and upload resources to Grafana Cloud. + +### Grant access in Grafana Enterprise + +{{< admonition type="important">}} +You must [configure RBAC](https://grafana.com/docs/grafana/latest/administration/roles-and-permissions/access-control/configure-rbac/) before you can grant other administrators access to the Grafana Migration Assistant. +{{< /admonition >}} + +To grant other Admins access to the migration assistant in Grafana Enterprise: + +1. Sign in to Grafana as a server administrator. +1. Navigate to **Home** > **Administration** > **Users and access** > **Users** in the Grafana sidebar. +1. Click an Admin. +1. In the **Organizations** section, click **Change role**. +1. Select **Organization resource migrator** from the role selector menu under **Migration Assistant**. + + ![The Organization resource migrator role in the role picker](/media/docs/grafana-cloud/account-management/screenshot-grant-migration-assistant-access.png) + +1. Click **Apply**. + +## Use the migration assistant + +You can use the migration assistant to generate a migration token on your Grafana Cloud instance, use that token to connect your self-managed Grafana instance to your Grafana Cloud instance, build snapshots of your self-managed Grafana instance, and upload these snapshots to Grafana Cloud. + +### Generate a migration token on the destination cloud instance: + +1. Navigate to **Home** > **Administration** > **General** > **Migrate to Grafana Cloud** in the cloud instance where you intend to migrate your resources. +1. Click on the **Generate a migration token** button. + + ![The Generate a migration token button in the Migrate to Grafana Cloud page in the intended Grafana Cloud Stack](/media/docs/grafana-cloud/account-management/screenshot-generate-migration-token.png) + +1. Make a copy of the migration token by copying to clipboard. The token is required to authenticate your self-managed instance with the Grafana Cloud Stack. + +### Connect your self-managed Grafana instance to the Grafana Cloud Stack + +1. On your self-managed Grafana instance, navigate to **Home** > **Administration** > **General** > **Migrate to Grafana Cloud**. + +1. Click the **Migrate this instance to Cloud** button. + + ![The Migrate this instance to Cloud button in the Migrate to Grafana Cloud page on a self-managed Grafana instance](/media/docs/grafana-cloud/account-management/screenshot-migrate-to-cloud.png) + +1. Enter your token and click **Connect to this Stack**. + + ![The Migration token field and Connect to this stack button in the Connect to a cloud stack page in a self-managed Grafana instance](/media/docs/grafana-cloud/account-management/screenshot-connect-to-a-stack.png) + +### Build a snapshot + +After connecting to the cloud stack, this is the empty state of the migration assistant. You need to create a snapshot of the self-managed Grafana instance to upload it to the cloud stack. + +- Click **Build snapshot** + + ![The Build snapshot button on the Migrate to Grafana Cloud page in a self-managed Grafana instance](/media/docs/grafana-cloud/account-management/screenshot-build-a-snapshot.png) + +### Upload resources to the cloud + +After a snapshot is created, a list of resources appears with resource Type and Status populated with **Not yet uploaded**. + +![A list of resources with snapshots built but not yet uploaded to Grafana Cloud](/media/docs/grafana-cloud/account-management/screenshot-upload-snapshot.png) + +1. Click on **Upload snapshot** to copy the resources to the Grafana Cloud instance. This also updates statuses for the list of resources. The status changes to 'Uploaded to cloud' for resources successfully copied to the cloud. + + The Snapshot information also updates to inform the user of total resources, errors, and total number of successfully migrated resources. + + ![An updates list of resources with snapshots built after attempting to upload them to Grafana Cloud](/media/docs/grafana-cloud/account-management/screenshot-updated-snapshot-page.png) + +1. Use the assistant's real-time progress tracking to monitor the migration. + +1. Review error details for any issues that need manual resolution. + +## Snapshots created by the migration assistant + +The migration assistant currently supports a subset of all resources available in Grafana. Refer to [Supported Resources](https://wwww.grafana.com/docs/grafana-cloud/account-management/cloud-migration-assistant/#supported-resources) for more details. + +When you create a snapshot, the migration assistant makes a copy of all supported resources and saves them in the snapshot. The snapshot reflects the current state of the resources when the snapshot is built and is stored locally on your instance, ready to be uploaded in the last stage. It is currently not possible to select specific resources to include in the snapshot, such as only dashboards. All supported resources are included by default. + +Resources saved in the snapshot are strictly limited to the resources stored within an organization. This is important to note if there are multiple organizations used in your Grafana instance. If you want to migrate multiple organizations, refer to [Migrate multiple organizations](https://wwww.grafana.com/docs/grafana-cloud/account-management/cloud-migration-assistant/#migrate-multiple-organizations) for more information and guidance. + +## Resource migration details + +During a migration, resource UIDs are preserved, allowing you to correlate your local and cloud resources. If you perform the same migration multiple times, resources in your Grafana Cloud stack that were previously migrated are updated. The assistant never modifies your self-managed resources or cloud resources that didn't come from a snapshot. + +### Dashboards and folders + +Dashboard names and UIDs are preserved along with references to data sources. Folder hierarchy is also preserved, so you can find your dashboards and other resources saved in identical folder locations. + +### Data sources + +Your data sources, including credentials, are migrated securely and seamlessly to your Grafana Cloud instance, so you don't need to find and enter all your data source credentials again. + +### Plugins + +The migration assistant supports any plugins found in the plugins catalog. As long as the plugin is signed or is a core plugin built into Grafana, it is eligible for migration. Due to security reasons, unsigned plugins are not supported in Grafana Cloud. If you are using any unsigned private plugins, Grafana recommends you seek an alternative plugin for the catalog or work on a strategy to deprecate certain functionality from your self-managed instance. + +Upgrade any plugins you intend to migrate before using the migration assistant as any migrated plugins will be configured on the Grafana Cloud instance as the latest version of that plugin. + +{{< admonition type="caution">}} +If you want to migrate Enterprise plugins, check what type of plan your Grafana Cloud instance is on and whether or not this plan requires an Enterprise plugin add-on. +{{< /admonition >}} + +### Grafana Alerting resources + +The migration assistant can migrate the majority of Grafana Alerting resources to your Grafana Cloud instance. These include: + +- Alert rules +- Notifications +- Contact points +- Mute timings +- Notification policy tree +- Notification templates + +This is sufficient to have your Alerting configuration up and running in Grafana Cloud with minimal effort. + +Migration of Silences is not supported by the migration assistant and needs to be configured manually. Alert History is also not available for migration. + +Successfully migrating Alerting resources to your Grafana Cloud instance could result in 2 sets of notifications being generated; one from your OSS/Enterprise instance and another from the newly migrated alerts in your Grafana Cloud instance. To avoid double notifications, a new `alert_rules_state` configuration option in the `custom.ini` or `grafana.ini` file controls how Alert Rules are migrated to the Grafana Cloud instance and is set to `paused` by default so you can review and test your Alerting resources in your Grafana Cloud instance without duplicate notifications. + +The available options for `alert_rule_state` are: + +`paused` +: Creates all Alert rules in paused state on the Cloud instance. This is helpful to avoid double notifications. + +`unchanged` +: The Alert rules maintain their original state coming from the source instance. + +When you are ready to start using your alert rules and notifications from your Grafana Cloud instance, run the migration again with `alert_rules_state = unchanged`. + +### Resource permissions + +Because the migration assistant does not yet migrate teams or RBAC permissions, your resources are migrated with default permissions. Ensure that you reconfigure permissions in your cloud stack as needed following a migration. For more information, refer to [Grafana Cloud user roles and permissions](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/cloud-roles/). + +## Migrate multiple organizations + +If you are using the [organizations](https://grafana.com/docs/grafana/latest/administration/organization-management/#about-organizations) feature on your Grafana Instance and intend to migrate to Grafana Cloud, you need to plan this aspect of the migration carefully. + +The organizations feature is not supported in Grafana Cloud, but folders and RBAC can be used to protect and grant permissions to resources instead. The recommended path is to migrate multiple organizations to a single cloud stack. This is the simplest option and provides the best user experience. + +The migration assistant creates and uploads snapshots based on the resources within a specific organization. There is no option to migrate an entire Grafana instance with multiple organizations at once. You need to run the migration process for each organization you want to migrate. + +The Grafana server administrator is granted access to the migration assistant by default. The server administrator can perform the migration by switching organizations and running the migration assistant each time. The Grafana server administrator can also grant access to the migration assistant to organization administrators who are members using the RBAC **Migration Assistant:Organization resource migrator** role. This allows those organization administrators to run the migration process for their respective organizations. + +### Access Control and managing resources in the Cloud Instance + +The main driver for setting up organizations in the first place is resource isolation. In order to achieve this in Grafana Cloud, you can organize resources into folders and set up teams and permissions that correspond to your organizations. + +For more information about configuring teams and permissions, refer to [Configure Grafana Teams](https://grafana.com/docs/grafana/latest/administration/team-management/configure-grafana-teams/). diff --git a/docs/sources/administration/migration-guide/manually-migrate-to-grafana-cloud.md b/docs/sources/administration/migration-guide/manually-migrate-to-grafana-cloud.md new file mode 100644 index 00000000000..d0bffd7b8f2 --- /dev/null +++ b/docs/sources/administration/migration-guide/manually-migrate-to-grafana-cloud.md @@ -0,0 +1,312 @@ +--- +description: Migrate from Grafana OSS/Enterprise to Grafana Cloud manually +keywords: + - Grafana Cloud + - Grafana Enterprise + - Grafana OSS +menuTitle: Manually migrate to Grafana Cloud +title: Migrate from Grafana OSS/Enterprise to Grafana Cloud manually +weight: 300 +--- + +# Migrate from Grafana OSS/Enterprise to Grafana Cloud manually + +This migration guide is designed to assist Grafana OSS/Enterprise users in seamlessly transitioning manually to Grafana Cloud. + +{{< admonition type="note" >}} +There isn't yet a standard method for importing existing data into Grafana Cloud from self-managed databases. +{{< /admonition >}} + +## Plan and perform a manual migration + +If you need to migrate resources beyond what is supported by the Grafana Cloud Migration Assistant, you can migrate them manually with this guide. Moving your team from Grafana OSS/Enterprise to Grafana Cloud manually involves some coordination and communication in addition to the technical migration in the following documentation. + +If you are an existing Grafana OSS/Enterprise customer, contact your account team at Grafana Labs to plan a transition period, arrange licenses, and learn how much your Grafana Cloud subscription costs in comparison to Grafana OSS/Enterprise. The account team can also offer specific guidance and arrange professional services to assist with your migration if needed. + +Evaluate Grafana Cloud's security and compliance policies at the [Grafana Labs Trust Center](https://trust.grafana.com/). + +You may choose to test Grafana Cloud for some time before migrating your entire organization. To do so, set up a “test” stack in Cloud and migrate resources there first. If you use Grafana Alerting, make sure to set up a different contact point so that alerts do not fire twice. + +When you decide to migrate, set aside a day of cutover during which users should not create new dashboards or alerts. Migrate any newly-created resources, turn on your production Alerting contact points and notification policies in Cloud and turn them off in Grafana OSS/Enterprise, and notify your users. You may also choose to redirect the Grafana OSS/Enterprise URL to your Grafana Cloud URL. + +| Component | Migration Effort | Notes | +| ------------ | ---------------- | -------------------------------------------------------------------------- | +| Folders | Low | | +| Dashboards | Low | Data source references might need to be renamed | +| Alerts | Medium | Data source based alerts might need to be adapted | +| Plugins | Medium | Depends on the feature set of the plugin | +| Data sources | High | If the data sources references any secrets, you need to provide them again | + +## Before you begin + +Ensure you have the following: + +- A [Grafana Cloud Stack](https://grafana.com/docs/grafana-cloud/get-started/) and access to a Linux Machine (or a working WSL2 installation) to run the code snippets in this guide. +- Administrator access to a Grafana Cloud stack. To check you access level, Go to `https://grafana.com/orgs//members` +- Administrator access to your existing Grafana OSS/Enterprise instance. To check your access level, Go to `https:///admin/users` +- Access to the credentials used to connect to your data sources. For example, API keys or usernames and passwords. Since this information is encrypted, it cannot be copied from one instance to the other. +- If some of your data sources are only available from inside your network, refer to the requirements for [Private Data Source Connect](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/) +- For Plugins, Reports and Playlists only: The [curl](https://github.com/curl/curl) and [jq](https://jqlang.github.io/jq/download/) command line tools + +## Upgrade Grafana OSS/Enterprise to the latest version + +Grafana Cloud stacks generally run the latest version of Grafana. In order to avoid issues during migration, upgrade Grafana by following our guides [here](https://grafana.com/docs/grafana/latest/upgrade-guide/). + +## Migrate Grafana resources + +In this guide, the term **"resources"** refers to things you create in Grafana, like dashboards, folders, alerts, data sources, and permissions. + +The process of migration works by pulling the existing resources (like dashboards and folders) from the old Grafana instance, modifying them if necessary, and then pushing them to the new Grafana Cloud instance. + +In the provided code snippets throughout this migration guide, you need to substitute specific placeholders with your actual credentials and instance URLs. Make the following replacements before executing the scripts: + +- `$GRAFANA_SOURCE_TOKEN` with the access token from your Grafana OSS/Enterprise instance. +- `$GRAFANA_DEST_TOKEN` with the access token from your Grafana Cloud instance. +- `$GRAFANA_ONPREM_INSTANCE_URL` with the URL of your Grafana OSS/Enterprise instance. For example: `https://grafana.mydomain.com` +- `$GRAFANA_CLOUD_INSTANCE_URL` with the URL of your Grafana Cloud instance. For example: `https://myorganization.grafana.net` + +### Migrate Grafana Plugins + +Migration of plugins is the first step when transitioning from Grafana OSS/Enterprise to Grafana Cloud, given that plugins are integral components that influence the functionality and display of other Grafana resources, such as dashboards. + +1. To retrieve the Plugins installed in your Grafana OSS/Enterprise instance, issue an HTTP GET request to the `/api/plugins` endpoint. Use the following shell command: + + ```shell + response=$(curl -s -H "Accept: application/json" -H "Authorization: Bearer $GRAFANA_SOURCE_TOKEN" "${GRAFANA_ONPREM_INSTANCE_URL}/api/plugins") + + plugins=$(echo $response | jq '[.[] | select(.signatureType == "community" or (.signatureType != "internal" and .signatureType != "")) | {name: .id, version: .info.version}]') + + echo "$plugins" > plugins.json + ``` + + The command provided above will carry out an HTTP request to this endpoint and accomplish several tasks: + + - It issues a GET request to the `/api/plugins` endpoint of your Grafana OSS/Enterprise instance to retrieve a list of installed plugins. + - It filters out the list to only include community plugins and those signed by external parties. + - It extracts the plugin ID and version before storing them in a `plugins.json` file. + +1. To import the plugins in your Grafana Cloud Instance, execute the following command. This command constructs an HTTP POST request to `https://grafana.com/api/instances//plugins` + + ```shell + CLOUD_INSTANCE=$GRAFANA_CLOUD_INSTANCE_URL + + stack_slug="${CLOUD_INSTANCE#*//}" + stack_slug="${stack_slug%%.*}" + jq -c '.[]' plugins.json | while IFS= read -r plugin; do + name=$(echo "$plugin" | jq -r '.name') + version=$(echo "$plugin" | jq -r '.version') + echo "Adding plugin $name with version $version to stack $stack_slug" + response=$(curl -s -X POST "https://grafana.com/api/instances/$stack_slug/plugins" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d "{\"plugin\": \"$name\", \"version\": \"$version\"}") + echo "POST response for plugin $name version $version: $response" + done + ``` + + Replace `` with your Grafana Cloud Access Policy Token. To create a new one, refer to Grafana Cloud [access policies documentation](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/access-policies/) + + This script iterates through each plugin listed in the `plugins.json` file: + + - It constructs a POST request for each plugin to add it to the specified Grafana Cloud instance. + - It reports back the response for each POST request to give you confirmation or information about any issues that occurred. + +### Migrate resources that are already provisioned as-code + +If you already use tools like [Terraform](https://grafana.com/docs/grafana-cloud/developer-resources/infrastructure-as-code/terraform/), [Ansible](https://grafana.com/docs/grafana-cloud/developer-resources/infrastructure-as-code/ansible/), or [Grafana’s HTTP API](https://grafana.com/docs/grafana-cloud/developer-resources/api-reference/http-api/) to provision resources to Grafana, redirect those to the new Grafana Cloud instance by replacing the Grafana URL and credentials. + +### Migrate dashboards, folders, data sources, library panels, and alert rules using Grizzly + +Grizzly is a command line tool that streamlines working with Grafana resources. Use it to migrate most of the content in your Grafana instance. Follow these steps in your terminal to install Grizzly. If you need to change the os or the architecture, Refer to the Grizzly [releases](https://github.com/grafana/grizzly/releases) and use the binary according to your needs. + +```shell +# download the binary (adapt os and arch as needed) +$ curl -fSL -o "/usr/local/bin/grr" "https://github.com/grafana/grizzly/releases/download/v0.3.1/grr-linux-amd64" + +# make it executable +$ chmod a+x "/usr/local/bin/grr" + +# have fun :) +$ grr --help +``` + +First, create a new folder on your computer and navigate to it to keep your work organized. + +```shell +mkdir grafana-migration +cd grafana-migration +``` + +To give grizzly access to your Grafana OSS/Enterprise instance and the Grafana Cloud Instance, you need to create a [service account](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/service-accounts/) and a corresponding [access token](https://www.grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/service-accounts/#service-account-tokens) on each instance. You can use these tokens to authenticate requests to pull and push resources. Follow these steps on your Grafana OSS/Enterprise instance: + +- Navigate to the **Administration -> Users and access -> Service Accounts** Page within the Grafana OSS/Enterprise instance. +- Click on **Add Service Account** +- Give the Service account a descriptive name like “grizzly-migration” and apply the **Admin** role. +- After creating the account, click on **Add Service Account Token** +- Enter a name for the token +- Select **Set expiration date** and enter an expiry date for the token +- Click **Generate Token** and save this token in a password manager or other secure place. + +Complete the service account creation and token generation process for your Grafana Cloud Instance by following the same steps outlined above for your Grafana OSS/Enterprise instance. This ensures that Grizzly has the necessary access token for both platforms. + +Next, to tell grizzly which instances you’re going to work on, use the following commands: + +```shell +grr config create-context grafana-onprem +grr config use-context grafana-onprem +grr config set output-format json +grr config set grafana.url $GRAFANA_ENT_INSTANCE_URL +grr config set grafana.token $GRAFANA_SOURCE_TOKEN + +grr config create-context grafana-cloud +grr config use-context grafana-cloud +grr config set output-format json +grr config set grafana.url $GRAFANA_CLOUD_INSTANCE_URL +grr config set grafana.token $GRAFANA_DEST_TOKEN +``` + +Afterward, you will have two contexts set up; one for your local Grafana OSS/Enterprise installation and one for Grafana Cloud. The `grr config use-context` command allows you to switch between the two instances while using Grizzly. + +#### Export existing resources + +Switch to the `grafana-onprem` context and use the pull command to fetch the resources you want to migrate: + +```shell +grr config use-context grafana-onprem +grr pull . \ + -t 'Dashboard/*' \ + -t 'Datasource/*' \ + -t 'DashboardFolder/*' \ + -t 'LibraryElement/*' \ + -t 'AlertRuleGroup/*' \ + -t 'AlertContactPoint/*' \ + -t 'AlertNotificationPolicy/*' +``` + +This will fetch the specified resources from Grafana and store them in the current directory. + +#### Push the resources to your Grafana Cloud stack + +With everything in place, switch to the Grafana cloud context and use the following commands to apply the resources to the configured instance: + +```shell +grr config use-context grafana-cloud + +grr apply . -t 'DashboardFolder/*' +grr apply . -t 'LibraryElement/*' +grr apply . -t 'Datasource/*' +grr apply . -t 'Dashboard/*' +grr apply . -t 'AlertRuleGroup/*' +grr apply . -t 'AlertContactPoint/*' +grr apply . -t 'AlertNotificationPolicy/*' +``` + +#### Fill in data source credentials + +After migrating your data sources, you must fill in their credentials, like tokens, usernames, or passwords. For security reasons, grizzly cannot read encrypted data source credentials from the existing Grafana instance. + +To fill in the missing authentication information, go to the **Connections -> Datasources** page in your new Grafana Cloud instance and verify that credentials for all data sources are set. You can skip data sources starting with `grafanacloud` - These are managed by Grafana Cloud directly and provide access to Grafana Cloud databases. + +If one of your data sources can only be accessed from your internal network, take a look at the [Private Data Source Connect documentation](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/). + +After you have configured the data sources, all your dashboards should be available as they were before. + +##### (Optional) Configure Private Data Source Connect (PDC) + +This step only applies if you use Grafana OSS/Enterprise to access network-secured data sources. + +Some data sources, like Prometheus or SQL databases, live on private networks or behind fire wall rules that are not accessible by Grafana Cloud. If your Grafana OSS/Enterprise instance was hosted on the same network as your data source, you might find that Grafana Cloud cannot connect to all of the same data sources that Grafana OSS/Enterprise could access. + +To access these data sources from Grafana Cloud, follow our guide to [configure PDC in your network](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/), and then configure the applicable Grafana data sources to [connect using PDC](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/configure-pdc/#configure-a-data-source-to-use-private-data-source-connect-pdc). Note that PDC is only needed for your network-secured data sources, not for data sources like Splunk or CloudWatch that are accessible over the public internet. + +For more information on how PDC works, see our [overview document](/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/). + +### Migrate reports and playlists using Grafana’s HTTP API + +Grizzly does not currently support Reports and Playlists as a resource, so you can perform this migration using Grafana’s HTTP API using the `curl` command. + +#### Reports (For Grafana Enterprise only) + +1. To export your Reports, you will need to invoke the `api/reports` endpoint of your Grafana OSS/Enterprise instance. The below shell command accomplishes this by using `curl` to send a request to the endpoint and then stores the retrieved report configuration into a file named `reports.json`. + + ```shell + curl ${GRAFANA_ONPREM_INSTANCE_URL}/api/reports -H "Authorization: Bearer $GRAFANA_SOURCE_TOKEN" > reports.json + ``` + +2. To upload the configuration data you have saved in the `reports.json` file to your new Grafana Cloud instance, run the below command. The command will take the local file `reports.json` and push its contents to the `api/reports` endpoint of your Grafana Cloud instance. + + ```shell + jq -M -r -c '.[]' < reports.json | while read -r json; do curl -XPOST ${GRAFANA_CLOUD_INSTANCE_URL}/api/reports -H"Authorization: Bearer $GRAFANA_DEST_TOKEN" -d"$json" -H 'Content-Type: application/json'; done + ``` + +#### Playlists + +1. To retrieve the Playlists from your Grafana OSS/Enterprise instance, issue an HTTP GET request to the `/api/playlists` endpoint. Use the following shell command: + + ```shell + mkdir playlists + curl "${GRAFANA_ONPREM_INSTANCE_URL}/api/playlists" \ + -H "Authorization: Bearer $GRAFANA_SOURCE_TOKEN" \ + | jq -M -r -c '.[] | .uid' \ + | while read -r uid; do \ + curl "${GRAFANA_ONPREM_INSTANCE_URL}/api/playlists/$uid" \ + -H "Authorization: Bearer $GRAFANA_SOURCE_TOKEN" \ + > playlists/$uid.json; \ + done + ``` + + The command provided above will carry out an HTTP request to this endpoint and accomplish several tasks: + + - It fetches an array of all the playlists available in the Grafana OSS/Enterprise instance. + - It then iterates through each playlist to obtain the complete set of details. + - Finally, it stores each playlist's specification as separate JSON files within a directory named `playlists` + +2. To import the playlists, execute the following command. This command constructs an HTTP POST request targeting the `/api/playlists` endpoint of your Grafana Cloud Instance. + + ```shell + for playlist in playlists/*; do + curl -XPOST "${GRAFANA_CLOUD_INSTANCE_URL}/api/playlists" \ + -H "Authorization: Bearer $GRAFANA_DEST_TOKEN" \ + -H "Content-Type: application/json" \ + -d $playlist > /dev/null; + done + ``` + +### Migrate single sign-on configuration + +Grafana Cloud stacks support all of the same authentication and authorization options as Grafana OSS/Enterprise, except for [anonymous authentication](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/anonymous-auth/) and use of the [Auth proxy](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/auth-proxy/). However, single sign-on settings cannot be exported and imported like dashboards, alerts, and other resources. + +To set up SAML authentication from scratch using Grafana’s UI or API, follow [these instructions](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/saml-ui/) to Configure SAML authentication in Grafana. + +LDAP and OIDC/OAuth2 can only be configured in Grafana Cloud by the Grafana Labs support team. Follow [these instructions](https://grafana.com/docs/grafana-cloud/account-management/authentication-and-permissions/) to request SSO configuration from the support team. + +### Migrate custom Grafana configuration + +You may have customized the [configuration](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/) of your Grafana OSS/Enterprise instance, for example with feature toggles, custom auth, or embedding options. Since Grafana configuration is stored in environment variables or the filesystem where Grafana runs, Grafana Cloud users do not have access to it. However, you can open a support ticket to ask a Grafana Labs support engineer for customizations. + +The following customizations are available via support: + +- Enabling [feature toggles](http://www.grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/feature-toggles). +- [Single sign-on and team sync using SAML, LDAP, or OAuth](http://www.grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication). +- Enable [embedding Grafana dashboards in other applications](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#allow_embedding) for Grafana Cloud contracted customers. +- [Audit logging](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/audit-grafana/) ([Usage insights logs and dashboards](https://grafana.com/docs/grafana-cloud/account-management/usage-insights/) are available in Grafana Cloud Pro and Advanced by default). + +Note that the following custom configurations are not supported in Grafana Cloud: + +- [Anonymous user access](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/anonymous-auth/). +- [Auth proxy](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/auth-proxy/). +- [Third-party database encryption](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-database-encryption/) and the [Hashicorp Vault](https://grafana.com/docs/grafana/latest/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/) integration. +- Running self-signed plugins, like custom-built data sources or visualizations. For more information on plugin signing, refer to our [developer documentation](https://grafana.com/developers/plugin-tools/publish-a-plugin/sign-a-plugin). + +If you have a custom configuration in Grafana OSS/Enterprise that is not listed here, reach out to our support team to find out whether they can help you set it up. + +## Next steps + +After you have successfully migrated resources and configuration from Grafana OSS/Enterprise, consider the following steps to enhance your monitoring experience: + +- **Get started with Grafana Cloud**: learn more about the functionality available in Grafana Cloud, which is not available in the open source or Enterprise editions. Read more in [Get started with Grafana Cloud](https://grafana.com/docs/grafana-cloud/get-started/) +- **AWS PrivateLink for Grafana Cloud**: securely transmit telemetry data from your AWS Virtual Private Cloud (VPC) to Grafana Cloud, entirely within the AWS network. + Learn how to set this up with [AWS PrivateLink Integration](https://grafana.com/docs/grafana-cloud/send-data/aws-privatelink/). +- **Azure PrivateLink for Grafana Cloud**, securely transmit telemetry from your Azure Virtual Network to Grafana Cloud while staying on the Azure network, and avoid exposing your traffic to the public internet. + Learn how to set this up with [AWS PrivateLink Integration](https://grafana.com/docs/grafana-cloud/send-data/azure-privatelink/). +- **[Grafana Integrations](https://grafana.com/docs/grafana-cloud/monitor-infrastructure/integrations/)**: ready-made integrations to make monitoring your infrastructure and applications more straightforward. diff --git a/docs/sources/administration/organization-management/index.md b/docs/sources/administration/organization-management/index.md index a332c8110db..6c4d52941f3 100644 --- a/docs/sources/administration/organization-management/index.md +++ b/docs/sources/administration/organization-management/index.md @@ -46,7 +46,7 @@ The following table summarizes the resources you can share and/or isolate using The member of one organization cannot view dashboards assigned to another organization. However, a user can belong to multiple organizations. -Grafana Server Administrators are responsible for creating organizations. For more information about the Grafana Server Administrator role, refer to [Grafana server administrators]({{< relref "../roles-and-permissions/#grafana-server-administrators" >}}). +Grafana Server Administrators are responsible for creating organizations. For more information about the Grafana Server Administrator role, refer to [Grafana server administrators](../roles-and-permissions/#grafana-server-administrators). ## View a list of organizations @@ -80,9 +80,9 @@ Create an organization when you want to isolate dashboards and other resources f 1. In the Preferences section, select a home dashboard, time zone, and week start. - For more information about preferences, refer to [Preferences]({{< relref "../organization-preferences/" >}}). + For more information about preferences, refer to [Preferences](../organization-preferences/). -For more information about adding users to an organization, refer to [Add a user to an organization]({{< relref "../user-management/server-user-management/add-remove-user-to-org/" >}}). +For more information about adding users to an organization, refer to [Add a user to an organization](../user-management/server-user-management/add-remove-user-to-org/). ## Delete an organization diff --git a/docs/sources/administration/organization-preferences/index.md b/docs/sources/administration/organization-preferences/index.md index 590370bf27f..6ff4cf25dc0 100644 --- a/docs/sources/administration/organization-preferences/index.md +++ b/docs/sources/administration/organization-preferences/index.md @@ -20,9 +20,9 @@ Grafana preferences are basic settings. They control the Grafana UI theme, home Preferences are sometimes confusing because they can be set at four different levels, listed from highest level to lowest: -- **Server -** Affects all users on the Grafana server. Set by a [Grafana server admin]({{< relref "../roles-and-permissions/#grafana-server-administrators" >}}). -- **Organization -** Affects all users in an organization. Set by an [Organization admin]({{< relref "../roles-and-permissions/#organization-roles" >}}). -- **Team -** Affects all users assigned to a team. Set by an Organization Admin or Team Admin. To learn more about these roles, refer to [Teams and permissions]({{< relref "../roles-and-permissions/#teams-and-permissions" >}}). +- **Server -** Affects all users on the Grafana server. Set by a [Grafana server admin](../roles-and-permissions/#grafana-server-administrators). +- **Organization -** Affects all users in an organization. Set by an [Organization admin](../roles-and-permissions/#organization-roles). +- **Team -** Affects all users assigned to a team. Set by an Organization Admin or Team Admin. To learn more about these roles, refer to [Teams and permissions](../roles-and-permissions/#teams-and-permissions). - **User account -** Affects the individual user. Set by the user on their own account. The lowest level always takes precedence. For example, if a user sets their theme to **Light**, then their visualization of Grafana displays the light theme. Nothing at any higher level can override that. @@ -33,7 +33,7 @@ If the user is aware of the change and intended it, then that's great! But if th In Grafana, you can change your names and emails associated with groups or accounts in the Settings or Preferences. This topic provides instructions for each task. -Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions]({{< relref "../roles-and-permissions/" >}}). +Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions](../roles-and-permissions/). ### Change organization name @@ -75,13 +75,13 @@ To change the team name or email, follow these steps: ### Change user name or email -To learn how to edit your user information, refer to [Edit your profile]({{< relref "../user-management/user-preferences/#edit-your-profile" >}}). +To learn how to edit your user information, refer to [Edit your profile](../user-management/user-preferences/#edit-your-profile). ## Change Grafana UI theme In Grafana, you can modify the UI theme configured in the Settings or Preferences. Set the UI theme for the server, an organization, a team, or your personal user account using the instructions in this topic. -Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions]({{< relref "../roles-and-permissions/" >}}). +Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions](../roles-and-permissions/). ### Theme options @@ -105,9 +105,9 @@ Here is an example of the light theme. ### Change server UI theme -As a Grafana server administrator, you can change the default Grafana UI theme for all users who are on the server by setting the [default_theme]({{< relref "../../setup-grafana/configure-grafana/#default_theme" >}}) option in the Grafana configuration file. +As a Grafana server administrator, you can change the default Grafana UI theme for all users who are on the server by setting the [default_theme](../../setup-grafana/configure-grafana/#default_theme) option in the Grafana configuration file. -To see what the current settings are, refer to [View server settings]({{< relref "../stats-and-license#view-server-settings" >}}). +To see what the current settings are, refer to [View server settings](../stats-and-license/#view-server-settings). ### Change organization UI theme @@ -141,11 +141,11 @@ You can change the UI theme for your user account. This setting overrides UI the By default, Grafana uses the timezone in your web browser. However, you can override this setting at the server, organization, team, or individual user level. This topic provides instructions for each task. -Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions]({{< relref "../roles-and-permissions/" >}}). +Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions](../roles-and-permissions/). ### Set server timezone -Grafana server administrators can choose a default timezone for all users on the server by setting the [default_timezone]({{< relref "../../setup-grafana/configure-grafana/#default_timezone" >}}) option in the Grafana configuration file. +Grafana server administrators can choose a default timezone for all users on the server by setting the [default_timezone](../../setup-grafana/configure-grafana/#default_timezone) option in the Grafana configuration file. ### Set organization timezone @@ -179,7 +179,7 @@ You can change the timezone for your user account. This setting overrides timezo The home dashboard you set is the one all users will see by default when they log in. Click the Grafana icon or **Home** in the breadcrumb to return to it. You can set the home dashboard for the server, an organization, a team, or your personal user account. This topic provides instructions for each task. -Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions]({{< relref "../roles-and-permissions/" >}}). +Some tasks require certain permissions. For more information about roles, refer to [Roles and permissions](../roles-and-permissions/). ### Set the home dashboard for the server @@ -194,7 +194,7 @@ Users with the Grafana Server Admin flag on their account or access to the confi #### Use a JSON file as the home dashboard 1. Save your JSON file somewhere that Grafana can access it. For example, in the Grafana `data` folder of Grafana. -1. Update your configuration file to set the path to the JSON file. Refer to [default_home_dashboard_path]({{< relref "../../setup-grafana/configure-grafana/#default_home_dashboard_path" >}}) for more information about modifying the Grafana configuration files. +1. Update your configuration file to set the path to the JSON file. Refer to [default_home_dashboard_path](../../setup-grafana/configure-grafana/#default_home_dashboard_path) for more information about modifying the Grafana configuration files. ```ini [dashboards] @@ -244,7 +244,7 @@ You can choose your own personal home dashboard. This setting overrides all home ### Change server language -Grafana server administrators can change the default Grafana UI language for all users on the server by setting the [default_language]({{< relref "../../setup-grafana/configure-grafana/#default_language" >}}) option in the Grafana configuration file. +Grafana server administrators can change the default Grafana UI language for all users on the server by setting the [default_language](../../setup-grafana/configure-grafana/#default_language) option in the Grafana configuration file. ### Change organization language diff --git a/docs/sources/administration/plugin-management/index.md b/docs/sources/administration/plugin-management/index.md index 09566ccf250..1f43832b69b 100644 --- a/docs/sources/administration/plugin-management/index.md +++ b/docs/sources/administration/plugin-management/index.md @@ -56,17 +56,17 @@ Use app plugins when you want an out-of-the-box monitoring experience. ### Managing access for app plugins -Customize access to app plugins with [RBAC]({{< relref "../roles-and-permissions/access-control/rbac-for-app-plugins" >}}). +Customize access to app plugins with [RBAC](../roles-and-permissions/access-control/rbac-for-app-plugins/). By default, the Viewer, Editor and Admin roles have access to all app plugins that their Organization role allows them to access. Access is granted by the `fixed:plugins.app:reader` role. {{% admonition type="note" %}} -To prevent users from seeing an app plugin, refer to [these permissions scenarios]({{< relref "../roles-and-permissions/access-control/plan-rbac-rollout-strategy#prevent-viewers-from-accessing-an-app-plugin" >}}). +To prevent users from seeing an app plugin, refer to [these permissions scenarios](../roles-and-permissions/access-control/plan-rbac-rollout-strategy/#prevent-viewers-from-accessing-an-app-plugin). {{% /admonition %}} ## Plugin catalog -The Grafana plugin catalog allows you to browse and manage plugins from within Grafana. Only Grafana server administrators and Organization administrators can access and use the plugin catalog. For more information about Grafana roles and permissions, refer to [Roles and permissions]({{< relref "../administration/roles-and-permissions" >}}). +The Grafana plugin catalog allows you to browse and manage plugins from within Grafana. Only Grafana server administrators and Organization administrators can access and use the plugin catalog. For more information about Grafana roles and permissions, refer to [Roles and permissions](../roles-and-permissions/). The following access rules apply depending on the user role: @@ -88,7 +88,7 @@ The Grafana plugin catalog is designed to work with a single Grafana server inst _Video shows the Plugin catalog in a previous version of Grafana._ {{% admonition type="note" %}} -If required, the Grafana plugin catalog can be disabled using the `plugin_admin_enabled` flag in the [configuration]({{< relref "../../setup-grafana/configure-grafana/#plugin_admin_enabled" >}}) file. +If required, the Grafana plugin catalog can be disabled using the `plugin_admin_enabled` flag in the [configuration](../../setup-grafana/configure-grafana/#plugin_admin_enabled) file. {{% /admonition %}} @@ -114,7 +114,7 @@ There are also additional ways to install plugins depending on your setup. #### Install a plugin using Grafana CLI -Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line. For more information about Grafana CLI plugin commands, refer to [Plugin commands]({{< relref "../../cli/#plugins-commands" >}}). +Grafana CLI allows you to install, upgrade, and manage your Grafana plugins using a command line. For more information about Grafana CLI plugin commands, refer to [Plugin commands](../../cli/#plugins-commands). #### Install a plugin from a ZIP file @@ -126,15 +126,15 @@ Download the archive containing the plugin assets, and install it by extracting unzip my-plugin-0.2.0.zip -d YOUR_PLUGIN_DIR/my-plugin ``` -The path to the plugin directory is defined in the configuration file. For more information, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana/#plugins" >}}). +The path to the plugin directory is defined in the configuration file. For more information, refer to [Configuration](../../setup-grafana/configure-grafana/#plugins). -#### Install a plugin using Grafana configuration +#### Install a plugin using Grafana configuration {{% admonition type="note" %}} This feature requires Grafana 11.5.0 or later. {{% /admonition %}} -You can install plugins by adding the plugin ID to the `plugins.preinstall` section in the Grafana configuration file. This prevents the plugin from being accidentally uninstalled and can be auto-updated. For more information, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana/#plugins" >}}). +You can install plugins by adding the plugin ID to the `plugins.preinstall` section in the Grafana configuration file. This prevents the plugin from being accidentally uninstalled and can be auto-updated. For more information, refer to [Configuration](../../setup-grafana/configure-grafana/#plugins). #### Install a plugin in air-gapped environment @@ -224,7 +224,7 @@ All plugins are signed under a _signature level_. The signature level determines Unsigned plugins are not supported in Grafana Cloud. {{% /admonition %}} -We strongly recommend that you don't run unsigned plugins in your Grafana instance. However, if you're aware of the risks and you still want to load an unsigned plugin, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana/#allow_loading_unsigned_plugins" >}}). +We strongly recommend that you don't run unsigned plugins in your Grafana instance. However, if you're aware of the risks and you still want to load an unsigned plugin, refer to [Configuration](../../setup-grafana/configure-grafana/#allow_loading_unsigned_plugins). If you've allowed loading of an unsigned plugin, then Grafana writes a warning message to the server log: @@ -236,6 +236,32 @@ WARN[06-01|16:45:59] Running an unsigned plugin pluginID= If you're developing a plugin, then you can enable development mode to allow all unsigned plugins. {{% /admonition %}} +## Integrate plugins + +You can configure your Grafana instance to let the frontends of installed plugins directly communicate locally with the backends of other installed plugins. By default, you can only communicate with plugin backends remotely. You can use this configuration to, for example, enable a [canvas panel](https://grafana.com/docs/grafana/latest/panels-visualizations/visualizations/canvas/) to call an application resource API that is permitted by the `actions_allow_post_url` option. + +To enable backend communication between plugins: + +1. Set the plugins you want to communicate with. In your configuration file (`grafana.ini` or `custom.ini` depending on your operating system) remove the semicolon to enable and then set the following configuration option: + + ``` + actions_allow_post_url= + ``` + + This is a comma-separated list that uses glob matching. + + - To allow access to all plugins that have a backend: + + ``` + actions_allow_post_url=/api/plugins/* + ``` + + - To access to the backend of only one plugin: + + ``` + actions_allow_post_url=/api/plugins/ + ``` + ## Plugin Frontend Sandbox {{% admonition type="caution" %}} @@ -256,7 +282,7 @@ Plugins running inside the Frontend Sandbox should continue to work normally wit The Frontend Sandbox feature is currently behind the `pluginsFrontendSandbox` feature flag. To enable it, you'll need to: -1. Enable the feature flag in your Grafana configuration. For more information about enabling feature flags, refer to [Configure feature toggles](/setup-grafana/configure-grafana/feature-toggles/). +1. Enable the feature flag in your Grafana configuration. For more information about enabling feature flags, refer to [Configure feature toggles](/docs/grafana//setup-grafana/configure-grafana/feature-toggles/). 2. For self-hosted Grafana installations, add the plugin IDs you want to sandbox in the `security` section using the `enable_frontend_sandbox_for_plugins` configuration option. diff --git a/docs/sources/administration/provisioning/index.md b/docs/sources/administration/provisioning/index.md index 5c164a708aa..bbbbec185cd 100644 --- a/docs/sources/administration/provisioning/index.md +++ b/docs/sources/administration/provisioning/index.md @@ -20,7 +20,7 @@ This makes GitOps more natural since data sources and dashboards can be defined ## Configuration file -Refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana/" >}}) for more information on what you can configure in `grafana.ini`. +Refer to [Configuration](../../setup-grafana/configure-grafana/) for more information on what you can configure in `grafana.ini`. ### Configuration file locations @@ -73,7 +73,7 @@ Therefore, we heavily rely on the expertise of the community. ## Data sources -You can manage data sources in Grafana by adding YAML configuration files in the [`provisioning/datasources`]({{< relref "../../setup-grafana/configure-grafana#provisioning" >}}) directory. +You can manage data sources in Grafana by adding YAML configuration files in the [`provisioning/datasources`](../../setup-grafana/configure-grafana/#provisioning) directory. Each configuration file can contain a list of `datasources` to add or update during startup. If the data source already exists, Grafana reconfigures it to match the provisioned configuration file. @@ -92,7 +92,7 @@ This prevents old configurations from overwriting newer ones if you have differe ### Example data source configuration file -This example provisions a [Graphite data source]({{< relref "../../datasources/graphite" >}}): +This example provisions a [Graphite data source](../../datasources/graphite/): ```yaml # Configuration file version @@ -172,14 +172,14 @@ datasources: editable: false ``` -For provisioning examples of specific data sources, refer to that [data source's documentation]({{< relref "../../datasources" >}}). +For provisioning examples of specific data sources, refer to that [data source's documentation](../../datasources/). #### JSON data Not all data sources have the same configuration settings. Only the most common fields are included in examples. To provision the rest of a data source's settings, include them as a JSON blob in the `jsonData` field. -Common settings in the [built-in core data sources]({{< relref "../../datasources#built-in-core-data-sources" >}}) include: +Common settings in the [built-in core data sources](../../datasources/#built-in-core-data-sources) include: {{< admonition type="note" >}} Data sources tagged with _HTTP\*_ communicate using the HTTP protocol, which includes all core data source plugins except MySQL, PostgreSQL, and MSSQL. @@ -240,11 +240,11 @@ Data sources tagged with _HTTP\*_ communicate using the HTTP protocol, which inc | implementation | string | AlertManager | The implementation of the AlertManager data source, such as `prometheus`, `cortex` or `mimir` | | handleGrafanaManagedAlerts | boolean | AlertManager | When enabled, Grafana-managed alerts are sent to this Alertmanager | -For examples of specific data sources' JSON data, refer to that [data source's documentation]({{< relref "../../datasources" >}}). +For examples of specific data sources' JSON data, refer to that [data source's documentation](../../datasources/). #### Secure JSON Data -Secure JSON data is a map of settings that are encrypted with a [secret key]({{< relref "../../setup-grafana/configure-grafana#secret_key" >}}) from the Grafana configuration. +Secure JSON data is a map of settings that are encrypted with a [secret key](../../setup-grafana/configure-grafana/#secret_key) from the Grafana configuration. The encryption hides content from the users of the application. This should be used for storing the TLS Cert and password that Grafana appends to the request on the server side. All of these settings are optional. @@ -285,7 +285,7 @@ datasources: ## Plugins -You can manage plugin applications in Grafana by adding one or more YAML configuration files in the [`provisioning/plugins`]({{< relref "../../setup-grafana/configure-grafana#provisioning" >}}) directory. +You can manage plugin applications in Grafana by adding one or more YAML configuration files in the [`provisioning/plugins`](../../setup-grafana/configure-grafana/#provisioning) directory. Each configuration file can contain a list of `apps` that update during start up. Grafana updates each app to match the configuration file. @@ -320,7 +320,7 @@ apps: ## Dashboards -You can manage dashboards in Grafana by adding one or more YAML configuration files in the [`provisioning/dashboards`]({{< relref "../../setup-grafana/configure-grafana#dashboards" >}}) directory. +You can manage dashboards in Grafana by adding one or more YAML configuration files in the [`provisioning/dashboards`](../../setup-grafana/configure-grafana/#dashboards) directory. Each configuration file can contain a list of `dashboards providers` that load dashboards into Grafana from the local filesystem. The dashboard provider configuration file looks somewhat like this: @@ -380,7 +380,7 @@ The JSON definition in the input field when using `Copy JSON to Clipboard` or `S ### Reusable dashboard URLs -If the dashboard in the JSON file contains an [UID]({{< relref "../../dashboards/build-dashboards/view-dashboard-json-model" >}}), Grafana forces insert/update on that UID. +If the dashboard in the JSON file contains an [UID](../../dashboards/build-dashboards/view-dashboard-json-model/), Grafana forces insert/update on that UID. This allows you to migrate dashboards between Grafana instances and provisioning Grafana from configuration without breaking the URLs given because the new dashboard URL uses the UID as identifier. When Grafana starts, it updates and inserts all dashboards available in the configured folders. If you modify the file, then the dashboard is also updated. @@ -436,7 +436,7 @@ You can't create nested folders structures, where you have folders within folder ## Alerting -For information on provisioning Grafana Alerting, refer to [Provision Grafana Alerting resources]({{< relref "../../alerting/set-up/provision-alerting-resources/" >}}). +For information on provisioning Grafana Alerting, refer to [Provision Grafana Alerting resources](../../alerting/set-up/provision-alerting-resources/). ### Supported settings @@ -479,6 +479,7 @@ The following sections detail the supported settings and secure settings for eac | mentionGroups | | | mentionChannel | | | token | yes | +| color | | #### Alert notification `victorops` @@ -650,5 +651,5 @@ The following sections detail the supported settings and secure settings for eac Grafana Enterprise supports: -- [Provisioning role-based access control with Grafana]({{< relref "../roles-and-permissions/access-control/rbac-grafana-provisioning/" >}}) -- [Provisioning role-based access control with Terraform]({{< relref "../roles-and-permissions/access-control/rbac-terraform-provisioning/" >}}) +- [Provisioning role-based access control with Grafana](../roles-and-permissions/access-control/rbac-grafana-provisioning/) +- [Provisioning role-based access control with Terraform](../roles-and-permissions/access-control/rbac-terraform-provisioning/) diff --git a/docs/sources/administration/recorded-queries/index.md b/docs/sources/administration/recorded-queries/index.md index d61585f0da5..fdeaa7da656 100644 --- a/docs/sources/administration/recorded-queries/index.md +++ b/docs/sources/administration/recorded-queries/index.md @@ -35,7 +35,7 @@ Recorded queries only work with backend data source plugins. Refer to [Backend d - single row and column - A query that returns a single row and column. - row count - A query that returns meaningful rows to be counted. -- expression - Any expression. To learn more about creating and using expressions, see [Write expression queries]({{< relref "../../panels-visualizations/query-transform-data/expression-queries" >}}). +- expression - Any expression. To learn more about creating and using expressions, see [Write expression queries](../../panels-visualizations/query-transform-data/expression-queries/). - dataplane numeric - A query that returns [dataplane numeric kind](/developers/dataplane/numeric) data. After a recorded query is created or enabled, it immediately creates a snapshot and continues to create snapshots at the set interval. The recorded query stops taking snapshots when it is disabled, deleted, or when Grafana is not running. Data points are gathered in the backend by running the recorded query and forwarding each result to a remote-write enabled Prometheus instance. @@ -48,7 +48,7 @@ To use a recorded query, create one and add it to a dashboard. After that, it ca 1. Find/create a query you want to record on a dashboard in an edit panel. The query must only return one row and column. If it returns more, you can still record the number of results returned using the “count” option. - The query's data source must be a backend data source. - - Expressions can be used to aggregate data from a time series query. Refer to [Write expression queries]({{< relref "../../panels-visualizations/query-transform-data/expression-queries" >}}) to learn more about creating and using expressions. + - Expressions can be used to aggregate data from a time series query. Refer to [Write expression queries](../../panels-visualizations/query-transform-data/expression-queries/) to learn more about creating and using expressions. 1. Click the record query button located in the top right of the query editor. 1. Enter recorded query information. All fields are required unless otherwise indicated. - Name - Name of the recorded query. @@ -68,7 +68,7 @@ You can add existing recorded queries to panels in a dashboard. For each recorde 1. If you want to filter recorded queries by data source, select a data source from the filter by data source drop down menu. 1. Click the `Add` button on your recorded query to add it to the panel. -After adding your recorded query to the panel, the panel data source will become `-- Mixed --`. Your recorded query is represented by a `Prometheus` query with a name label matching your recorded query name. Refer to [Prometheus]({{< relref "../../datasources/prometheus/" >}}) to learn more about the `Prometheus` data source. +After adding your recorded query to the panel, the panel data source will become `-- Mixed --`. Your recorded query is represented by a `Prometheus` query with a name label matching your recorded query name. Refer to [Prometheus](../../datasources/prometheus/) to learn more about the `Prometheus` data source. If after adding a recorded query, a query with a `-- Mixed --` data source instead of `Prometheus` data source appears, this could mean that a Prometheus remote write target was not set up for recorded queries. Refer to [Remote write target](#remote-write-target) to set up a remote write point. diff --git a/docs/sources/administration/roles-and-permissions/_index.md b/docs/sources/administration/roles-and-permissions/_index.md index 134482723b4..29c69087072 100644 --- a/docs/sources/administration/roles-and-permissions/_index.md +++ b/docs/sources/administration/roles-and-permissions/_index.md @@ -34,14 +34,14 @@ If you are running Grafana Enterprise, you can also control access to data sourc A Grafana server administrator manages server-wide settings and access to resources such as organizations, users, and licenses. Grafana includes a default server administrator that you can use to manage all of Grafana, or you can divide that responsibility among other server administrators that you create. {{% admonition type="note" %}} -The server administrator role does not mean that the user is also a Grafana [organization administrator]({{< relref "#organization-roles" >}}). +The server administrator role does not mean that the user is also a Grafana [organization administrator](#organization-roles). {{% /admonition %}} A server administrator can perform the following tasks: - Manage users and permissions - Create, edit, and delete organizations -- View server-wide settings defined in the [Configuration]({{< relref "../../setup-grafana/configure-grafana/" >}}) file +- View server-wide settings defined in the [Configuration](../../setup-grafana/configure-grafana/) file - View Grafana server statistics, including total users and active sessions - Upgrade the server to Grafana Enterprise. @@ -49,7 +49,7 @@ A server administrator can perform the following tasks: The server administrator role does not exist in Grafana Cloud. {{% /admonition %}} -To assign or remove server administrator privileges, see [Server user management]({{< relref "../user-management/server-user-management/assign-remove-server-admin-privileges/" >}}). +To assign or remove server administrator privileges, see [Server user management](../user-management/server-user-management/assign-remove-server-admin-privileges/). ## Organization users and permissions @@ -69,11 +69,11 @@ Permissions assigned to a user within an organization control the extent to whic - library panels - API keys -For more information about managing organization users, see [User management]({{< relref "../user-management/manage-org-users/" >}}). +For more information about managing organization users, see [User management](../user-management/manage-org-users/). ### Organization roles -Organization role-based permissions are global, which means that each permission level applies to all Grafana resources within an given organization. For example, an editor can see and update _all_ dashboards in an organization, unless those dashboards have been specifically restricted using [dashboard permissions]({{< relref "../user-management/manage-dashboard-permissions/" >}}). +Organization role-based permissions are global, which means that each permission level applies to all Grafana resources within an given organization. For example, an editor can see and update _all_ dashboards in an organization, unless those dashboards have been specifically restricted using [dashboard permissions](../user-management/manage-dashboard-permissions/). Grafana uses the following roles to control user access: @@ -117,32 +117,9 @@ You can specify the following permissions to dashboards and folders. > Important: When a user creates a dashboard or a folder they are automatically granted **Admin** permissions for it. -For more information about assigning dashboard folder permissions, refer to [Grant dashboard folder permissions]({{< relref "../user-management/manage-dashboard-permissions/#grant-dashboard-folder-permissions" >}}). +For more information about assigning dashboard folder permissions, refer to [Grant dashboard folder permissions](../user-management/manage-dashboard-permissions/#grant-dashboard-folder-permissions). -For more information about assigning dashboard permissions, refer to [Grant dashboard permissions]({{< relref "../user-management/manage-dashboard-permissions/#grant-dashboard-permissions" >}}). - -## Editors with administrator permissions - -If you have access to the Grafana server, you can modify the default editor role so that editors can use administrator permissions to manage dashboard folders, dashboards, and teams that they create. - -{{% admonition type="note" %}} -This permission does not allow editors to manage folders, dashboards, and teams that they do not create. -{{% /admonition %}} - -This setting can be used to enable self-organizing teams to administer their own dashboards. - -For more information about assigning administrator permissions to editors, refer to [Grant editors administrator permissions]({{< relref "../user-management/server-user-management/grant-editor-admin-permissions/" >}}). - -## Viewers with dashboard preview and Explore permissions - -If you have access to the Grafana server, you can modify the default viewer role so that viewers can: - -- Edit and preview dashboards, but cannot save their changes or create new dashboards. -- Access and use [Explore]({{< relref "../../explore" >}}). - -Extending the viewer role is useful for public Grafana installations where you want anonymous users to be able to edit panels and queries, but not be able to save or create new dashboards. - -For more information about assigning dashboard preview permissions to viewers, refer to [Enable viewers to preview dashboards and use Explore]({{< relref "../user-management/manage-dashboard-permissions/#enable-viewers-to-edit-but-not-save-dashboards-and-use-explore" >}}). +For more information about assigning dashboard permissions, refer to [Grant dashboard permissions](../user-management/manage-dashboard-permissions/#grant-dashboard-permissions). ## Teams and permissions @@ -153,15 +130,15 @@ You can assign a team member one of the following permissions: - **Member**: Includes the user as a member of the team. Members do not have team administrator privileges. - **Admin**: Administrators have permission to manage various aspects of the team, including team membership, permissions, and settings. -Because teams exist inside an organization, the organization administrator can manage all teams. When the `editors_can_admin` setting is enabled, editors can create teams and manage teams that they create. For more information about the `editors_can_admin` setting, refer to [Grant editors administrator permissions]({{< relref "../user-management/server-user-management/grant-editor-admin-permissions/" >}}). +Because teams exist inside an organization, the organization administrator can manage all teams. -For details on managing teams, see [Team management]({{< relref "../team-management/" >}}). +For details on managing teams, see [Team management](../team-management/). ## Grafana Enterprise user permissions features While Grafana OSS includes a robust set of permissions and settings that you can use to manage user access to server and organization resources, you might find that you require additional capabilities. -[Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise">}}) provides the following permissions-related features: +[Grafana Enterprise](../../introduction/grafana-enterprise/) provides the following permissions-related features: - Data source permissions - Role-based access control (RBAC) @@ -170,13 +147,13 @@ While Grafana OSS includes a robust set of permissions and settings that you can By default, a user can query any data source in an organization, even if the data source is not linked to the user's dashboards. -Data source permissions enable you to restrict data source query permissions to specific **Users**, **Service Accounts**, and **Teams**. For more information about assigning data source permissions, refer to [Data source permissions]({{< relref "../data-source-management/#data-source-permissions/" >}}). +Data source permissions enable you to restrict data source query permissions to specific **Users**, **Service Accounts**, and **Teams**. For more information about assigning data source permissions, refer to [Data source permissions](../data-source-management/#data-source-permissions/). ### Role-based access control RBAC provides you a way of granting, changing, and revoking user read and write access to Grafana resources, such as users, reports, and authentication. -For more information about RBAC, refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control/" >}}). +For more information about RBAC, refer to [Role-based access control](access-control/). ### Learn more diff --git a/docs/sources/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/index.md b/docs/sources/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/index.md index 09c2fc4c3d4..e04c2fcecf2 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/index.md @@ -369,9 +369,11 @@ Here are two ways to achieve this: # Update the role curl -H 'Authorization: Bearer glsa_kcVxDhZtu5ISOZIEt' -H 'Content-Type: application/json' \ - -X PUT-d @/tmp/basic_viewer.json '/api/access-control/roles/basic_viewer' + -X PUT -d @/tmp/basic_viewer.json '/api/access-control/roles/basic_viewer' ``` + The token that is used in this request is the [service account token](ref:service-accounts). + - Or use the `role > from` list and `permission > state` option of your provisioning file: ```yaml @@ -394,6 +396,20 @@ Here are two ways to achieve this: state: 'present' ``` + If your goal is to remove an access to an app you should remove it from the role and update it. For example: + + ```bash + # Fetch the role, modify it to remove permissions to kentik-connect-app and increment role version + curl -H 'Authorization: Bearer glsa_kcVxDhZtu5ISOZIEt' \ + -X GET '/api/access-control/roles/basic_viewer' | \ + jq 'del(.created)| del(.updated) | del(.permissions[].created) | del(.permissions[].updated) | .version += 1' | \ + jq 'del(.permissions[] | select (.action == "plugins.app:access" and .scope == "plugins:id:kentik-connect-app"))' + + # Update the role + curl -H 'Authorization: Bearer glsa_kcVxDhZtu5ISOZIEt' -H 'Content-Type: application/json' \ + -X PUT -d @/tmp/basic_viewer.json '/api/access-control/roles/basic_viewer' + ``` + ### Manage user permissions through teams In the scenario where you want users to grant access by the team they belong to, we recommend to set users role to `No Basic Role` and let the team assignment assign the role instead. diff --git a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md index f651becaa4e..8458e4d9355 100644 --- a/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md +++ b/docs/sources/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions/index.md @@ -58,8 +58,8 @@ The following tables list permissions associated with basic and fixed roles. | ------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | Grafana Admin | `basic_grafana_admin` | `fixed:roles:reader`
`fixed:roles:writer`
`fixed:users:reader`
`fixed:users:writer`
`fixed:org.users:reader`
`fixed:org.users:writer`
`fixed:ldap:reader`
`fixed:ldap:writer`
`fixed:stats:reader`
`fixed:settings:reader`
`fixed:settings:writer`
`fixed:provisioning:writer`
`fixed:organization:reader`
`fixed:organization:maintainer`
`fixed:licensing:reader`
`fixed:licensing:writer`
`fixed:datasources.caching:reader`
`fixed:datasources.caching:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:plugins:maintainer`
`fixed:authentication.config:writer`
`fixed:library.panels:creator`
`fixed:library.panels:reader`
`fixed:library.panels:general.reader`
`fixed:library.panels:writer`
`fixed:library.panels:general.writer`
`fixed:groupsync:writer`
`fixed:migrationassistant:migrator` | Default [Grafana server administrator](/docs/grafana//administration/roles-and-permissions/#grafana-server-administrators) assignments. | | Admin | `basic_admin` | `fixed:reports:reader`
`fixed:reports:writer`
`fixed:datasources:reader`
`fixed:datasources:writer`
`fixed:organization:writer`
`fixed:datasources.permissions:reader`
`fixed:datasources.permissions:writer`
`fixed:teams:writer`
`fixed:dashboards:reader`
`fixed:dashboards:writer`
`fixed:dashboards.permissions:reader`
`fixed:dashboards.permissions:writer`
`fixed:dashboards.public:writer`
`fixed:folders:reader`
`fixed:folders:writer`
`fixed:folders.permissions:reader`
`fixed:folders.permissions:writer`
`fixed:alerting:writer`
`fixed:apikeys:reader`
`fixed:apikeys:writer`
`fixed:alerting.provisioning.secrets:reader`
`fixed:alerting.provisioning:writer`
`fixed:datasources.caching:reader`
`fixed:datasources.caching:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:plugins:writer`
`fixed:library.panels:creator`
`fixed:library.panels:reader`
`fixed:library.panels:general.reader`
`fixed:library.panels:writer`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer`
`fixed:groupsync:writer` | Default [Grafana organization administrator](ref:rbac-basic-roles) assignments. | -| Editor | `basic_editor` | `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:teams:creator` if the `editors_can_admin` configuration flag is enabled
`fixed:alerting:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:creator`
`fixed:library.panels:general.reader`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | -| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader`
`fixed:datasources:explorer` if the `viewers_can_edit` configuration flag is enabled | Default [Viewer](ref:rbac-basic-roles) assignments. | +| Editor | `basic_editor` | `fixed:datasources:explorer`
`fixed:dashboards:creator`
`fixed:folders:creator`
`fixed:annotations:writer`
`fixed:alerting:writer`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:creator`
`fixed:library.panels:general.reader`
`fixed:library.panels:general.writer`
`fixed:alerting.provisioning.status:writer` | Default [Editor](ref:rbac-basic-roles) assignments. | +| Viewer | `basic_viewer` | `fixed:datasources.id:reader`
`fixed:organization:reader`
`fixed:annotations:reader`
`fixed:annotations.dashboard:writer`
`fixed:alerting:reader`
`fixed:plugins.app:reader`
`fixed:dashboards.insights:reader`
`fixed:datasources.insights:reader`
`fixed:library.panels:general.reader` | Default [Viewer](ref:rbac-basic-roles) assignments. | | No Basic Role | n/a | | Default [No Basic Role](ref:rbac-basic-roles) | ## Fixed role definitions @@ -94,7 +94,7 @@ To learn how to use the roles API to determine the role UUIDs, refer to [Manage | `fixed:authentication.config:writer` | `fixed_0rYhZ2Qnzs8AdB1nX7gexk3fHDw` | `settings:read` for scope `settings:auth.saml:*`
`settings:write` for scope `settings:auth.saml:*` | Read and update authentication and SAML settings. | | `fixed:dashboards:creator` | `fixed_ZorKUcEPCM01A1fPakEzGBUyU64` | `dashboards:create`
`folders:read` | Create dashboards. | | `fixed:dashboards:reader` | `fixed_Sgr67JTOhjQGFlzYRahOe45TdWM` | `dashboards:read` | Read all dashboards. | -| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:edit`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | +| `fixed:dashboards:writer` | `fixed_OK2YOQGIoI1G031hVzJB6rAJQAs` | All permissions from `fixed:dashboards:reader` and
`dashboards:write`
`dashboards:delete`
`dashboards:create`
`dashboards.permissions:read`
`dashboards.permissions:write` | Read, create, update, and delete all dashboards. | | `fixed:dashboards.insights:reader` | `fixed_JlBJ2_gizP8zhgaeGE2rjyZe2Rs` | `dashboards.insights:read` | Read dashboard insights data and see presence indicators. | | `fixed:dashboards.permissions:reader` | `fixed_f17oxuXW_58LL8mYJsm4T_mCeIw` | `dashboards.permissions:read` | Read all dashboard permissions. | | `fixed:dashboards.permissions:writer` | `fixed_CcznxhWX_Yqn8uWMXMQ-b5iFW9k` | All permissions from `fixed:dashboards.permissions:reader` and
`dashboards.permissions:write` | Read and update all dashboard permissions. | diff --git a/docs/sources/administration/stats-and-license/index.md b/docs/sources/administration/stats-and-license/index.md index 1643fd505cf..ec926f73c2f 100644 --- a/docs/sources/administration/stats-and-license/index.md +++ b/docs/sources/administration/stats-and-license/index.md @@ -25,11 +25,11 @@ This setting contains information about tools that Grafana Server Admins can use ## View Grafana server settings -> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions. +> Refer to [Role-based access control](../roles-and-permissions/access-control/) in Grafana Enterprise to understand how you can control access with RBAC permissions. -If you are a Grafana server administrator, use the Settings tab to view the settings that are applied to your Grafana server via the [Configuration]({{< relref "../../setup-grafana/configure-grafana#configuration-file-location" >}}) file and any environmental variables. +If you are a Grafana server administrator, use the Settings tab to view the settings that are applied to your Grafana server via the [Configuration](../../setup-grafana/configure-grafana/#configuration-file-location) file and any environmental variables. -> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions#grafana-server-administrators" >}}). +> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions](../roles-and-permissions/#grafana-server-administrators). ### View server settings @@ -38,15 +38,15 @@ If you are a Grafana server administrator, use the Settings tab to view the sett ### Available settings -For a full list of server settings, refer to [Configuration]({{< relref "../../setup-grafana/configure-grafana#server" >}}). +For a full list of server settings, refer to [Configuration](../../setup-grafana/configure-grafana/#server). ## View Grafana server stats -> Refer to [Role-based access control]({{< relref "../roles-and-permissions/access-control" >}}) in Grafana Enterprise to understand how you can control access with RBAC permissions. +> Refer to [Role-based access control](../roles-and-permissions/access-control/) in Grafana Enterprise to understand how you can control access with RBAC permissions. If you are a Grafana server admin, then you can view useful statistics about your Grafana server in the Stats & Licensing tab. -> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions]({{< relref "../roles-and-permissions#grafana-server-administrators" >}}). +> **Note:** Only Grafana server administrators can access the **Server Admin** menu. For more information about about administrative permissions, refer to [Roles and permissions](../roles-and-permissions/#grafana-server-administrators). ### View server stats diff --git a/docs/sources/administration/user-management/manage-dashboard-permissions/index.md b/docs/sources/administration/user-management/manage-dashboard-permissions/index.md index e87d0193fcc..88087df89c2 100644 --- a/docs/sources/administration/user-management/manage-dashboard-permissions/index.md +++ b/docs/sources/administration/user-management/manage-dashboard-permissions/index.md @@ -14,7 +14,7 @@ weight: 500 Dashboard and folder permissions enable you to grant a viewer the ability to edit and save dashboard changes, or limit an editor's permission to modify a dashboard. -For more information about dashboard permissions, refer to [Dashboard permissions]({{< relref "../../roles-and-permissions/#dashboard-permissions" >}}). +For more information about dashboard permissions, refer to [Dashboard permissions](../../roles-and-permissions/#dashboard-permissions). ## Grant folder permissions @@ -23,7 +23,7 @@ When you grant user permissions for folders, that setting applies to all dashboa ### Before you begin - Ensure you have organization administrator privileges -- Identify the dashboard folder permissions you want to modify and the users, service accounts or teams to which you want to grant access. For more information about dashboard permissions, refer to [Dashboard permissions]({{< relref "../../roles-and-permissions/#dashboard-permissions" >}}). +- Identify the dashboard folder permissions you want to modify and the users, service accounts or teams to which you want to grant access. For more information about dashboard permissions, refer to [Dashboard permissions](../../roles-and-permissions/#dashboard-permissions). **To grant dashboard folder permissions**: @@ -63,29 +63,9 @@ Grant dashboard permissions when you want to restrict or enhance dashboard acces 1. Select the user, service account, team, or role. 1. Select the permission and click **Save**. -## Enable viewers to edit (but not save) dashboards and use Explore +# Edit dashboard permissions -By default, the viewer organization role does not allow viewers to create dashboards or use the Explore feature. However, by modifying a configuration setting, you can allow viewers to edit a panel and make changes to a dashboard but not save those changes. This setting also enables viewers to use the Explore feature. - -This modification is useful for public Grafana installations where you want anonymous users to be able to edit panels and queries but not save or create new dashboards. - -### Before you begin - -- Ensure that you have access to the Grafana server - -**To enable viewers to preview dashboards and use Explore**: - -1. Open the Grafana configuration file. - - For more information about the Grafana configuration file and its location, refer to [Configuration]({{< relref "../../../setup-grafana/configure-grafana/" >}}). - -1. Locate the `viewers_can_edit` parameter. -1. Set the `viewers_can_edit` value to `true`. -1. Save your changes and restart Grafana. - -## Edit dashboard permissions - -Edit dashboard permissions when you are want to enhance or restrict a user's access to a dashboard. For more information about dashboard permissions, refer to [Dashboard permissions]({{< relref "../../roles-and-permissions/#dashboard-permissions" >}}). +Edit dashboard permissions when you are want to enhance or restrict a user's access to a dashboard. For more information about dashboard permissions, refer to [Dashboard permissions](../../roles-and-permissions/#dashboard-permissions). ### Before you begin @@ -155,4 +135,4 @@ Folder permissions settings: Result: User1 has editor permissions for the folder because user1 has permissions on a folder that contains this folder. -> Refer to [Role-based access Control]({{< relref "../../roles-and-permissions/access-control/" >}}) in Grafana Enterprise to understand how to use RBAC permissions to restrict access to dashboards, folders, administrative functions, and other resources. +> Refer to [Role-based access Control](../../roles-and-permissions/access-control/) in Grafana Enterprise to understand how to use RBAC permissions to restrict access to dashboards, folders, administrative functions, and other resources. diff --git a/docs/sources/administration/user-management/manage-org-users/index.md b/docs/sources/administration/user-management/manage-org-users/index.md index 85c8a8bb882..1364e55882f 100644 --- a/docs/sources/administration/user-management/manage-org-users/index.md +++ b/docs/sources/administration/user-management/manage-org-users/index.md @@ -19,7 +19,7 @@ weight: 400 Organization administrators can invite users to join their organization. Organization users have access to organization resources based on their role, which is **Admin**, **Editor**, or **Viewer**. Permissions associated with each role determine the tasks a user can perform in the system. -For more information about organization user permissions, refer to [Organization users and permissions]({{< relref "../../roles-and-permissions/#organization-users-and-permissions" >}}). +For more information about organization user permissions, refer to [Organization users and permissions](../../roles-and-permissions/#organization-users-and-permissions). {{% admonition type="note" %}} Users added at the organization level will have access to all stacks and services by default, without the ability to be filtered by stack unless Single Sign-On (SSO) or Role-Based Access Control (RBAC) is implemented. @@ -41,15 +41,15 @@ You can see a list of users with accounts in your Grafana organization. If neces 1. Navigate to **Administration > Users and access > Users**. {{% admonition type="note" %}} -If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also [view a global list of users]({{< relref "../server-user-management#view-a-list-of-users" >}}) in the Server Admin section of Grafana. +If you have [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can also [view a global list of users](../server-user-management/#view-a-list-of-users) in the Server Admin section of Grafana. {{% /admonition %}} ## Change a user's organization permissions -Update user permissions when you want to enhance or restrict a user's access to organization resources. For more information about organization permissions, refer to [Organization roles]({{< relref "../../roles-and-permissions/#organization-roles" >}}). +Update user permissions when you want to enhance or restrict a user's access to organization resources. For more information about organization permissions, refer to [Organization roles](../../roles-and-permissions/#organization-roles). {{% admonition type="note" %}} -Organization roles sync from the authentication provider on user sign-in. To prevent synchronization of organization roles from the authentication provider regardless of their role in the authentication provider, then refer to the `skip_org_role_sync` setting in your Grafana configuration. Refer to [skip org role sync]({{< relref "../../../setup-grafana/configure-grafana/#authgrafana_com-skip_org_role_sync" >}}) for more information. +Organization roles sync from the authentication provider on user sign-in. To prevent synchronization of organization roles from the authentication provider regardless of their role in the authentication provider, then refer to the `skip_org_role_sync` setting in your Grafana configuration. Refer to [skip org role sync](../../../setup-grafana/configure-grafana/#authgrafana_com-skip_org_role_sync) for more information. {{% /admonition %}} ### Before you begin @@ -69,7 +69,7 @@ Organization roles sync from the authentication provider on user sign-in. To pre 1. Click **Update**. {{% admonition type="note" %}} -If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also [change a user's organization permissions]({{< relref "../server-user-management/change-user-org-permissions/" >}}) in the Server Admin section. +If you have [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can also [change a user's organization permissions](../server-user-management/change-user-org-permissions/) in the Server Admin section. {{% /admonition %}} ## Invite a user to join an organization @@ -80,14 +80,14 @@ When you invite users to join an organization, you assign the **Admin**, **Edito - If the user is new to Grafana, then use their email address to issue an invitation. The system automatically creates the user account on first sign in. {{% admonition type="note" %}} -If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also manually [add a user to an organization]({{< relref "../server-user-management/add-remove-user-to-org/" >}}). +If you have [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can also manually [add a user to an organization](../server-user-management/add-remove-user-to-org/). {{% /admonition %}} ### Before you begin - Ensure you have organization administrator privileges. - If the user already has access to Grafana, obtain their user name. -- Determine the permissions you want to assign to the user. For more information about organization permissions, refer to [Organization roles]({{< relref "../../roles-and-permissions/#organization-roles" >}}). +- Determine the permissions you want to assign to the user. For more information about organization permissions, refer to [Organization roles](../../roles-and-permissions/#organization-roles). **To invite or add an existing user account to your organization**: @@ -105,7 +105,7 @@ If you have [server administrator]({{< relref "../../roles-and-permissions/#graf | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | Email or username | Either the email or username that the user will use to sign in to Grafana. | | Name | The user's name. | - | Role | Click the organization role to assign this user. For more information about organization roles, refer to [Organization roles]({{< relref "../../roles-and-permissions/#organization-roles" >}}).. | + | Role | Click the organization role to assign this user. For more information about organization roles, refer to [Organization roles](../../roles-and-permissions/#organization-roles).. | | Send invite email | Switch to on if your organization has configured. The system sends an email to the user inviting them to sign in to Grafana and join the organization. Switch to off if you are not using email. The user can sign in to Grafana with the email or username you entered. | 1. Click **Submit**. @@ -156,4 +156,4 @@ This action does not remove the user account from the Grafana server. 1. Click the red **X** to remove the user from the organization. -> **Note:** If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can also [remove a user from an organization]({{< relref "../server-user-management/add-remove-user-to-org/#remove-a-user-from-an-organization" >}}) on the Users page of the Server Admin section. +> **Note:** If you have [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can also [remove a user from an organization](../server-user-management/add-remove-user-to-org/#remove-a-user-from-an-organization) on the Users page of the Server Admin section. diff --git a/docs/sources/administration/user-management/server-user-management/_index.md b/docs/sources/administration/user-management/server-user-management/_index.md index f5d14efcd25..cd3640c8224 100644 --- a/docs/sources/administration/user-management/server-user-management/_index.md +++ b/docs/sources/administration/user-management/server-user-management/_index.md @@ -20,13 +20,13 @@ weight: 100 A _user_ is defined as any individual who can log in to Grafana. Each user is associated with a _role_ that includes _permissions_. Permissions determine the tasks a user can perform in the system. -If you have [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions in Grafana, you can manage all users for a Grafana instance in the Server Admin section: +If you have [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions in Grafana, you can manage all users for a Grafana instance in the Server Admin section: {{< section >}} -If you have [organization administrator]({{< relref "../../roles-and-permissions/#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, refer to [Manage users in a organization]({{< relref "../manage-org-users/" >}}). +If you have [organization administrator](../../roles-and-permissions/#organization-roles) permissions and _not_ [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, refer to [Manage users in a organization](../manage-org-users/). -For more information about user roles and permissions, refer to [Roles and permissions]({{< relref "../../roles-and-permissions/" >}}). For more information about managing users in general, see [User management]({{< relref "../" >}}). +For more information about user roles and permissions, refer to [Roles and permissions](../../roles-and-permissions/). For more information about managing users in general, see [User management](../). ## View a list of users @@ -42,7 +42,7 @@ You can see a list of users with accounts on your Grafana server. This action mi 1. Click **Administration** in the left-side menu, **Users and access**, and then **Users**. {{% admonition type="note" %}} -If you have [organization administrator]({{< relref "../../roles-and-permissions/#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can still [view of list of users in a given organization]({{< relref "../manage-org-users/#view-a-list-of-organization-users" >}}). +If you have [organization administrator](../../roles-and-permissions/#organization-roles) permissions and _not_ [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can still [view of list of users in a given organization](../manage-org-users/#view-a-list-of-organization-users). {{% /admonition %}} ## View user details @@ -104,7 +104,7 @@ Edit a user account when you want to modify user login credentials, or delete, d Add users when you want to manually provide individuals with access to Grafana. -When you create a user using this method, you must create their password. The user does not receive a notification by email. To invite a user to Grafana and allow them to create their own password, [invite a user to join an organization]({{< relref "../manage-org-users#invite-a-user-to-join-an-organization" >}}). +When you create a user using this method, you must create their password. The user does not receive a notification by email. To invite a user to Grafana and allow them to create their own password, [invite a user to join an organization](../manage-org-users/#invite-a-user-to-join-an-organization). When you configure advanced authentication using Oauth, SAML, LDAP, or the Auth proxy, users are created automatically. @@ -119,10 +119,10 @@ When you configure advanced authentication using Oauth, SAML, LDAP, or the Auth 1. Click **New user**. 1. Complete the fields and click **Create user**. -When you create a user, the system assigns the user viewer permissions in a default organization, which you can change. You can now [add a user to a second organization]({{< relref "add-remove-user-to-org/" >}}). +When you create a user, the system assigns the user viewer permissions in a default organization, which you can change. You can now [add a user to a second organization](add-remove-user-to-org/). {{% admonition type="note" %}} -If you have [organization administrator]({{< relref "../../roles-and-permissions/#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../roles-and-permissions/#grafana-server-administrators" >}}) permissions, you can still add users by [inviting a user to join an organization]({{< relref "../manage-org-users#invite-a-user-to-join-an-organization" >}}). +If you have [organization administrator](../../roles-and-permissions/#organization-roles) permissions and _not_ [server administrator](../../roles-and-permissions/#grafana-server-administrators) permissions, you can still add users by [inviting a user to join an organization](../manage-org-users/#invite-a-user-to-join-an-organization). {{% /admonition %}} ## Force a user to log out of Grafana diff --git a/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md b/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md index 04ddd0dc490..f67983d8e68 100644 --- a/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md +++ b/docs/sources/administration/user-management/server-user-management/add-remove-user-to-org/index.md @@ -14,7 +14,7 @@ weight: 30 # Add or remove a user in an organization -Server administrators can add and remove users in organizations. To do this as an organization administrator, see [Manage users in an organization]({{< relref "../../manage-org-users/" >}}). +Server administrators can add and remove users in organizations. To do this as an organization administrator, see [Manage users in an organization](../../manage-org-users/). ## Add a user to an organization @@ -24,9 +24,9 @@ You are required to specify an Admin role for each organization. The first user ### Before you begin -- [Create an organization]({{< relref "../../../organization-management/#create-an-organization" >}}) -- [Add a user]({{< relref "./#add-a-user" >}}) to Grafana -- Ensure you have [Grafana server administrator privileges]({{< relref "./assign-remove-server-admin-privileges" >}}) +- [Create an organization](../../../organization-management/#create-an-organization) +- [Add a user](./#add-a-user) to Grafana +- Ensure you have [Grafana server administrator privileges](../assign-remove-server-admin-privileges/) **To add a user to an organization**: @@ -36,14 +36,14 @@ You are required to specify an Admin role for each organization. The first user 1. In the Organizations section, click **Add user to organization**. 1. Select an organization and a role. - For more information about user permissions, refer to [Organization roles]({{< relref "../../../roles-and-permissions#organization-roles" >}}). + For more information about user permissions, refer to [Organization roles](../../../roles-and-permissions/#organization-roles). 1. Click **Add to organization**. The next time the user signs in, they will be able to navigate to their new organization using the Switch Organizations option in the user profile menu. {{% admonition type="note" %}} -If you have [organization administrator]({{< relref "../../../roles-and-permissions#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../../roles-and-permissions#grafana-server-administrators" >}}) permissions, you can still [invite a user to join an organization]({{< relref "../../manage-org-users#invite-a-user-to-join-an-organization" >}}). +If you have [organization administrator](../../../roles-and-permissions/#organization-roles) permissions and _not_ [server administrator](../../../roles-and-permissions/#grafana-server-administrators) permissions, you can still [invite a user to join an organization](../../manage-org-users/#invite-a-user-to-join-an-organization). {{% /admonition %}} ## Remove a user from an organization @@ -62,4 +62,4 @@ Remove a user from an organization when they no longer require access to the das 1. In the Organization section, click **Remove from organization** next to the organization from which you want to remove the user. 1. Click **Confirm removal**. -> **Note:** If you have [organization administrator]({{< relref "../../../roles-and-permissions#organization-roles" >}}) permissions and _not_ [server administrator]({{< relref "../../../roles-and-permissions#grafana-server-administrators" >}}) permissions, you can still [remove a user from an organization]({{< relref "../../manage-org-users#remove-a-user-from-an-organization" >}}) in the Users section of organization configuration. +> **Note:** If you have [organization administrator](../../../roles-and-permissions/#organization-roles) permissions and _not_ [server administrator](../../../roles-and-permissions/#grafana-server-administrators) permissions, you can still [remove a user from an organization](../../manage-org-users/#remove-a-user-from-an-organization) in the Users section of organization configuration. diff --git a/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md b/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md index c017f104bdd..31523789db9 100644 --- a/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md +++ b/docs/sources/administration/user-management/server-user-management/assign-remove-server-admin-privileges/index.md @@ -13,7 +13,7 @@ weight: 20 # Assign or remove Grafana server administrator privileges -Grafana server administrators are responsible for creating users, organizations, and managing permissions. For more information about the server administration role, refer to [Grafana server administrators]({{< relref "../../../roles-and-permissions#grafana-server-administrators" >}}). +Grafana server administrators are responsible for creating users, organizations, and managing permissions. For more information about the server administration role, refer to [Grafana server administrators](../../../roles-and-permissions/#grafana-server-administrators). {{% admonition type="note" %}} Server administrators are "super-admins" with full permissions to create, read, update, and delete all resources and users in all organizations, as well as update global settings such as licenses. Only grant this permission to trusted users. @@ -21,7 +21,7 @@ Server administrators are "super-admins" with full permissions to create, read, ## Before you begin -- [Add a user]({{< relref "../#add-a-user" >}}) +- [Add a user](../#add-a-user) - Ensure you have Grafana server administrator privileges **To assign or remove Grafana administrator privileges**: diff --git a/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md b/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md index 4569a5ac8f2..4bf9eac2862 100644 --- a/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md +++ b/docs/sources/administration/user-management/server-user-management/change-user-org-permissions/index.md @@ -11,11 +11,11 @@ weight: 50 # Change a user's organization permissions -Update organization permissions when you want to enhance or restrict a user's access to organization resources. For more information about organization permissions, refer to [Organization roles]({{< relref "../../../roles-and-permissions/#organization-roles" >}}). +Update organization permissions when you want to enhance or restrict a user's access to organization resources. For more information about organization permissions, refer to [Organization roles](../../../roles-and-permissions/#organization-roles). ## Before you begin -- [Add a user to an organization]({{< relref "./add-remove-user-to-org/" >}}) +- [Add a user to an organization](../add-remove-user-to-org/) - Ensure you have Grafana server administrator privileges **To change a user's organization permissions**: diff --git a/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md b/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md deleted file mode 100644 index cfefd775975..00000000000 --- a/docs/sources/administration/user-management/server-user-management/grant-editor-admin-permissions/index.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -aliases: - - ../../manage-users-and-permissions/manage-server-users/grant-editor-admin-permissions/ -labels: - products: - - enterprise - - oss -title: Grant editors team creator permissions -weight: 60 ---- - -# Grant editors team creator permissions - -By default, the editor organization role does not allow editors to creator and manage teams. You can allow them to do so using the `editors_can_admin` configuration option. - -When `editors_can_admin` is enabled, users with the Editor role in an organization can create teams, and they are Administrators of the teams they create. To learn more about team permissions, refer to [Team management]({{< relref "../../../team-management/" >}}). - -## Before you begin - -- Ensure that you have access to the Grafana server - -**To enable editors with team creator permissions**: - -1. Log in to the Grafana server and open the Grafana configuration file. - - For more information about the Grafana configuration file and its location, refer to [Configuration]({{< relref "../../../../setup-grafana/configure-grafana/" >}}). - -1. Locate the `editors_can_admin` parameter. -1. Set the `editors_can_admin` value to `true`. -1. Save your changes and restart the Grafana server. diff --git a/docs/sources/administration/user-management/user-preferences/index.md b/docs/sources/administration/user-management/user-preferences/index.md index 41166419d52..eb1bae56a7f 100644 --- a/docs/sources/administration/user-management/user-preferences/index.md +++ b/docs/sources/administration/user-management/user-preferences/index.md @@ -50,7 +50,7 @@ Your profile includes your name, user name, and email address, which you can upd ## Edit your preferences -You can choose the way you would like data to appear in Grafana, including the UI theme, home dashboard, timezone, and first day of the week. You can set these preferences for your own account, for a team, for an organization, or Grafana-wide using configuration settings. Your user preferences take precedence over team, organization, and Grafana default preferences. For more information, see [Grafana preferences]({{< relref "../../organization-preferences/" >}}). +You can choose the way you would like data to appear in Grafana, including the UI theme, home dashboard, timezone, and first day of the week. You can set these preferences for your own account, for a team, for an organization, or Grafana-wide using configuration settings. Your user preferences take precedence over team, organization, and Grafana default preferences. For more information, see [Grafana preferences](../../organization-preferences/). - **UI theme** determines whether Grafana appears in light mode or dark mode. By default, UI theme is set to dark mode. - **Home dashboard** refers to the dashboard you see when you sign in to Grafana. By default, this is set to the Home dashboard. @@ -85,7 +85,7 @@ Every user is a member of at least one organization. You can have different role 1. Click the user icon in the top right corner of the page and select **Profile**. 1. Scroll down to the Organizations section and review the following information: - **Name**: The name of the organizations of which you are a member. - - **Role**: The role to which you are assigned in the organization. For more information about roles and permissions, refer to [Organization users and permissions]({{< relref "../../roles-and-permissions/#organization-users-and-permissions" >}}). + - **Role**: The role to which you are assigned in the organization. For more information about roles and permissions, refer to [Organization users and permissions](../../roles-and-permissions/#organization-users-and-permissions). - **Current**: Grafana indicates the organization that you are currently signed into as _Current_. If you are a member of multiple organizations, you can click **Select** to switch to that organization. ## View your Grafana sessions diff --git a/docs/sources/alerting/_index.md b/docs/sources/alerting/_index.md index 601ae34e4e1..8362360d188 100644 --- a/docs/sources/alerting/_index.md +++ b/docs/sources/alerting/_index.md @@ -25,7 +25,7 @@ cards: items: - title: Introduction href: ./fundamentals/ - description: Learn more about the fundamentals and available features that help you create, manage, and respond to alerts; and improve your team’s ability to resolve issues quickly. + description: Learn more about the fundamentals and available features that help you create, manage, and respond to alerts; and improve your team's ability to resolve issues quickly. height: 24 - title: Configure alert rules href: ./alerting-rules/ @@ -55,7 +55,8 @@ Monitor your incoming metrics data or log entries and set up your Grafana Alerti In this way, you eliminate the need for manual monitoring and provide a first line of defense against system outages or changes that could turn into major incidents. -Using Grafana Alerting, you create queries and expressions from multiple data sources — no matter where your data is stored — giving you the flexibility to combine your data and alert on your metrics and logs in new and unique ways. You can then create, manage, and take action on your alerts from a single, consolidated view, and improve your team’s ability to identify and resolve issues quickly. +Using Grafana Alerting, you create queries and expressions from multiple data sources, no matter where you store your data, giving you the flexibility to combine your data and alert on your metrics and logs in new and unique ways. +You can then create, manage, and take action on your alerts from a single, consolidated view, and improve your team's ability to identify and resolve issues quickly. ## Explore diff --git a/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md b/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md index 2ad18a60ab6..3b30819b328 100644 --- a/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md +++ b/docs/sources/alerting/alerting-rules/create-grafana-managed-rule.md @@ -118,15 +118,17 @@ refs: # Configure Grafana-managed alert rules -Grafana-managed rules can query data from multiple data sources in a single alert rule. They are the most flexible [alert rule type](ref:alert-rules). You can also add expressions to transform your data, set alert conditions, and images in alert notifications. +Grafana-managed rules can query data from multiple data sources in a single alert rule. +They're the most flexible [alert rule type](ref:alert-rules). +You can also add expressions to transform your data, set alert conditions, and images in alert notifications. -{{% admonition type="note" %}} +{{< admonition type="note" >}} In Grafana Cloud, the number of Grafana-managed alert rules you can create depends on your Grafana Cloud plan. - Free Forever plan: You can create up to 100 free alert rules, with each alert rule having a maximum of 1000 alert instances. - All paid plans (Pro and Advanced): They have a soft limit of 2000 alert rules and support unlimited alert instances. To increase the limit, open a support ticket from the [Cloud portal](/docs/grafana-cloud/account-management/support/). -{{% /admonition %}} +{{< /admonition >}} To create or edit Grafana-managed alert rules, follow the instructions below. For a practical example, check out our [tutorial on getting started with Grafana alerting](http://grafana.com/tutorials/alerting-get-started/). @@ -144,11 +146,11 @@ Only users with **Edit** permissions for the folder storing the rules can edit o You can use default or advanced options for Grafana-managed alert rule creation. The default options streamline rule creation with a cleaner header and a single query and condition. For more complex rules, use advanced options to add multiple queries and expressions. -You can toggle between the two options. Once you have created an alert rule, the system defaults to your previous choice for the next alert rule. +You can toggle between the two options. +After you have created an alert rule, the system defaults to your previous choice for the next alert rule. -Switching from advanced to default may result in queries and expressions that cannot be converted. In this case, a warning message asks if you want to continue to reset to default settings. - -Default and advanced options are enabled by default for Grafana Cloud users and this feature is being rolled out progressively. OSS users can enable them via the [`alertingQueryAndExpressionsStepMode` feature toggle](/setup-grafana/configure-grafana/feature-toggles/). +Switching from advanced to default may result in queries and expressions that can't be converted. +In this case, a warning message asks if you want to continue to reset to default settings. {{< docs/shared lookup="alerts/configure-alert-rule-name.md" source="grafana" version="" >}} @@ -171,9 +173,10 @@ You can toggle between **Default** and **Advanced** options. If the [Default vs. {{< collapse title="Advanced options" >}} 1. Select a data source. -1. From the **Options** dropdown, specify a [time range](ref:time-units-and-relative-ranges). +1. From the **Options** drop-down menu, specify a [time range](ref:time-units-and-relative-ranges). - Note that Grafana Alerting only supports fixed relative time ranges, for example, `now-24hr: now`. It does not support absolute time ranges: `2021-12-02 00:00:00 to 2021-12-05 23:59:592` or semi-relative time ranges: `now/d to: now`. + Note that Grafana Alerting only supports fixed relative time ranges, for example, `now-24hr: now`. + It doesn't support absolute time ranges: `2021-12-02 00:00:00 to 2021-12-05 23:59:592` or semi-relative time ranges: `now/d to: now`. 1. Add a query. @@ -224,7 +227,8 @@ To do this, you need to make sure that your alert rule is in the right evaluatio The pending period is the period in which an alert rule can be in breach of the condition until it fires. - Once a condition is met, the alert goes into the **Pending** state. If the condition remains active for the duration specified, the alert transitions to the **Firing** state, else it reverts to the **Normal** state. + After a condition is met, the alert goes into the **Pending** state. + If the condition remains active for the duration specified, the alert transitions to the **Firing** state, else it reverts to the **Normal** state. 1. Turn on pause alert notifications, if required. @@ -255,20 +259,16 @@ Complete the following steps to set up notifications. 1. Choose this option to select an existing [contact point](ref:contact-points). - All notifications for this alert rule are sent to this contact point automatically and notification policies are not used. + All notifications for this alert rule are sent to this contact point automatically and notification policies aren't used. 1. You can also optionally select a mute timing as well as groupings and timings to define when not to send notifications. - {{< admonition type="note" >}} - An auto-generated notification policy is generated. Only admins can view these auto-generated policies from the **Notification policies** list view. Any changes have to be made in the alert rules form. {{< /admonition >}} - **Use notification policy** - 1. Choose this option to use the [notification policy tree](ref:notification-policies) to direct your notifications. + 1. Choose this option to use the [notification policy tree](ref:notification-policies) to handle alert notifications. - {{< admonition type="note" >}} - All alert rules and instances, irrespective of their labels, match the default notification policy. If there are no nested policies, or no nested policies match the labels in the alert rule or alert instance, then the default notification policy is the matching policy. - {{< /admonition >}} + All notifications for this alert rule are managed by the notification policy tree, which routes alerts based on their labels. + If an alert doesn't match a specific policy, the default notification policy applies, ensuring all alerts are handled. 1. Preview your alert instance routing set up. diff --git a/docs/sources/alerting/alerting-rules/link-alert-rules-to-panels.md b/docs/sources/alerting/alerting-rules/link-alert-rules-to-panels.md index aeaddf1e405..746cb778052 100644 --- a/docs/sources/alerting/alerting-rules/link-alert-rules-to-panels.md +++ b/docs/sources/alerting/alerting-rules/link-alert-rules-to-panels.md @@ -44,6 +44,10 @@ Grafana allows you to link an alert rule to a dashboard panel. This can help you An alert rule is linked to a panel by setting the [`dashboardUId` and `panelId` annotations](ref:annotations). Both annotations must be set together. +{{% admonition type="tutorial" %}} +For a hands-on example of integrating alert rules with dashboards, check out [Part 5 of our Get Started with Grafana Alerting tutorial](http://www.grafana.com/tutorials/alerting-get-started-pt5/). +{{% /admonition %}} + ## Link alert rules to panels When configuring the alert rule, you can set the dashboard and panel annotations as shown in this [video](https://youtu.be/ClLp-iSoaSY?si=qKWnvSVaQuvYcuw9&t=170). diff --git a/docs/sources/alerting/alerting-rules/templates/_index.md b/docs/sources/alerting/alerting-rules/templates/_index.md index cf211fed7b6..f6da85e1977 100644 --- a/docs/sources/alerting/alerting-rules/templates/_index.md +++ b/docs/sources/alerting/alerting-rules/templates/_index.md @@ -190,9 +190,7 @@ low In this example, the value of the `severity` label is determined by the query value, and the possible options are `critical`, `high`, `medium`, or `low`. You can then use the `severity` label to change their notifications—for instance, sending `critical` alerts immediately or routing `low` alerts to a specific team for further review. -{{% admonition type="note" %}} -You should avoid displaying query values in labels, as this may create numerous unique alert instances—one for each distinct label value. Instead, use annotations for query values. -{{% /admonition %}} +{{< docs/shared lookup="alerts/note-dynamic-labels.md" source="grafana" version="" >}} ### How to template a label diff --git a/docs/sources/alerting/alerting-rules/templates/examples.md b/docs/sources/alerting/alerting-rules/templates/examples.md index c8c6f9dbb40..e9ee1a8015b 100644 --- a/docs/sources/alerting/alerting-rules/templates/examples.md +++ b/docs/sources/alerting/alerting-rules/templates/examples.md @@ -209,9 +209,7 @@ In this example, the `severity` label is determined by the query value: You can then use the `severity` label to control how alerts are handled. For instance, you could send `critical` alerts immediately, while routing `low` severity alerts to a team for further investigation. -{{% admonition type="note" %}} -You should avoid displaying query values in labels, as this may create many alert instances—one for each distinct label value. Instead, use annotations to convey query values. -{{% /admonition %}} +{{< docs/shared lookup="alerts/note-dynamic-labels.md" source="grafana" version="" >}} ### Based on query label diff --git a/docs/sources/alerting/configure-notifications/create-silence.md b/docs/sources/alerting/configure-notifications/create-silence.md index 6f781a60ce3..5cf6f4a9c04 100644 --- a/docs/sources/alerting/configure-notifications/create-silence.md +++ b/docs/sources/alerting/configure-notifications/create-silence.md @@ -61,7 +61,7 @@ refs: # Configure silences -Silences stop notifications from getting created and last for only a specified window of time. Use them to temporarily prevent alert notifications, such as during incident response or a maintenance window. +Silences stop notifications from being created for a specified time window but do not interrupt alert evaluation. Use them to temporarily prevent alert notifications, such as during incident response or a maintenance window. {{< admonition type="note" >}} Silences are assigned to a [specific Alertmanager](ref:alertmanager-architecture) and only suppress notifications for alerts managed by that Alertmanager. diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/_index.md b/docs/sources/alerting/configure-notifications/manage-contact-points/_index.md index ce35c4c75e8..215ed1926dc 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/_index.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/_index.md @@ -86,12 +86,7 @@ refs: destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/integrations/configure-mqtt/ - alertmanager-architecture: - - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/configure-notifications/#alertmanager-architecture - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/#alertmanager-architecture - external-alertmanager: + configure-alertmanager: - pattern: /docs/grafana/ destination: /docs/grafana//alerting/set-up/configure-alertmanager/ - pattern: /docs/grafana-cloud/ @@ -101,13 +96,23 @@ refs: destination: /docs/grafana//alerting/configure-notifications/template-notifications/manage-notification-templates/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/template-notifications/manage-notification-templates/ + configure-grafana-alerts: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/create-grafana-managed-rule/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/create-grafana-managed-rule/ + configure-contact-points: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/ --- # Configure contact points Use contact points to specify where to receive alert notifications. Contact points contain the configuration for sending alert notifications, including destinations like email, Slack, OnCall, webhooks, and their notification messages. -A contact point can have one or multiple destinations, known as [contact point integrations](#list-of-supported-integrations). Alert notifications are sent to each integration within the chosen contact point. +A contact point can have one or multiple destinations, known as [contact point integrations](#supported-contact-point-integrations). Alert notifications are sent to each integration within the chosen contact point. On the **Contact Points** tab, you can: @@ -119,9 +124,42 @@ On the **Contact Points** tab, you can: - Delete contact points. Note that you cannot delete contact points that are in use by a notification policy. To proceed, either delete the notification policy or update it to use another contact point. {{% admonition type="note" %}} -Contact points are assigned to a [specific Alertmanager](ref:alertmanager-architecture) and cannot be used by notification policies in other Alertmanagers. +Contact points are assigned to a [specific Alertmanager](ref:configure-alertmanager) and cannot be used by notification policies in other Alertmanagers. {{% /admonition %}} +## Supported contact point integrations + +Each contact point integration has its own configuration options and setup process. The following list shows the contact point integrations supported by Grafana. + +{{< column-list >}} + +- Alertmanager +- [AWS SNS](ref:sns) +- Cisco Webex Teams +- DingDing +- [Discord](ref:discord) +- [Email](ref:email) +- [Google Chat](ref:gchat) +- [Grafana OnCall](ref:oncall) +- Kafka REST Proxy +- Line +- [Microsoft Teams](ref:teams) +- [MQTT](ref:mqtt) +- [Opsgenie](ref:opsgenie) +- [PagerDuty](ref:pagerduty) +- Pushover +- Sensu Go +- [Slack](ref:slack) +- [Telegram](ref:telegram) +- Threema Gateway +- VictorOps +- [Webhook](ref:webhook) +- WeCom + +{{< /column-list >}} + +Some of the integrations above are not supported by Prometheus Alertmanager. For the list of supported integrations, refer to the [Prometheus Alertmanager receiver settings](https://prometheus.io/docs/alerting/latest/configuration/#receiver-integration-settings). + ## Add a contact point Complete the following steps to add a contact point. @@ -132,7 +170,7 @@ Complete the following steps to add a contact point. 1. On the **Contact Points** tab, click **+ Add contact point**. 1. Enter a descriptive name for the contact point. 1. From **Integration**, select a type and fill out mandatory fields. For example, if you choose email, enter the email addresses. Or if you choose Slack, enter the Slack channel and users who should be contacted. -1. Some contact point integrations, like email or Webhook, have optional settings. In **Optional settings**, specify additional settings for the selected contact point integration. +1. Some [contact point integrations](#supported-contact-point-integrations), like email or Webhook, have optional settings. In **Optional settings**, specify additional settings for the selected contact point integration. 1. In Notification settings, optionally select **Disable resolved message** if you do not want to be notified when an alert resolves. 1. Save your changes. @@ -148,6 +186,16 @@ To add another integration to a contact point, complete the following steps. - In **Optional settings**, specify additional settings for the selected contact point integration. 1. Save your changes. +## Customize notification messages + +In contact points, you can also customize notification messages. For example, when setting up an email contact point integration, click **Message** or **Subject** to modify it. + +By default, notification messages include common alert details, which are usually sufficient for most cases. + +If necessary, you can customize the content and format of notification messages. You can create a custom notification template, which can then be applied to one or more contact points. + +On the **Notification templates** tab, you can view, edit, copy or delete notification templates. Refer to [manage notification templates](ref:manage-notification-templates) for instructions on selecting or creating a template for a contact point. + ## Test a contact point Testing a contact point is only available for Grafana Alertmanager. Complete the following steps to test a contact point. @@ -159,45 +207,9 @@ Testing a contact point is only available for Grafana Alertmanager. Complete the 1. Choose whether to send a predefined test notification or choose custom to add your own custom annotations and labels to include in the notification. 1. Click **Send test notification** to fire the alert. -## Customize notification messages +## Enable notifications for a contact point -In contact points, you can also customize notification messages. For example, when setting up an email contact point integration, click **Message** or **Subject** to modify it. +After creating a contact point, you can enable it to receive alert notifications using one of the following methods: -By default, notification messages include common alert details, which are usually sufficient for most cases. - -If necessary, you can customize the content and format of notification messages. You can create a custom notification template, which can then be applied to one or more contact points. - -On the **Notification templates** tab, you can view, edit, copy or delete notification templates. Refer to [manage notification templates](ref:manage-notification-templates) for instructions on selecting or creating a template for a contact point. - -## List of supported integrations - -Each contact point integration has its own configuration options and setup process. In most cases, this involves providing an API key or a Webhook URL. - -The following table lists the contact point integrations supported by Grafana. - -| Name | Type | -| ---------------------------- | ------------------------- | -| Alertmanager | `prometheus-alertmanager` | -| [Amazon SNS](ref:sns) | `sns` | -| Cisco Webex Teams | `webex` | -| DingDing | `dingding` | -| [Discord](ref:discord) | `discord` | -| [Email](ref:email) | `email` | -| [Google Chat](ref:gchat) | `googlechat` | -| [Grafana Oncall](ref:oncall) | `oncall` | -| Kafka REST Proxy | `kafka` | -| Line | `line` | -| [Microsoft Teams](ref:teams) | `teams` | -| [MQTT](ref:mqtt) | `mqtt` | -| [Opsgenie](ref:opsgenie) | `opsgenie` | -| [Pagerduty](ref:pagerduty) | `pagerduty` | -| Pushover | `pushover` | -| Sensu Go | `sensugo` | -| [Slack](ref:slack) | `slack` | -| [Telegram](ref:telegram) | `telegram` | -| Threema Gateway | `threema` | -| VictorOps | `victorops` | -| [Webhook](ref:webhook) | `webhook` | -| WeCom | `wecom` | - -Some of these integrations are not compatible with [external Alertmanagers](ref:external-alertmanager). For the list of Prometheus Alertmanager integrations, refer to the [Prometheus Alertmanager receiver settings](https://prometheus.io/docs/alerting/latest/configuration/#receiver-integration-settings). +- **Assign it to alert rules** – Select the contact point in the [notifications options for Grafana-managed alert rules](ref:configure-grafana-alerts) to directly associate it with specific alerts. +- **Assign it to notification policies** – Add the contact point to one or more [notification policies](ref:configure-contact-points), which manage the alert notifications you want the contact point to receive. diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-amazon-sns.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-amazon-sns.md index 84274e64043..9c449640511 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-amazon-sns.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/configure-amazon-sns.md @@ -14,11 +14,32 @@ labels: menuTitle: Amazon SNS title: Configure Amazon SNS for Alerting weight: 100 +refs: + notification-templates: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/template-notifications/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/template-notifications/ + configure-contact-points: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/ + test-contact-point: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/#test-a-contact-point + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/#test-a-contact-point + enable-contact-point-notifications: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/#enable-notifications-for-a-contact-point + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/#enable-notifications-for-a-contact-point --- -# Configure Amazon SNS for Alerting +# Configure Amazon SNS notifications -Use the Grafana Alerting - Amazon SNS integration to send notifications to Amazon SNS when your alerts are firing. You can receive notifications via the various subscriber channels supported by SNS. +Use the Amazon SNS integration in a contact point to send alert notifications to a SNS topic. Then, configure the SNS topic to forward notifications to distinct subscriber channels used in your SNS account. ## Before you begin @@ -27,71 +48,51 @@ Before you begin, ensure you have the following: - **AWS SNS Topic**: An SNS topic to send notifications to. - **AWS IAM Identity with necessary access**: An IAM identity (e.g. user, role) with the necessary permissions to publish messages to the SNS topic. -For an example setup, see [Example Minimal Setup Using Assumed IAM Role]({{< relref "#example-minimal-setup-using-assumed-iam-role" >}}). +For a minimal setup, refer to [Example using an Access Key](#example-using-an-access-key). -## Adding the SNS Contact Point in Grafana +## Configure Amazon SNS for a contact point -With AWS resources configured, proceed to add SNS as a contact point in Grafana. +To create a contact point with a SNS integration, complete the following steps. -- Navigate to **Alerts & IRM** -> **Alerting** -> **Contact points**. -- Click on **"Add contact point"**. -- **Name**: Enter a descriptive name (e.g., `AWS SNS`). -- Choose **"AWS SNS"** from the list of contact point types. +1. Navigate to **Alerts & IRM** -> **Alerting** -> **Contact points**. +1. Click **+ Add contact point**. +1. Enter a name for the contact point. +1. From the **Integration** list, select **AWS SNS**. +1. Set up the required [settings](#sns-settings) for your SNS configuration. +1. Click **Save contact point**. -### 2. Configure SNS Settings +For more details on contact points, including how to test them and enable notifications, refer to [Configure contact points](ref:configure-contact-points). -#### SNS Settings +## SNS Settings - **The Amazon SNS API URL**: (Optional) The SNS API URL, e.g., `https://sns.us-east-2.amazonaws.com`. If not specified, the SNS API URL from the SNS SDK will be used. - **Signature Version (sigv4)**: Configures AWS's Signature Verification 4 signing process to sign requests. - **Region**: (Optional) The AWS region. If blank, the region from the default credentials chain is used. - - **Access Key**: The AWS API access key. - - **Secret Key**: The AWS API secret key. + - **Access Key** : (Optional) The AWS API access key. + - **Secret Key**: (Optional) The AWS API secret key. + > Both `Access Key` and `Secret Key` must be provided together or left blank together. + > + > If left blank, Grafana searches for credentials using the default credentials chain, including environment variables (`AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`), the shared credential file, and EC2 instance roles. - **Profile**: (Optional) Named AWS profile used to authenticate. - **Role ARN**: (Optional) The ARN of an AWS IAM role to assume for authentication, serving as an alternative to using AWS API keys. - **SNS topic ARN**: (Optional) If you don't specify this value, you must specify a value for the `Phone number` or `Target ARN`. If you are using a FIFO SNS topic you should set a message group interval longer than 5 minutes to prevent messages with the same group key being deduplicated by the SNS default deduplication window. - **Phone number**: (Optional) Phone number if message is delivered via SMS in E.164 format. If you don't specify this value, you must specify a value for the `SNS topic ARN` or `Target ARN`. - **Target ARN**: (Optional) The mobile platform endpoint ARN if message is delivered via mobile notifications. If you don't specify this value, you must specify a value for the `SNS topic ARN` or `Phone number`. -- **Subject**: (Optional) Customize the subject line or use the default template. This field is templateable. -- **Message**: (Optional) Customize the message content or use the default template. This field is templateable. +- **Subject**: (Optional) Customize the subject. This field supports [notification templates](ref:notification-templates) and, by default, uses the default title template (`default.title`). It **cannot be an empty string**. +- **Message**: (Optional) Customize the message. This field supports [notification templates](ref:notification-templates) and, by default, uses the default message template (`default.message`). - **Attributes**: (Optional) Add any SNS message attributes. -{{< admonition type="note" >}} -Both `Access Key` and `Secret Key` must be provided together or left blank together. If blank it defaults to a chain of credential -providers to search for credentials in environment variables, shared credential file, and EC2 Instance Roles. +## Example using an Access Key -Environment variables: `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY`. -{{< /admonition >}} +This section outlines a minimal setup to configure Amazon SNS with Alerting. -### 3. Test & Save the Contact Point - -- Click **"Test"** to verify that the SNS configuration is working correctly. -- After the test is successful, click **"Save contact point"** to add the SNS contact point. - -### 4. Next steps - -The SNS contact point is ready to receive alert notifications. - -To add this contact point to your alert, complete the following steps. - -1. In Grafana, navigate to **Alerting** > **Alert rules**. -1. Edit or create a new alert rule. -1. Scroll down to the **Configure labels and notifications** section. -1. Under Notifications click **Select contact point**. -1. From the drop-down menu, select the previously created contact point. -1. **Click Save rule and exit**. - -## Example Minimal Setup Using Assumed IAM Role - -This section outlines a minimal setup to configure SNS with Grafana using an assumed IAM Role. - -### 1. Create an SNS Topic +### 1. Create an SNS Topic and Email Subscriber 1. **Navigate to SNS in AWS Console**: - Go to the [Amazon SNS Console](https://console.aws.amazon.com/sns/v3/home). -2. **Create a new topic** [[AWS Documentation](https://docs.aws.amazon.com/sns/latest/dg/sns-create-topic.html)]: +2. **Create a new topic**: - On the **Topics** page, choose **"Create topic"**. - Select **"Standard"** as the type. @@ -99,105 +100,70 @@ This section outlines a minimal setup to configure SNS with Grafana using an ass - **Encryption**: Leave disabled for this minimal setup. - Click **"Create topic"**. -3. (Optional) **Add an email subscriber to help test** [[AWS Documentation](https://docs.aws.amazon.com/sns/latest/dg/sns-email-notifications.html)]: +3. (Optional) **Add an email subscriber to help test**: - Within your newly created topic, click on **"Create subscription"**. - **Protocol**: Choose `Email`. - **Endpoint**: Enter your email address to receive test notifications. - Click **"Create subscription"**. - **Confirm Subscription**: Check your email and confirm the subscription by clicking the provided link. -### 2. Create an IAM Role +### 2. Create an IAM Policy, User, and Access Key 1. **Navigate to IAM in AWS Console**: - Go to the [IAM Console](https://console.aws.amazon.com/iam/home). -2. **Create a new role** [[AWS Documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-user.html)]: +2. **Create a new policy**: - - On the **Roles** page, choose **"Create role"**. - - **Trusted Entity**: Select **"This account"**. - - Click **"Next"** until the end, name it (e.g., `GrafanaSNSRole`), and click **"Create role"**. - -3. **Attach Inline Policy**: - - - After creating the role, select it and navigate to the **"Permissions"** tab. - - Click on **"Add permission"** > **"Create inline policy"**. + - On the **Policies** page, choose **"Create policy"**. - Switch to the **"JSON"** tab and paste the following policy, replacing `Resource` with your SNS topic ARN: - ```json - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": ["sns:Publish", "sns:GetTopicAttributes"], - "Resource": "arn:aws:sns:::" - } - ] - } - ``` + ```json + { + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": ["sns:Publish", "sns:GetTopicAttributes"], + "Resource": "arn:aws:sns:::" + } + ] + } + ``` - Click **"Next"**, name it (e.g., `SNSPublishPolicy`), and click **"Create policy"**. -### 3. Create an IAM Policy - -1. **Create a new policy to allow assuming the above IAM role** [[AWS Documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/access_policies_create-console.html)]: - - - In the IAM Console, on the **Policies** page, choose **"Create policy"**. - - Switch to the **"JSON"** tab and paste the following policy, replacing `Resource` with the ARN of the role you created earlier: - - ```json - { - "Version": "2012-10-17", - "Statement": [ - { - "Effect": "Allow", - "Action": "sts:AssumeRole", - "Resource": "arn:aws:iam:::role/GrafanaSNSRole" - } - ] - } - ``` - -2. **Review and Create**: - - Click **"Next"**, name it (e.g., `AssumeSNSRolePolicy`), and click **"Create policy"**. - -### 4. Create an IAM User - -1. **Create a new IAM user to assume the above role** [[AWS Documentation](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_users_create.html)]: +3. **Create a new IAM user and assign the policy** - In the IAM Console, on the **Users** page, choose **"Create user"**. - - Enter a **User name**, e.g., `grafana-sns-user`. + - Enter a **User name**, e.g., `alerting-sns-user`. - Click **"Next"**. - - Select **"Attach policies directly"**. - - Search for the policy you created earlier (`AssumeSNSRolePolicy`) and select it. + - In **Set permissions**, select **"Attach policies directly"**. + - Search for the policy you created earlier (`SNSPublishPolicy`) and select it. - Click **"Next"** , and click **"Create user"**. -2. **Generate credentials**: +4. **Create an Access Key**: - Within your newly created user, click on **"Create access key"**. - Select an appropriate use-case, e.g., `Application running outside AWS`. - Click **"Next"** , and click **"Create access key"**. - - **Save Credentials**: Note the **Access key ID** and **Secret access key**. You'll need these for Grafana's configuration. + - **Save Credentials**: Note the **Access key ID** and **Secret access key** that are required in the next step. -### 5. Add the SNS Contact Point in Grafana +### 3. Configure the SNS Contact Point in Grafana -After creating the IAM user and obtaining the necessary credentials, proceed to [configure the SNS contact point in Grafana]({{< relref "#adding-the-sns-contact-point-in-grafana" >}}) using the following details: +Follow the steps in [configure Amazon SNS for a contact point](#configure-amazon-sns-for-a-contact-point), using the settings below and replacing the placeholders with the SNS and IAM values created in the previous steps. -- **The Amazon SNS API URL**: `https://sns.us-east-1.amazonaws.com` +- **The Amazon SNS API URL**: `https://sns..amazonaws.com` - **Signature Version (sigv4)**: - - **Region**: `us-east-1` + - **Region**: `` - **Access Key**: ``. - **Secret Key**: `` - - **Role ARN**: `arn:aws:iam:::role/GrafanaSNSRole` -- **SNS topic ARN**: `arn:aws:sns:::My-Topic` +- **SNS topic ARN**: `arn:aws:sns:::` -{{< admonition type="note" >}} -Replace the placeholder values (`https://sns.us-east-1.amazonaws.com`, `us-east-1`, ``, ``, `arn:aws:iam:::role/GrafanaSNSRole`, `arn:aws:sns:::My-Topic`) with your actual AWS credentials and ARNs. -{{< /admonition >}} +[Test the contact point](ref:test-contact-point) to ensure it's working, or [enable notifications](ref:enable-contact-point-notifications) for it. ## Additional Resources +- [Configure contact points](ref:configure-contact-points) - [Amazon SNS Documentation](https://docs.aws.amazon.com/sns/index.html) -- [AWS IAM Documentation](https://docs.aws.amazon.com/iam/index.html) -- [Prometheus Alertmanager SNS Integration](https://prometheus.io/docs/alerting/configuration/#sns_config) -- [Cloudwatch AWS Authentication]({{< relref "../../../../datasources/aws-cloudwatch/aws-authentication" >}}) +- [Amazon IAM Documentation](https://docs.aws.amazon.com/iam/index.html) +- [Prometheus Alertmanager SNS Configuration](https://prometheus.io/docs/alerting/configuration/#sns_config) diff --git a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md index 6562b948095..e7741ac3b56 100644 --- a/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md +++ b/docs/sources/alerting/configure-notifications/manage-contact-points/integrations/webhook-notifier.md @@ -28,13 +28,83 @@ refs: destination: /docs/grafana//alerting/configure-notifications/template-notifications/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/template-notifications/ + configure-contact-points: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/configure-notifications/manage-contact-points/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/configure-notifications/manage-contact-points/ --- -# Configure the webhook notifier for Alerting +# Configure webhook notifications -The webhook notification is a simple way to send information about a state change over HTTP to a custom endpoint. Using this notification you could integrate Grafana into a system of your choosing. +Use the webhook integration in contact points to send alert notifications to your webhook. -## Webhook JSON payload +The webhook integration is a flexible way to integrate alerts into your system. When a notification is triggered, it sends a JSON request with alert details and additional data to the webhook endpoint. + +## Configure webhook for a contact point + +To create a contact point with webhook integration, complete the following steps. + +1. Navigate to **Alerts & IRM** -> **Alerting** -> **Contact points**. +1. Click **+ Add contact point**. +1. Enter a name for the contact point. +1. From the **Integration** list, select **Webhook**. +1. In the **URL** field, copy in your Webhook URL. +1. (Optional) Configure [additional settings](#webhook-settings). +1. Click **Save contact point**. + +For more details on contact points, including how to test them and enable notifications, refer to [Configure contact points](ref:configure-contact-points). + +## Webhook settings + +| Option | Description | +| ------ | ---------------- | +| URL | The Webhook URL. | + +#### Optional settings + +| Option | Description | +| --------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | +| HTTP Method | Specifies the HTTP method to use: `POST` or `PUT`. | +| Basic Authentication Username | Username for HTTP Basic Authentication. | +| Basic Authentication Password | Password for HTTP Basic Authentication. | +| Authentication Header Scheme | Scheme for the `Authorization` Request Header. Default is `Bearer`. | +| Authentication Header Credentials | Credentials for the `Authorization` Request header. | +| Max Alerts | Maximum number of alerts to include in a notification. Any alerts exceeding this limit are ignored. `0` means no limit. | +| TLS | TLS configuration options, including CA certificate, client certificate, and client key. | + +{{< admonition type="note" >}} + +You can configure either HTTP Basic Authentication or the Authorization request header, but not both. + +{{< /admonition >}} + +#### Optional settings using templates + +Use the following settings to include custom data within the [JSON payload](#body). Both options support using [notification templates](ref:notification-templates). + +| Option | Description | +| ------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | +| Title | Sends the value as a string in the `title` field of the [JSON payload](#body). Supports [notification templates](ref:notification-templates). | +| Message | Sends the value as a string in the `message` field of the [JSON payload](#body). Supports [notification templates](ref:notification-templates). | + +{{< admonition type="note" >}} +You can customize the `title` and `message` options to include custom messages and notification data using notification templates. These fields are always sent as strings in the JSON payload. + +However, you cannot customize the webhook data structure, such as adding or changing other JSON fields and HTTP headers, or sending data in a different format like XML. + +If you need to format these fields as JSON or modify other webhook request options, consider sending webhook notifications to a proxy server that adjusts the webhook request before forwarding it to the final destination. +{{< /admonition >}} + +#### Optional notification settings + +| Option | Description | +| ------------------------ | ------------------------------------------------------------------- | +| Disable resolved message | Enable this option to prevent notifications when an alert resolves. | + +## JSON payload + +The following example shows the payload of a webhook notification containing information about two firing alerts: ```json { @@ -106,76 +176,47 @@ The webhook notification is a simple way to send information about a state chang } ``` -## Webhook fields - ### Body -| Key | Type | Description | -| ----------------- | ------------------------- | ------------------------------------------------------------------------------- | -| receiver | string | Name of the webhook | -| status | string | Current status of the alert, `firing` or `resolved` | -| orgId | number | ID of the organization related to the payload | -| alerts | array of [alerts](#alert) | Alerts that are triggering | -| groupLabels | object | Labels that are used for grouping, map of string keys to string values | -| commonLabels | object | Labels that all alarms have in common, map of string keys to string values | -| commonAnnotations | object | Annotations that all alarms have in common, map of string keys to string values | -| externalURL | string | External URL to the Grafana instance sending this webhook | -| version | string | Version of the payload | -| groupKey | string | Key that is used for grouping | -| truncatedAlerts | number | Number of alerts that were truncated | -| title | string | Custom title | -| state | string | State of the alert group (either `alerting` or `ok`) | -| message | string | Custom message | +The JSON payload of webhook notifications includes the following key-value pairs: + +| Key | Type | Description | +| ------------------- | ------------------------- | -------------------------------------------------------------------------------- | +| `receiver` | string | Name of the contact point. | +| `status` | string | Current status of the alert, `firing` or `resolved`. | +| `orgId` | number | ID of the organization related to the payload. | +| `alerts` | array of [alerts](#alert) | Alerts that are triggering. | +| `groupLabels` | object | Labels that are used for grouping, map of string keys to string values. | +| `commonLabels` | object | Labels that all alarms have in common, map of string keys to string values. | +| `commonAnnotations` | object | Annotations that all alarms have in common, map of string keys to string values. | +| `externalURL` | string | External URL to the Grafana instance sending this webhook. | +| `version` | string | Version of the payload structure. | +| `groupKey` | string | Key that is used for grouping. | +| `truncatedAlerts` | number | Number of alerts that were truncated. | +| `state` | string | State of the alert group (either `alerting` or `ok`). | + +The following key-value pairs are also included in the JSON payload and can be configured in the [webhook settings using notification templates](#optional-settings-using-templates). + +| Key | Type | Description | +| --------- | ------ | -------------------------------------------------------------------------------------------------------------------- | +| `title` | string | Custom title. Configurable in [webhook settings using notification templates](#optional-settings-using-templates). | +| `message` | string | Custom message. Configurable in [webhook settings using notification templates](#optional-settings-using-templates). | ### Alert -| Key | Type | Description | -| ------------ | ------ | ---------------------------------------------------------------------------------- | -| status | string | Current status of the alert, `firing` or `resolved` | -| labels | object | Labels that are part of this alert, map of string keys to string values | -| annotations | object | Annotations that are part of this alert, map of string keys to string values | -| startsAt | string | Start time of the alert | -| endsAt | string | End time of the alert, default value when not resolved is `0001-01-01T00:00:00Z` | -| values | object | Values that triggered the current status | -| generatorURL | string | URL of the alert rule in the Grafana UI | -| fingerprint | string | The labels fingerprint, alarms with the same labels will have the same fingerprint | -| silenceURL | string | URL to silence the alert rule in the Grafana UI | -| dashboardURL | string | A link to the Grafana Dashboard if the alert has a Dashboard UID annotation | -| panelURL | string | A link to the panel if the alert has a Panel ID annotation | -| imageURL | string | URL of a screenshot of a panel assigned to the rule that created this notification | +The Alert object represents an alert included in the notification group, as provided by the [`alerts` field](#body). -{{< admonition type="note" >}} - -You can customize the `title` and `message` fields using [notification templates](ref:notification-templates). - -However, you cannot customize webhook data structure or format, including JSON fields or sending data in XML, nor can you change the webhook HTTP headers. - -{{< /admonition >}} - -## Procedure - -To create your Webhook integration in Grafana Alerting, complete the following steps. - -1. Navigate to **Alerts & IRM** -> **Alerting** -> **Contact points**. -1. Click **+ Add contact point**. -1. Enter a contact point name. -1. From the Integration list, select **Webhook**. -1. In the **URL** field, copy in your Webhook URL. -1. Click **Test** to check that your integration works. - - ** For Grafana Alertmanager only.** - -1. Click **Save contact point**. - -## Next steps - -The Webhook contact point is ready to receive alert notifications. - -To add this contact point to your alert, complete the following steps. - -1. In Grafana, navigate to **Alerting** > **Alert rules**. -1. Edit or create a new alert rule. -1. Scroll down to the **Configure labels and notifications** section. -1. Under Notifications, click **Select contact point**. -1. From the drop-down menu, select the previously created contact point. -1. **Click Save rule and exit**. +| Key | Type | Description | +| -------------- | ------ | ----------------------------------------------------------------------------------- | +| `status` | string | Current status of the alert, `firing` or `resolved`. | +| `labels` | object | Labels that are part of this alert, map of string keys to string values. | +| `annotations` | object | Annotations that are part of this alert, map of string keys to string values. | +| `startsAt` | string | Start time of the alert. | +| `endsAt` | string | End time of the alert, default value when not resolved is `0001-01-01T00:00:00Z`. | +| `values` | object | Values that triggered the current status. | +| `generatorURL` | string | URL of the alert rule in the Grafana UI. | +| `fingerprint` | string | The labels fingerprint, alarms with the same labels will have the same fingerprint. | +| `silenceURL` | string | URL to silence the alert rule in the Grafana UI. | +| `dashboardURL` | string | A link to the Grafana Dashboard if the alert has a Dashboard UID annotation. | +| `panelURL` | string | A link to the panel if the alert has a Panel ID annotation. | +| `imageURL` | string | URL of a screenshot of a panel assigned to the rule that created this notification. | diff --git a/docs/sources/alerting/configure-notifications/mute-timings.md b/docs/sources/alerting/configure-notifications/mute-timings.md index 1ef726267e3..79be30654e0 100644 --- a/docs/sources/alerting/configure-notifications/mute-timings.md +++ b/docs/sources/alerting/configure-notifications/mute-timings.md @@ -39,7 +39,9 @@ refs: # Configure mute timings -A mute timing is a recurring interval of time when no new notifications for a policy are generated or sent. Use them to prevent alerts from firing a specific and reoccurring period, for example, a regular maintenance period or weekends. +A mute timing is a recurring interval that stops notifications for one or multiple notification policies during a specified period. It suppresses notifications but does not interrupt alert evaluation. + +Use mute timings to temporarily pause notifications for a specific recurring period, such as a regular maintenance window or weekends. {{< admonition type="note" >}} Mute timings are assigned to a [specific Alertmanager](ref:alertmanager-architecture) and only suppress notifications for alerts managed by that Alertmanager. diff --git a/docs/sources/alerting/configure-notifications/template-notifications/reference.md b/docs/sources/alerting/configure-notifications/template-notifications/reference.md index e20d31ee77b..905ad86e264 100644 --- a/docs/sources/alerting/configure-notifications/template-notifications/reference.md +++ b/docs/sources/alerting/configure-notifications/template-notifications/reference.md @@ -96,25 +96,25 @@ You can execute this template by passing the dot (`.`): `Alert` contains data for an individual alert: -| Name | Type | Description | -| -------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | -| `Status` | string | Firing or resolved. | -| `Labels` | [KV](#kv) | The labels for this alert. It includes all [types of labels](ref:label-types). | -| `Annotations` | [KV](#kv) | The annotations for this alert. | -| `StartsAt` | [Time](#time) | The time the alert fired | -| `EndsAt` | [Time](#time) | Only set if the end time of an alert is known. Otherwise set to a configurable timeout period from the time since the last alert was received. | -| `GeneratorURL` | string | A link to Grafana, or the source of the alert if using an external alert generator. | -| `Fingerprint` | string | A unique string that identifies the alert. | +| Name | Type | Description | +| -------------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Status` | string | Firing or resolved. | +| `Labels` | [KV](#kv) | The labels associated with this alert.
It includes all [types of labels](ref:label-types), but only query labels used in the alert condition. | +| `Annotations` | [KV](#kv) | The annotations for this alert. | +| `StartsAt` | [Time](#time) | The time the alert fired | +| `EndsAt` | [Time](#time) | Only set if the end time of an alert is known. Otherwise set to a configurable timeout period from the time since the last alert was received. | +| `GeneratorURL` | string | A link to Grafana, or the source of the alert if using an external alert generator. | +| `Fingerprint` | string | A unique string that identifies the alert. | Grafana-managed alerts include these additional properties: -| Name | Type | Description | -| -------------- | --------- | ------------------------------------------------------------------------------------ | -| `DashboardURL` | string | A link to the Grafana Dashboard if the alert has a Dashboard UID annotation. | -| `PanelURL` | string | A link to the panel if the alert has a Panel ID annotation. | -| `SilenceURL` | string | A link to silence the alert. | -| `Values` | [KV](#kv) | The values of all expressions, including Classic Conditions. | -| `ValueString` | string | A string that contains the labels and value of each reduced expression in the alert. | +| Name | Type | Description | +| -------------- | --------- | -------------------------------------------------------------------------------------------------- | +| `DashboardURL` | string | A link to the Grafana Dashboard if the alert has a Dashboard UID annotation. | +| `PanelURL` | string | A link to the panel if the alert has a Panel ID annotation. | +| `SilenceURL` | string | A link to silence the alert. | +| `Values` | [KV](#kv) | The values of expressions used to evaluate the alert condition. Only relevant values are included. | +| `ValueString` | string | A string that contains the labels and value of each reduced expression in the alert. | This example iterates over the list of firing and resolved alerts (`.Alerts`) in the notification and prints the data for each alert: diff --git a/docs/sources/alerting/fundamentals/_index.md b/docs/sources/alerting/fundamentals/_index.md index 934f019cfd3..147a5e36d2d 100644 --- a/docs/sources/alerting/fundamentals/_index.md +++ b/docs/sources/alerting/fundamentals/_index.md @@ -132,7 +132,7 @@ Each notification policy decides where to send the alert (contact point) and whe ### Silences and mute timings -[Silences](ref:silences) and [mute timings](ref:mute-timings) allow you to pause notifications for specific alerts or even entire notification policies. Use a silence to pause notifications on an ad-hoc basis, such as during a maintenance window; and use mute timings to pause notifications at regular intervals, such as evenings and weekends. +[Silences](ref:silences) and [mute timings](ref:mute-timings) allow you to pause notifications without interrupting alert rule evaluation. Use a silence to pause notifications on a one-time basis, such as during a maintenance window; and use mute timings to pause notifications at regular intervals, such as evenings and weekends. ### Architecture diff --git a/docs/sources/alerting/fundamentals/alert-rule-evaluation/state-and-health.md b/docs/sources/alerting/fundamentals/alert-rule-evaluation/state-and-health.md index cb4f932a5f6..4c871e2d6e7 100644 --- a/docs/sources/alerting/fundamentals/alert-rule-evaluation/state-and-health.md +++ b/docs/sources/alerting/fundamentals/alert-rule-evaluation/state-and-health.md @@ -68,7 +68,7 @@ Alert instances will be routed for [notifications](ref:notifications) when they ### `No Data` and `Error` alerts -When evaluation of an alert rule produces state `No Data` or `Error`, Grafana Alerting generates a new alert instance that have the following additional labels: +When an alert rule evaluation results in a `No Data` or `Error` state, Grafana Alerting immediately creates a new alert instance —skipping the pending period—with the following additional labels: - `alertname`: Either `DatasourceNoData` or `DatasourceError` depending on the state. - `datasource_uid`: The UID of the data source that caused the state. @@ -87,7 +87,7 @@ In [Configure no data and error handling](ref:no-data-and-error-handling), you c Note that `No Data` and `Error` states are supported only for Grafana-managed alert rules. -{{< figure src="/media/docs/alerting/alert-rule-configure-no-data-and-error.png" alt="A screenshot of the `Configure no data and error handling` option in Grafana Alerting." max-width="500px" >}} +{{< figure src="/media/docs/alerting/alert-rule-configure-no-data-and-error-v2.png" alt="A screenshot of the `Configure no data and error handling` option in Grafana Alerting." max-width="500px" >}} {{< docs/shared lookup="alerts/table-configure-no-data-and-error.md" source="grafana" version="" >}} diff --git a/docs/sources/alerting/fundamentals/alert-rules/_index.md b/docs/sources/alerting/fundamentals/alert-rules/_index.md index 47e410b8564..439c56b130c 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/_index.md +++ b/docs/sources/alerting/fundamentals/alert-rules/_index.md @@ -25,9 +25,17 @@ refs: destination: /docs/grafana-cloud/connect-externally-hosted/data-sources/prometheus/configure-prometheus-data-source/#alerting queries-and-conditions: - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#data-source-queries - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/#data-source-queries + alert-condition: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#alert-condition + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/#alert-condition + recorded-queries: + - pattern: /docs/ + destination: /docs/grafana//administration/recorded-queries/ notification-images: - pattern: /docs/grafana/ destination: /docs/grafana//alerting/configure-notifications/template-notifications/images-in-notifications/ @@ -45,14 +53,9 @@ refs: destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/create-recording-rules/ expression-queries: - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#expression-queries + destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#advanced-options-expressions - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/#expression-queries - alert-condition: - - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/fundamentals/alert-rules/queries-conditions/#alert-condition - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/#alert-condition + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/queries-conditions/#advanced-options-expressions alert-rule-evaluation: - pattern: /docs/grafana/ destination: /docs/grafana//alerting/fundamentals/alert-rules/rule-evaluation/ @@ -64,8 +67,8 @@ refs: An alert rule is a set of evaluation criteria for when an alert rule should fire. An alert rule consists of: -- Queries and expressions that select the data set to evaluate. -- A condition (the threshold) that the query must meet or exceed to trigger the alert instance. +- [Queries](ref:queries-and-conditions) that select the dataset to evaluate. +- An [alert condition](ref:alert-condition) (the threshold) that the query must meet or exceed to trigger the alert instance. - An interval that specifies the frequency of [alert rule evaluation](ref:alert-rule-evaluation) and a duration indicating how long the condition must be met to trigger the alert instance. - Other customizable options, for example, setting what should happen in the absence of data, notification messages, and more. diff --git a/docs/sources/alerting/fundamentals/alert-rules/queries-conditions.md b/docs/sources/alerting/fundamentals/alert-rules/queries-conditions.md index 229816db306..175306e8ef1 100644 --- a/docs/sources/alerting/fundamentals/alert-rules/queries-conditions.md +++ b/docs/sources/alerting/fundamentals/alert-rules/queries-conditions.md @@ -17,21 +17,16 @@ labels: title: Queries and conditions weight: 104 refs: - data-sources: - - pattern: /docs/grafana/ - destination: /docs/grafana//datasources/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/connect-externally-hosted/data-sources/ data-source-alerting: - pattern: /docs/grafana/ destination: /docs/grafana//alerting/fundamentals/alert-rules/#supported-data-sources - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rules/#supported-data-sources - alert-rule-evaluation: + state-and-health: - pattern: /docs/grafana/ - destination: /docs/grafana//alerting/fundamentals/alert-rule-evaluation/ + destination: /docs/grafana//alerting/fundamentals/state-and-health/ - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/alert-rule-evaluation/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/fundamentals/state-and-health/ query-transform-data: - pattern: /docs/grafana/ destination: /docs/grafana//panels-visualizations/query-transform-data/ @@ -41,71 +36,122 @@ refs: # Queries and conditions -In Grafana, queries fetch and transform data from [data sources,](ref:data-sources) which include databases like MySQL or PostgreSQL, time series databases like Prometheus or InfluxDB, and services like Amazon CloudWatch or Azure Monitor. +In Grafana, queries fetch and transform data from data sources, which include databases like MySQL or PostgreSQL, time series databases like Prometheus or InfluxDB, and services like Amazon CloudWatch or Azure Monitor. -A query specifies the data to extract from a data source, with the syntax varying based on the type of data source used. +An alert rule defines the following components: -In Alerting, an alert rule defines of one or more queries and expressions that select the data you want to measure and a [condition](#alert-condition) that needs to be met before an alert rule fires. +- A [query](#data-source-queries) that specifies the data to retrieve from a data source, with the syntax depending on the type of data source used. +- A [condition](#alert-condition) that must be met before the alert rule fires. +- Optional [expressions](#advanced-options-expressions) to perform transformations on the retrieved data. + +Alerting periodically runs the queries and expressions, evaluating the condition. If the condition is breached, an alert instance is triggered for each time series. ## Data source queries -Alerting queries are the same type of queries available in Grafana panels. Queries in Grafana can be applied in various ways, depending on the data source and query language being used. However, not all [data sources support Alerting](ref:data-source-alerting). +Alerting queries are the same as the queries used in Grafana panels, but Grafana-managed alerts are limited to querying [data sources that have Alerting enabled](ref:data-source-alerting). -Each data source’s query editor provides a customized user interface to help you write queries that take advantage of its unique capabilities. For additional information about queries in Grafana, refer to [Query and transform data](ref:query-transform-data). +Queries in Grafana can be applied in various ways, depending on the data source and query language being used. Each data source’s query editor provides a customized user interface to help you write queries that take advantage of its unique capabilities. -Some common types of query components include: +For more details about queries in Grafana, refer to [Query and transform data](ref:query-transform-data). -**Metrics or data fields**: Specify the specific metrics or data fields you want to retrieve, such as CPU usage, network traffic, or sensor readings. +{{< figure src="/media/docs/alerting/alerting-query-conditions-default-options.png" max-width="750px" caption="Define alert query and alert condition" >}} -**Time range**: Define the time range for which you want to fetch data, such as the last hour, a specific day, or a custom time range. +## Alert condition -**Filters**: Apply filters to narrow down the data based on specific criteria, such as filtering data by a specific tag, host, or application. +The alert condition is the query or expression that determines whether the alert fires or not depending whether the value satisfies the specified comparison. There can be only one condition which determines the triggering of the alert. -**Aggregations**: Perform aggregations on the data to calculate metrics like averages, sums, or counts over a given time period. +If the queried data meets the defined condition, Grafana fires the alert. -**Grouping**: Group the data by specific dimensions or tags to create aggregated views or breakdowns. +When using **Default options**, the `When` input [reduces the query data](#reduce), and the last input defines the threshold condition. -{{% admonition type="note" %}} -Grafana doesn't support alert queries with template variables. More details [here](https://community.grafana.com/t/template-variables-are-not-supported-in-alert-queries-while-setting-up-alert/2514). -{{% /admonition %}} +When using **Advanced options**, you have to choose one of your queries or expressions as the alert condition. -## Expression queries +## Advanced options: Expressions -In Grafana, an expression is used to perform calculations, transformations, or aggregations on the data source queried data. It allows you to create custom metrics or modify existing metrics based on mathematical operations, functions, or logical expressions. +Expressions are only available for Grafana-managed alerts and when the **Advanced options** are enabled. -By leveraging expression queries, users can perform tasks such as calculating the percentage change between two values, applying functions like logarithmic or trigonometric functions, aggregating data over specific time ranges or dimensions, and implementing conditional logic to handle different scenarios. +In Grafana, expressions allow you to perform calculations, transformations, or aggregations on queried data. They modify existing metrics through mathematical operations, functions, or logical expressions. -In Alerting, you can only use expressions for Grafana-managed alert rules. For each expression, you can choose from the math, reduce, and resample expressions. These are called multi-dimensional rules, because they generate an alert instance for each series. +With expression queries, you can perform tasks such as calculating the percentage change between two values, applying functions like logarithmic or trigonometric functions, aggregating data over specific time ranges or dimensions, and implementing conditional logic to handle different scenarios. -**Reduce** +{{< figure src="/media/docs/alerting/alert-rule-expressions.png" max-width="750px" caption="Alert rule expressions" >}} -Aggregates time series values in the selected time range into a single value. It's not necessary for [rules using numeric data](#alert-on-numeric-data). +The following expressions are available: -**Math** +### Reduce -Performs free-form math functions/operations on time series and number data. Can be used to preprocess time series data or to define an alert condition for number data. For example: +Aggregates time series values within the selected time range into a single number. + +Reduce takes one or more time series and transform each series into a single number, which can then be compared in the alert condition. + +The following aggregations functions are included: `Min`, `Max`, `Mean`, `Mediam`, `Sum`, `Count`, and `Last`. + +### Math + +Performs free-form math functions/operations on time series data and numbers. For instance, `$A + 1` or `$A * 100`. + +You can also use a Math expression to define the alert condition for numbers. For example: - `$B > 70` should fire if the value of B (query or expression) is more than 70. - `$B < $C * 100` should fire if the value of B is less than the value of C multiplied by 100. If queries being compared have multiple series in their results, series from different queries are matched if they have the same labels or one is a subset of the other. -**Resample** +### Resample Realigns a time range to a new set of timestamps, this is useful when comparing time series data from different data sources where the timestamps would otherwise not align. -**Threshold** +### Threshold -Checks if any time series data matches the threshold condition. +Compares single numbers from previous queries or expressions (e.g., `$A`, `$B`) to a specified condition. It's often used to define the alert condition. -The threshold expression allows you to compare two single values. It returns `0` when the condition is false and `1` if the condition is true. The following threshold functions are available: +The threshold expression allows the comparison between two single values. Available threshold functions are: -- Is above (x > y) -- Is below (x < y) -- Is within range (x > y1 AND x < y2) -- Is outside range (x < y1 AND x > y2) +- **Is above**: `$A > 5` +- **Is below**: `$B < 3` +- **Is equal to**: `$A == 2` +- **Is not equal to**: `$B =! 4` +- **Is above or equal to**: `$A >= 8` +- **Is below or equal to**: `$B <= 16` +- **Is within range**: `$A > 0 AND $A < 10` +- **Is outside range**: `$B < 0 OR $B > 100` +- **Is within range included**: `$A >= 0 AND $A <= 10` +- **Is outside range included**: `$B <= 0 OR $B >= 100` -**Classic condition (legacy)** +A threshold returns `0` when the condition is false and `1` when true. + +If the threshold is set as the alert condition, the alert fires when the threshold returns `1`. + +#### Recovery threshold + +To reduce the noise from 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. + +The value of a flapping metric can continually go above and below a threshold, resulting 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 might trigger a notification: + +- 980 -> 1010 triggers a firing alert. +- 1010 -> 990 triggers a resolving alert. +- 990 -> 1020 triggers a firing alert again. + +To prevent this, you can set a recovery threshold to define two thresholds instead of one: + +1. An alert is triggered when the first threshold is crossed. +1. An alert is resolved only when the second (recovery) threshold is crossed. + +In the previous example, setting the recovery threshold to 900ms means the alert only resolves when the latency falls below 900ms: + +- 980 -> 1010 triggers a firing alert. +- 1010 -> 990 does not resolve the alert, keeping it in the firing state. +- 990 -> 1020 keeps the alert in the firing state. + +The recovery threshold mitigates unnecessary alert state changes and reduces alert noise. + +{{< collapse title="Classic condition (legacy)" >}} + +#### Classic condition (legacy) Classic conditions exist mainly for compatibility reasons and should be avoided if possible. @@ -113,66 +159,35 @@ Classic condition checks if any time series data matches the alert condition. It | Condition operators | How it works | | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| and | Two conditions before and after must be true for the overall condition to be true. | -| or | If one of conditions before and after are true, the overall condition is true. | -| logic-or | If the condition before `logic-or` is true, the overall condition is immediately true, without evaluating subsequent conditions. For instance, `TRUE and TRUE logic-or FALSE and FALSE` evaluate to `TRUE`, because the preceding condition returns `TRUE`. | +| `and` | Two conditions before and after must be true for the overall condition to be true. | +| `or` | If one of conditions before and after are true, the overall condition is true. | +| `logic-or` | If the condition before `logic-or` is true, the overall condition is immediately true, without evaluating subsequent conditions. For instance, `TRUE and TRUE logic-or FALSE and FALSE` evaluate to `TRUE`, because the preceding condition returns `TRUE`. | -## Aggregations +The following aggregation functions are also available to further refine your query. -Grafana Alerting provides the following aggregation functions to enable you to further refine your query. +| Function | What it does | +| ------------------ | ------------------------------------------------------------------------------- | +| `avg` | Displays the average of the values | +| `min` | Displays the lowest value | +| `max` | Displays the highest value | +| `sum` | Displays the sum of all values | +| `count` | Counts the number of values in the result | +| `last` | Displays the last value | +| `median` | Displays the median value | +| `diff` | Displays the difference between the newest and oldest value | +| `diff_abs` | Displays the absolute value of diff | +| `percent_diff` | Displays the percentage value of the difference between newest and oldest value | +| `percent_diff_abs` | Displays the absolute value of `percent_diff` | +| `count_non_null` | Displays a count of values in the result set that aren't `null` | -These functions are available for **Reduce** and **Classic condition** expressions only. - -| Function | Expression | What it does | -| ---------------- | ---------------- | ------------------------------------------------------------------------------- | -| avg | Reduce / Classic | Displays the average of the values | -| min | Reduce / Classic | Displays the lowest value | -| max | Reduce / Classic | Displays the highest value | -| sum | Reduce / Classic | Displays the sum of all values | -| count | Reduce / Classic | Counts the number of values in the result | -| last | Reduce / Classic | Displays the last value | -| median | Reduce / Classic | Displays the median value | -| diff | Classic | Displays the difference between the newest and oldest value | -| diff_abs | Classic | Displays the absolute value of diff | -| percent_diff | Classic | Displays the percentage value of the difference between newest and oldest value | -| percent_diff_abs | Classic | Displays the absolute value of percent_diff | -| count_non_null | Classic | Displays a count of values in the result set that aren't `null` | - -## Alert condition - -An alert condition is the query or expression that determines whether the alert fires or not depending on the value it yields. There can be only one condition which determines the triggering of the alert. - -After you have defined your queries and expressions, choose one of them as the alert rule condition. By default, the last expression added is used as the alert condition. - -When the queried data satisfies the defined condition, Grafana triggers the associated alert, which can be configured to send notifications through various channels like email, Slack, or PagerDuty. - -For details about how the alert evaluation triggers notifications, refer to [Alert rule evaluation](ref:alert-rule-evaluation). - -## Recovery threshold - -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. - -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 triggers a notification. - -To solve this problem, you can set a (custom) recovery threshold, which basically means having two thresholds instead of one: - -1. An alert is triggered when the first threshold is crossed. -2. An alert 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 only stops firing when it goes under 900ms and flapping is reduced. - -For details about how the alert evaluation triggers notifications, refer to [Alert rule evaluation](ref:alert-rule-evaluation). +{{< /collapse >}} ## Alert on numeric data Among certain data sources numeric data that is not time series can be directly alerted on, or passed into Server Side Expressions (SSE). This allows for more processing and resulting efficiency within the data source, and it can also simplify alert rules. -When alerting on numeric data instead of time series data, there is no need to reduce each labeled time series into a single number. Instead labeled numbers are returned to Grafana instead. +When alerting on numeric data instead of time series data, there is no need to [reduce](#reduce) each labeled time series into a single number. Instead labeled numbers are returned to Grafana instead. -### Tabular Data +#### Tabular Data This feature is supported with backend data sources that query tabular data: diff --git a/docs/sources/alerting/fundamentals/notifications/_index.md b/docs/sources/alerting/fundamentals/notifications/_index.md index 538eaa0d00a..4c85da09ef6 100644 --- a/docs/sources/alerting/fundamentals/notifications/_index.md +++ b/docs/sources/alerting/fundamentals/notifications/_index.md @@ -126,7 +126,7 @@ Grafana Alerting provides advanced notification capabilities that you’ll find For instance, you can customize notifications with shared [templates](ref:templates) that provide actionable alert information and can be reused for multiple notifications. -Additionally, you can use [silences](ref:silences) and [mute timings](ref:mute-timings) to pause notifications for a given time window or at regular intervals, respectively. +Additionally, you can use [silences](ref:silences) and [mute timings](ref:mute-timings) to pause or suppress notifications without interrupting alert evaluation. ## Architecture diff --git a/docs/sources/alerting/fundamentals/notifications/notification-policies.md b/docs/sources/alerting/fundamentals/notifications/notification-policies.md index 48a4bd70e37..ae8d53f1520 100644 --- a/docs/sources/alerting/fundamentals/notifications/notification-policies.md +++ b/docs/sources/alerting/fundamentals/notifications/notification-policies.md @@ -76,7 +76,7 @@ Each policy consists of a set of label matchers (0 or more) that specify which a {{< figure src="/media/docs/alerting/notification-routing.png" max-width="750px" caption="Matching alert instances with notification policies" alt="Example of a notification policy tree" >}} {{< admonition type="tip" >}} -For a practical example of routing with notification policies, refer to our [Getting Started with Alert Instances and Notification Routing tutorial](https://grafana.com/tutorials/alerting-get-started-pt4/). +For a practical example of routing with notification policies, refer to our [Getting Started with Alert Instances and Notification Routing tutorial](https://grafana.com/tutorials/alerting-get-started-pt2/). {{< /admonition >}} ## Routing diff --git a/docs/sources/alerting/monitor-status/view-alert-rules.md b/docs/sources/alerting/monitor-status/view-alert-rules.md index 8bc68611a2d..293faf3a0cf 100644 --- a/docs/sources/alerting/monitor-status/view-alert-rules.md +++ b/docs/sources/alerting/monitor-status/view-alert-rules.md @@ -5,7 +5,7 @@ aliases: - ../../alerting/alerting-rules/rule-list/ # /docs/grafana//alerting/alerting-rules/rule-list - ../../alerting/manage-notifications/view-alert-rules/ # /docs/grafana//alerting/manage-notifications/view-alert-rules/ canonical: https://grafana.com/docs/grafana/latest/alerting/monitor-status/view-alert-rules/ -description: View alert rules +description: View alert rules, compare their versions, and restore previous alert rules. keywords: - grafana - alerting @@ -43,6 +43,8 @@ This view includes filters to simplify managing large volumes of alerts. You can filter by data sources, dashboards, and alert rule properties such as state, type, health, and contact points. The **Search** input allows you to filter by additional parameters like folders, evaluation groups, labels, and more. +## Change alert rules list view + You can also change how the rule list is displayed using the **View as** option. - **Grouped**: Displays Grafana rules grouped by folder and evaluation group, and data-source rules by namespace and evaluation group. This is the default view. @@ -56,3 +58,14 @@ Select a group to expand it and view the list of alert rules within that group. {{< figure src="/media/docs/alerting/view-alert-rule-list-with-actions.png" max-width="750px" alt="View alert rule state and alert rule health in Grafana Alerting" >}} For details on how rule states and alert instance states are displayed, refer to [View alert state](ref:view-alert-state). + +## View and compare alert rules versions. + +To view previous alert rules for an alert, complete the following steps. + +1. Navigate to **Alerts & IRM -> Alerting -> Alert rules**. +1. Select an alert rule and click **View**. +1. Click the **Versions** tab. + The page displays a list of the previous rule versions. + +On the Alert rule's Versions page you can view and compare the previous rule versions. diff --git a/docs/sources/alerting/set-up/meta-monitoring.md b/docs/sources/alerting/set-up/meta-monitoring.md index 4c29f6ac4a9..46d8c517f8c 100644 --- a/docs/sources/alerting/set-up/meta-monitoring.md +++ b/docs/sources/alerting/set-up/meta-monitoring.md @@ -2,6 +2,7 @@ aliases: - ../meta-monitoring/ # /docs/grafana//alerting/meta-monitoring/ - ../monitoring/ # /docs/grafana//alerting/monitoring/ + - ../monitor/ # /docs/grafana//alerting/monitor/ canonical: https://grafana.com/docs/grafana/latest/alerting/set-up/meta-monitoring description: Monitor your alerting metrics to ensure you identify potential issues before they become critical. keywords: diff --git a/docs/sources/alerting/set-up/performance-limitations/index.md b/docs/sources/alerting/set-up/performance-limitations/index.md index 69becbad450..b8524e4c8a7 100644 --- a/docs/sources/alerting/set-up/performance-limitations/index.md +++ b/docs/sources/alerting/set-up/performance-limitations/index.md @@ -61,7 +61,13 @@ For more information, refer to [this GitHub issue](https://github.com/grafana/gr If you have a high number of alert instances, it can happen that the load on the database gets very high, as each state transition of an alert instance is saved in the database. -This can be prevented by writing to the database periodically. For this the feature flag `alertingSaveStatePeriodic` needs +### Compressed alert state + +When the `alertingSaveStateCompressed` feature toggle is enabled, Grafana saves the alert rule state in a compressed form, reducing database overhead for alerts with many instances. + +### Save state periodically + +High load can be also prevented by writing to the database periodically. For this the feature flag `alertingSaveStatePeriodic` needs to be enabled. By default, it saves the states every 5 minutes to the database and on each shutdown. The periodic interval can also be configured using the `state_periodic_save_interval` configuration flag. During this process, Grafana deletes all existing alert instances from the database and then writes the entire current set of instances back in batches in a single transacton. diff --git a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md index b7eb4b841fa..850600cc074 100644 --- a/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md +++ b/docs/sources/alerting/set-up/provision-alerting-resources/file-provisioning/index.md @@ -511,6 +511,8 @@ settings: # endpointUrl: https://custom_url/api/chat.postMessage # + color: {{ if eq .Status "firing" }}#D63232{{ else }}#36a64f{{ end }} + # title: | {{ template "slack.default.title" . }} text: | diff --git a/docs/sources/breaking-changes/_index.md b/docs/sources/breaking-changes/_index.md index af76c612b89..fa0628a51d9 100644 --- a/docs/sources/breaking-changes/_index.md +++ b/docs/sources/breaking-changes/_index.md @@ -25,7 +25,7 @@ For our purposes, a breaking change is any change that requires users or operato {{% admonition type="note" %}} -To learn what's available in a Grafana release, refer to the [What's new ]({{< relref "../whatsnew/" >}}) page for each version. For the steps we recommend when you upgrade, check out the [Upgrade guide]({{< relref "../upgrade-guide/" >}}) for each version. +To learn what's available in a Grafana release, refer to the [What's new ](../whatsnew/) page for each version. For the steps we recommend when you upgrade, check out the [Upgrade guide](../upgrade-guide/) for each version. {{% /admonition %}} diff --git a/docs/sources/breaking-changes/breaking-changes-v10-0.md b/docs/sources/breaking-changes/breaking-changes-v10-0.md index 946ba52c93c..8250dba93d2 100644 --- a/docs/sources/breaking-changes/breaking-changes-v10-0.md +++ b/docs/sources/breaking-changes/breaking-changes-v10-0.md @@ -34,7 +34,7 @@ For each change, the provided 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.0 What’s new]({{< relref "../whatsnew/whats-new-in-v10-0/" >}}). For the specific steps we recommend when you upgrade to v10.0, check out our [Upgrade guide]({{< relref "../upgrade-guide/upgrade-v10.0/index.md" >}}). +For release highlights and deprecations, refer to our [v10.0 What’s new](../../whatsnew/whats-new-in-v10-0/). For the specific steps we recommend when you upgrade to v10.0, check out our [Upgrade guide](../../upgrade-guide/upgrade-v10.0/). | Option | Description | | ------ | ----------- | -| Source dashboard | Select the dashboard from which you want to generate the report. | -| [Template variables (optional)](#template-variables) | Select the variable values for the selected dashboard. This option is only displayed if the dashboard has variables. | -| [Time range (optional)](#time-range) | By default, reports use the saved time range of the dashboard. Optionally, you can change the time range of the report. | -| Add another dashboard | Add more dashboards to the report. Additional dashboards will be rendered as new pages in the same PDF file, or additional images if you chose to embed images in your report email. You can't add the same dashboard to a report multiple times. | +| Source dashboard (required) | Select the dashboard from which you want to generate the report. | +| [Template variables](#template-variables) | Select the variable values for the selected dashboard. This option is only displayed if the dashboard has variables. | +| [Time range](#time-range) | If you leave the field empty, reports use the saved time range of the dashboard. Optionally, you can change the time range of the report. | +| Add another dashboard | Add more dashboards to the report. | @@ -179,30 +149,39 @@ At this step, select the dashboard or dashboards on which the report is based, a This option is only displayed if the dashboard has variables. -You can configure report-specific template variables for the dashboard on the report page. The variables that you select will override the variables from the dashboard, and they are used when rendering a PDF file of the report. For detailed information about using template variables, refer to the [Templates and variables](ref:templates-and-variables) section. +You can configure report-specific template variables for the dashboard on the report page. +The variables that you select override the variables from the dashboard. +For detailed information about using template variables, refer to [Variables](ref:templates-and-variables). -The query variables saved with a report might become out of date if the results of that query change. For example, if your template variable queries for a list of hostnames and a new hostname is added, then it will not be included in the report. If that occurs, the selected variables must be manually updated in the report. If you select the **All** value for the template variable or if you keep the dashboard's original variable selection, then the report stays up-to-date as new values are added. +The query variables saved with a report might become out-of-date if the results of that query change. +For example, if your template variable queries for a list of hostnames and a new hostname is added, then it won't be included in the report. +If that occurs, the selected variables must be manually updated in the report. +If you select the **All** value for the template variable or if you keep the dashboard's original variable selection, then the report stays up-to-date as new values are added. #### Time range -By default, reports use the saved time range of the dashboard. Optionally, you can change the time range of the report by: - -- 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. +If you leave the **Time range** field empty, reports use the saved time range of the dashboard. +Optionally, you can change the time range of the report by setting it in the **Time range** field. +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. ##### Report time zones -Reports use the time zone of the dashboard from which they’re 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. +Reports use the time zone of the dashboard from which they're 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 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 you want to use a specific time zone, save the dashboard with a fixed time zone instead of **Browser Time** -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](ref:time-range-controls). +Each dashboard's time zone setting is visible in the [time range controls](ref:time-range-controls). ### 2. Format report -At this step, set the report formatting options. You can select multiple options: +At this step, select one or more report formatting options. +You can select multiple options, but you must select _at least one_: - [Attach the report as a PDF](#attach-the-report-as-a-pdf) - [Include table data as PDF appendix](#table-data-in-pdf) (Public preview only) @@ -212,13 +191,18 @@ At this step, set the report formatting options. You can select multiple options #### Attach the report as a PDF -If you selected the PDF format option, under the **Style the PDF** section, set the following options: +If you selected the PDF format option under the **Style the PDF** section, you can configure the following options: -- **Show template variables** - Click the checkbox to select this option. +- **Configure multiple PDFs** - Click the **Combine all dashboard PDFs in one file** checkbox if you want to generate one PDF file for all the dashboards included in the report. This option is only displayed if your report includes multiple dashboards. +- **Configure report header** - Click the **Show template variables** checkbox to show dashboard variables. - **Orientation** - Set the report orientation in **Portrait** or **Landscape**. Refer to the [Layout and orientation table](#layout-and-orientation) to see examples. - **Layout** - Select one of the following: - - **Simple** - Renders each panel as full-width across the PDF. Refer to the [Layout and orientation table](#layout-and-orientation) to see examples. - - **Grid** - Renders the PDF with the same panel arrangement and width as the source dashboard. Refer to the [Layout and orientation table](#layout-and-orientation) to see examples. + + - **Simple** - Renders each panel as full-width across the PDF. + - **Grid** - Renders the PDF with the same panel arrangement and width as the source dashboard. + + Refer to the [Layout and orientation table](#layout-and-orientation) to see examples. + - **Zoom** - Zoom in to enlarge text in your PDF, or zoom out to see more data (like table columns) per panel. Click **Preview PDF** in the top-right corner of the screen to view a rendered PDF with the options you selected. @@ -238,50 +222,40 @@ Click **Preview PDF** in the top-right corner of the screen to view a rendered P #### Embed a dashboard as an image in the email -You can send a report email with an image of the dashboard embedded in the email instead of attached as a PDF. In this case, the email recipients can see the dashboard at a glance instead of having to open the PDF. +You can send a report email with an image of the dashboard embedded in the email. +This lets the email recipients see the dashboard at a glance. #### Attach a CSV file of the table panel data -{{< admonition type="note" >}} -To use this feature in Grafana Enterprise, you must have [Grafana image renderer plugin](/grafana/plugins/grafana-image-renderer) v3.0. -{{< /admonition >}} +You can attach a CSV file to the report email for each table panel on the selected dashboard. -You can attach a CSV file to the report email for each table panel on the selected dashboard, along with the PDF report. By default, CSV files larger than 10Mb are not sent, which keeps email servers from rejecting the email. You can increase or decrease this limit in the [reporting configuration](ref:rendering-configuration). - -This feature relies on the same plugin that supports the [image rendering](ref:image-rendering) features. - -When the CSV file is generated, it is temporarily written to the `csv` folder in the Grafana `data` folder. - -A background job runs every 10 minutes and removes temporary CSV files. You can configure how long a CSV file should be stored before being removed by configuring the [temp-data-lifetime](ref:temp-data-lifetime) setting. This setting also affects how long a renderer PNG file should be stored. - -Click **Download CSV** in the top-right corner of the screen to see the file. +Click **Download CSV** in the top-right corner of the screen to download a zipped file of the CSV files for your selected dashboard. #### Table data in PDF -{{% admonition type="note" %}} -Available in public preview (`pdfTables` feature toggle) in [Grafana Enterprise](ref:grafana-enterprise) v10.3+ with the [Grafana image renderer plugin](/grafana/plugins/grafana-image-renderer) v3.0+, as well as [Grafana Cloud](/docs/grafana-cloud/). -{{% /admonition %}} +{{< admonition type="note" >}} +Available in public preview (`pdfTables` feature toggle) in [Grafana Enterprise](ref:grafana-enterprise) v10.3+ with the [Grafana image renderer plugin](/grafana/plugins/grafana-image-renderer) v3.0+, as well as in [Grafana Cloud](/docs/grafana-cloud/). +{{< /admonition >}} When there's more data in your table visualizations than can be shown in the dashboard PDF, you can select one of these two options to access all table visualization data as PDF in your reports: -- **Include table data as PDF appendix** - Adds an appendix to the main dashboard PDF. +- **Include table data as PDF appendix** - Adds an appendix to the dashboard PDF. - **Attach a separate PDF of table data** - Generates a separate PDF file. -This feature relies on the same plugin that supports the [image rendering](ref:image-rendering) features. - ### 3. Schedule -At this step, set scheduling information. Options vary depending on the frequency you select. +At this step, set scheduling information. +Options vary depending on the frequency you select. | Option | Description | | ------ | ----------- | -| Frequency | Scheduled reports can be sent once, or repeated on an hourly, daily, weekly, or monthly basis, or sent at custom intervals. You can also disable scheduling by selecting **Never**, for example to send the report using the API. | +| Frequency | You can schedule reports to be sent once, or repeated on an hourly, daily, weekly, or monthly basis, or sent at custom intervals. You can also disable scheduling by selecting **Never**. For example, you might want to [send the report using the API](#send-a-report-using-the-api). | | Time | Choose one of the following:
  • **Send now** sends the report immediately after you save it. To stop sending the report at some point in the future, add an end date.
  • **Send later** schedules a report for a later date. When you select this option, the required **Start date**, **Start time**, and **Time zone** options are displayed.
| -| End date | If you leave the end date empty, the report is sent out indefinitely. | +| End date | If you leave this field empty, the report is sent out indefinitely. | | Send only from Monday to Friday | For reports that have an hourly or daily frequency, you can choose to send them only from Monday to Friday. | -| Send on the last day of the month | When you schedule a report with a monthly frequency, and set the start date between the 29th and the 31st of the month, the report is only sent during the months that have those dates. If you want the report to be sent every month, select this option instead. This way, the report is sent on the last day of every month regardless of how many days there are in any given month. | +| Send on the last day of the month | When you schedule a report with a monthly frequency, and set the start date between the 29th and the 31st of the month, the report is only sent during the months that have those dates. If you want the report to be sent every month, select the **Send on the last day of the month** option. This way, the report is sent on the last day of every month regardless of how many days there are in the month. | @@ -289,23 +263,29 @@ At this step, set scheduling information. Options vary depending on the frequenc At this step, enter information related to sharing the report: + + | Option | Description | | ------ | ----------- | -| Report name | Name of the report as you want it to appear in the **Reports** list. The report name also populates the email subject line. | -| Recipients | Enter the email addresses of the people or teams that you want to receive the report, separated by commas or semicolons. | +| Report name (required) | The name of the report as you want it to appear in the **Reports** list. The report name also populates the email subject line. | +| Recipients (required) | Enter the email addresses of the people or teams that you want to receive the report, separated by commas or semicolons. | | Reply-to email address | The address that appears in the **Reply to** field of the email. | -| Message | Message body in the email with the report. | -| Include a dashboard link | Include a link to the dashboard from within the report email. | +| Message | The body of the message in the email with the report. | +| Include a dashboard link | Include a links to the dashboards in the report email. | -Click **Send test email** in the top-right corner of the screen to verify that the configuration works as expected and to verify that emails are working. You can choose to send this email to the recipients configured for the report, or to a different set of email addresses only used for testing. The last saved version of the report will be sent to selected emails. + + +Click **Send test email** in the top-right corner of the screen to verify that the configuration works as expected and to verify that emails are working. +You can choose to send this email to the recipients configured for the report, or to a different set of email addresses only used for testing. ### 5. Confirm -At this step, the confirmation page displays all your the settings. Review them and confirm that they're correct or click the provided **Edit** links for each section to make updates. +At this step, the confirmation page displays all the report settings. +Review them and confirm that they're correct or click the provided **Edit** links for each section to make updates. Then, click **Send now** or **Schedule send**. @@ -313,7 +293,7 @@ You can also save the report as a draft or discard it. Discarding the report is ## Send a report using the API -You can send reports programmatically with the [send report](ref:send-report) endpoint in the [HTTP APIs](ref:http-apis). +You can send reports programmatically with the [send report](ref:send-report) endpoint using the HTTP API. ## Manage reports @@ -321,7 +301,7 @@ On the **Reports** page, you can view and manage your existing reports or create ![Reports page](/media/docs/grafana/dashboards/screenshot-reports-page-v11.5.png) -### Edit +### Edit reports To edit a report, follow these steps: @@ -331,9 +311,10 @@ To edit a report, follow these steps: 1. When you've finished making changes, click **Confirm** at the top of the screen to go to the last step. 1. Click **Update report**. -### Pause or resume a report +### Pause or resume reports {#pause-a-report} -You can pause and resume sending reports from the report list view. To do this, follow these steps: +You can pause and resume sending reports from the report list view. +To do this, follow these steps: 1. In the main menu, click **Dashboards > Reporting**. 1. On the row of the report you want to update, do one of the following: @@ -341,11 +322,22 @@ You can pause and resume sending reports from the report list view. To do this, - Click the pause icon - The report won't be sent according to its schedule until it's resumed. - Click the resume icon - The report resumes on its previous schedule. +### Delete reports + +To delete a report, follow these steps: + +1. In the main menu, click **Dashboards > Reporting**. +1. On the row of the report you want to update, click the trash can icon. +1. Click **Delete** to confirm. + +Deleting a report is irreversible. + ## Troubleshoot Reporting -To troubleshoot and get more log information, enable debug logging in the configuration file. Refer to [Configuration](ref:configuration) for more information. +To troubleshoot and get more log information, enable debug logging in the configuration file. +Refer to the [log filters configuration documentation](ref:log-filters) for more information. ```bash [log] -filters = report:debug +filters = rendering:debug,report.api:debug,report.render:debug,report.scheduler:debug,report.sender:debug,report.service:debug ``` diff --git a/docs/sources/dashboards/create-reports/report-settings/index.md b/docs/sources/dashboards/create-reports/report-settings/index.md index c442a4346a8..b878953b71a 100644 --- a/docs/sources/dashboards/create-reports/report-settings/index.md +++ b/docs/sources/dashboards/create-reports/report-settings/index.md @@ -12,21 +12,17 @@ title: Reporting settings description: Manage organizational Reporting settings weight: 700 refs: - grafana-enterprise: + change-ui-theme: - pattern: /docs/grafana/ - destination: /docs/grafana//introduction/grafana-enterprise/ + destination: /docs/grafana//administration/organization-preferences/#change-grafana-ui-theme - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//introduction/grafana-enterprise/ - configuration: - - pattern: /docs/grafana/ - destination: /docs/grafana//setup-grafana/configure-grafana/#filters - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//setup-grafana/configure-grafana/#filters + destination: /docs/grafana//administration/organization-preferences/#change-grafana-ui-theme --- # Reporting settings -You can configure organization-wide report settings and branding options in **Dashboards > Reporting > Settings**. Settings are applied to all the reports for the current organization. +You can configure organization-wide report settings and branding options in **Dashboards > Reporting > Settings**. +Settings are applied to all the reports for the current organization. ## Attachment settings @@ -34,13 +30,22 @@ The options in this section control the branding and theming of the report attac ### PDF -- **Company logo** - Company logo displayed in the report PDF. It can be configured by specifying a URL, or by uploading a file. The maximum file size is 16 MB. Defaults to the Grafana logo. +- **Company logo** - Company logo displayed in the report PDF. + Configure it by specifying a URL or uploading a file. + The maximum file size is 16 MB. + Defaults to the Grafana logo. -- **Theme** - Theme of the PDF attached to the report. Defaults to **Light**. The selected theme is also applied to the PDFs generated when you click **Preview PDF** during report creation or select the **Export as PDF** option on a dashboard. If **Current** is selected, the PDF in the report will be in the instance theme of the Admin, but the preview and exported PDFs will be in the user's instance theme. +- **Theme** - Theme of the PDF attached to the report. + The selected theme is also applied to the PDFs generated when you click **Preview PDF** during report creation or select the **Export as PDF** option on a dashboard. + + If **Current** is selected, the PDF in the report is in the instance theme of the report creator, but the preview and exported PDFs are in the user's instance theme. + Defaults to **Light**. ### Embedded Image -- **Theme** - Theme of the dashboard image embedded in the email. Defaults to **Dark**. +- **Theme** - Theme of the dashboard image embedded in the email. + If **Current** is selected, the image in the report is in the instance theme of the report creator. If the report creator doesn't have a theme set, then the team, organization, or server theme is used. For more information refer to [Change Grafana UI theme](ref:change-ui-theme). + Defaults to **Dark**. @@ -48,9 +53,10 @@ The options in this section control the branding and theming of the report attac -- **Company logo** - Company logo displayed in the report email. It can be configured by specifying a URL, or by uploading a file. The maximum file size is 16 MB. Defaults to the Grafana logo. +- **Company logo** - Company logo displayed in the report email. Configure it by specifying a URL or uploading a file. The maximum file size is 16 MB. Defaults to the Grafana logo. - **Email footer** - Toggle to enable the report email footer. Select **Sent by** or **None**. - **Footer link text** - Text of the link in the report email footer. Defaults to `Grafana`. - **Footer link URL** - Link of the report email footer. -Currently, the API does not allow for the simultaneous upload of files with identical names for both the email logo and report logo. You can still upload the same file for each logo separately in two distinct steps. +Currently, the API does not allow for the simultaneous upload of files with identical names for both the email logo and report logo. +You can still upload the same file for each logo separately in two distinct steps. diff --git a/docs/sources/dashboards/share-dashboards-panels/_index.md b/docs/sources/dashboards/share-dashboards-panels/_index.md index b9d84b58ab6..d424a4b75fb 100644 --- a/docs/sources/dashboards/share-dashboards-panels/_index.md +++ b/docs/sources/dashboards/share-dashboards-panels/_index.md @@ -44,9 +44,9 @@ refs: destination: /docs/grafana/grafana-cloud/visualizations/dashboards/share-dashboards-panels/shared-dashboards/ configure-report: - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/create-reports/#create-or-update-a-report + destination: /docs/grafana//dashboards/create-reports/#create-a-report - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/visualizations/dashboards/create-reports/#create-or-update-a-report + destination: /docs/grafana-cloud/visualizations/dashboards/create-reports/#create-a-report image-rendering-config: - pattern: /docs/grafana/ destination: /docs/grafana//setup-grafana/image-rendering/#configuration @@ -81,8 +81,6 @@ Grafana enables you to share dashboards and panels with other users within your - Reports - Library panels -You can also invite new members to your organization from the **Share** menu. For more information, refer to [Invite new members](#invite-new-members). - You must have an authorized viewer permission to see an image rendered by a direct link. The same permission is also required to view embedded links unless you have anonymous access permission enabled for your Grafana instance. {{< admonition type="note" >}} @@ -140,7 +138,7 @@ Learn how to configure and manage externally shared dashboards in [Externally sh ### Schedule a report {{< admonition type="note" >}} -This feature is only available in Grafana Enterprise. +This feature is only available on Grafana Enterprise. {{< /admonition >}} To share your dashboard as a report, follow these steps: @@ -204,6 +202,10 @@ In addition to sharing dashboards as links, reports, and snapshots, you can expo ### Export a dashboard as PDF +{{< admonition type="note" >}} +This feature is only available on Grafana Enterprise. +{{< /admonition >}} + To export a dashboard in its current state as a PDF, follow these steps: 1. Click **Dashboards** in the main menu. @@ -365,23 +367,3 @@ To delete existing snapshots, follow these steps: 1. Click the red **x** next to the snapshot URL that you want to delete. The snapshot is immediately deleted. You may need to clear your browser cache or use a private or incognito browser to confirm this. - -## Invite new members - -{{< admonition type="note" >}} -This feature is only available on Grafana Cloud. -{{< /admonition >}} - -You can invite new members to your organization using the **Share** drop-down menu. You must have the `OrgUsersAdd` permission to use this feature. - -To invite a new member to your organization, follow these steps: - -1. Click **Dashboards** in the main menu and open any dashboard. -1. Click the **Share** drop-down list in the top-right corner and select **Invite new member**. - - The **Members** page of your Grafana Cloud Portal opens. - -1. Enter the email address of the new member in the provided field. -1. Make a selection in the **Role** drop-down list. -1. (Optional) Select the **Receive billing emails** checkbox, if applicable. -1. Click **Invite**. diff --git a/docs/sources/dashboards/variables/add-template-variables/index.md b/docs/sources/dashboards/variables/add-template-variables/index.md index fa4e49ef5a4..54dc20e2d47 100644 --- a/docs/sources/dashboards/variables/add-template-variables/index.md +++ b/docs/sources/dashboards/variables/add-template-variables/index.md @@ -89,6 +89,8 @@ refs: # Add variables + + The following table lists the types of variables shipped with Grafana. | Variable type | Description | @@ -134,11 +136,13 @@ To create a variable, follow these steps: - [Interval](#add-an-interval-variable) - [Ad hoc filters](#add-ad-hoc-filters) + + ## Add a query variable Query variables enable you to write a data source query that can return a list of metric names, tag values, or keys. For example, a query variable might return a list of server names, sensor IDs, or data centers. The variable values change as they dynamically fetch options with a data source query. -Query variables are generally only supported for strings. If your query returns numbers or any other data type, you might need to convert them to strings in order to use them as variables. For the Azure data source, for example, you can use the [tostring](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tostringfunction) function for this purpose. +Query variables are generally only supported for strings. If your query returns numbers or any other data type, you might need to convert them to strings to use them as variables. For the Azure data source, for example, you can use the [`tostring`](https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tostringfunction) function for this purpose. Query expressions can contain references to other variables and in effect create linked variables. Grafana detects this and automatically refreshes a variable when one of its linked variables change. @@ -168,7 +172,7 @@ Query expressions are different for each data source. For more information, refe - Some data sources let you provide custom "display names" for the values. For instance, the PostgreSQL, MySQL, and Microsoft SQL Server plugins handle this by looking for fields named `__text` and `__value` in the result. Other data sources may look for `text` and `value` or use a different approach. Always remember to double-check the documentation for the data source. - If you need more room in a single input field query editor, then hover your cursor over the lines in the lower right corner of the field and drag downward to expand. -1. (Optional) In the **Regex** field, type a regex expression to filter or capture specific parts of the names returned by your data source query. To see examples, refer to [Filter variables with regex](#filter-variables-with-regex). +1. (Optional) In the **Regex** field, type a regular expression to filter or capture specific parts of the names returned by your data source query. To see examples, refer to [Filter variables with a regular expression](#filter-variables-with-regex). 1. In the **Sort** drop-down list, select the sort order for values to be displayed in the dropdown list. The default option, **Disabled**, means that the order of options returned by your data source query is used. 1. Under **Refresh**, select when the variable should update options: @@ -240,7 +244,7 @@ _Data source_ variables enable you to quickly change the data source for an enti 1. [Enter general options](#enter-general-options). 1. Under the **Data source options** section of the page, in the **Type** drop-down list, select the target data source for the variable. -1. (Optional) In **Instance name filter**, enter a regex filter for which data source instances to choose from in the variable value drop-down list. +1. (Optional) In **Instance name filter**, enter a regular expression filter for which data source instances to choose from in the variable value drop-down list. Leave this field empty to display all instances. @@ -289,6 +293,9 @@ The following example shows a more complex Graphite example, from the [Graphite groupByNode(summarize(movingAverage(apps.$app.$server.counters.requests.count, 5), '$interval', 'sum', false), 2, 'sum') ``` + + + ## Add ad hoc filters _Ad hoc filters_ are one of the most complex and flexible variable options available. @@ -298,10 +305,10 @@ Ad hoc filters let you add label/value filters that are automatically added to a Unlike other variables, you don't use ad hoc filters in queries. Instead, you use ad hoc filters to write filters for existing queries. -{{% admonition type="note" %}} +{{< admonition type="note" >}} Not all data sources support ad hoc filters. Examples of those that do include Prometheus, Loki, InfluxDB, and Elasticsearch. -{{% /admonition %}} +{{< /admonition >}} To create an ad hoc filter, follow these steps: @@ -318,6 +325,9 @@ To create an ad hoc filter, follow these steps: Now you can [filter data on the dashboard](ref:filter-dashboard). + + + ## Configure variable selection options **Selection Options** are a feature you can use to manage variable option selections. All selection options are optional, and they are off by default. @@ -326,9 +336,9 @@ Now you can [filter data on the dashboard](ref:filter-dashboard). Interpolating a variable with multiple values selected is tricky as it is not straight forward how to format the multiple values into a string that is valid in the given context where the variable is used. Grafana tries to solve this by allowing each data source plugin to inform the templating interpolation engine what format to use for multiple values. -{{% admonition type="note" %}} +{{< admonition type="note" >}} The **Custom all value** option on the variable must be blank for Grafana to format all values into a single string. If it is left blank, then Grafana concatenates (adds together) all the values in the query. Something like `value1,value2,value3`. If a custom `all` value is used, then instead the value is something like `*` or `all`. -{{% /admonition %}} +{{< /admonition >}} #### Multi-value variables with a Graphite data source @@ -336,17 +346,17 @@ Graphite uses glob expressions. A variable with multiple values would, in this c #### Multi-value variables with a Prometheus or InfluxDB data source -InfluxDB and Prometheus use regex expressions, so the same variable would be interpolated as `(host1|host2|host3)`. Every value would also be regex escaped. If not, a value with a regex control character would break the regex expression. +InfluxDB and Prometheus use regular expressions, so the same variable would be interpolated as `(host1|host2|host3)`. Every value would also be regular expression escaped. If not, a value with a regular expression control character would break the regular expression. #### Multi-value variables with an Elastic data source -Elasticsearch uses lucene query syntax, so the same variable would be formatted as `("host1" OR "host2" OR "host3")`. In this case, every value must be escaped so that the value only contains lucene control words and quotation marks. +Elasticsearch uses Lucene query syntax, so the same variable would be formatted as `("host1" OR "host2" OR "host3")`. In this case, every value must be escaped so that the value only contains Lucene control words and quotation marks. #### Troubleshoot multi-value variables -Automatic escaping and formatting can cause problems and it can be tricky to grasp the logic behind it. Especially for InfluxDB and Prometheus where the use of regex syntax requires that the variable is used in regex operator context. +Automatic escaping and formatting can cause problems and it can be tricky to grasp the logic behind it. Especially for InfluxDB and Prometheus where the use of regular expression syntax requires that the variable is used in regular expression operator context. -If you do not want Grafana to do this automatic regex escaping and formatting, then you must do one of the following: +If you do not want Grafana to do this automatic regular expression escaping and formatting, then you must do one of the following: - Turn off the **Multi-value** or **Include All option** options. - Use the [raw variable format](ref:raw-variable-format). @@ -359,28 +369,28 @@ Grafana adds an `All` option to the variable dropdown list. If a user selects th This option is only visible if the **Include All option** is selected. -Enter regex, globs, or lucene syntax in the **Custom all value** field to define the value of the `All` option. +Enter regular expressions, globs, or Lucene syntax in the **Custom all value** field to define the value of the `All` option. -By default the `All` value includes all options in combined expression. This can become very long and can have performance problems. Sometimes it can be better to specify a custom all value, like a wildcard regex. +By default the `All` value includes all options in combined expression. This can become very long and can have performance problems. Sometimes it can be better to specify a custom all value, like a wildcard regular expression. -In order to have custom regex, globs, or lucene syntax in the **Custom all value** option, it is never escaped so you have to think about what is a valid value for your data source. +In order to have custom regular expression, globs, or Lucene syntax in the **Custom all value** option, it is never escaped so you have to think about what is a valid value for your data source. ## Global variables Grafana has global built-in variables that can be used in expressions in the query editor. This topic lists them in alphabetical order and defines them. These variables are useful in queries, dashboard links, panel links, and data links. -### $\_\_dashboard +### `$__dashboard` This variable is the name of the current dashboard. -### $\_\_from and $\_\_to +### `$__from` and `$__to` Grafana has two built-in time range variables: `$__from` and `$__to`. They are currently always interpolated as epoch milliseconds by default, but you can control date formatting. | Syntax | Example result | Description | | ------------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `${__from}` | 1594671549254 | Unix millisecond epoch | -| `${__from:date}` | 2020-07-13T20:19:09.254Z | No args, defaults to ISO 8601/RFC 3339 | +| `${__from:date}` | 2020-07-13T20:19:09.254Z | No arguments, defaults to ISO 8601/RFC 3339 | | `${__from:date:iso}` | 2020-07-13T20:19:09.254Z | ISO 8601/RFC 3339 | | `${__from:date:seconds}` | 1594671549 | Unix seconds epoch | | `${__from:date:YYYY-MM}` | 2020-07 | Any custom [date format](https://momentjs.com/docs/#/displaying/) that does not include the `:` character. Uses browser time. Use `:date` or `:date:iso` for UTC | @@ -389,7 +399,7 @@ The syntax above also works with `${__to}`. You can use this variable in URLs, as well. For example, you can send a user to a dashboard that shows a time range from six hours ago until now: https://play.grafana.org/d/000000012/grafana-play-home?viewPanel=2&orgId=1?from=now-6h&to=now -### $\_\_interval +### `$__interval` You can use the `$__interval` variable as a parameter to group by time (for InfluxDB, MySQL, Postgres, MSSQL), Date histogram interval (for Elasticsearch), or as a _summarize_ function parameter (for Graphite). @@ -403,42 +413,42 @@ In the InfluxDB data source, the legacy variable `$interval` is the same variabl The InfluxDB and Elasticsearch data sources have `Group by time interval` fields that are used to hard code the interval or to set the minimum limit for the `$__interval` variable (by using the `>` syntax -> `>10m`). -### $\_\_interval_ms +### `$__interval_ms` This variable is the `$__interval` variable in milliseconds, not a time interval formatted string. For example, if the `$__interval` is `20m` then the `$__interval_ms` is `1200000`. -### $\_\_name +### `$__name` -This variable is only available in the Singlestat panel and can be used in the prefix or suffix fields on the Options tab. The variable is replaced with the series name or alias. +This variable is only available in the **Singlestat** panel and can be used in the prefix or suffix fields on the Options tab. The variable is replaced with the series name or alias. -{{% admonition type="note" %}} -The Singlestat panel is no longer available from Grafana 8.0. -{{% /admonition %}} +{{< admonition type="note" >}} +The **Singlestat** panel is no longer available from Grafana 8.0. +{{< /admonition >}} -### $\_\_org +### `$__org` This variable is the ID of the current organization. `${__org.name}` is the name of the current organization. -### $\_\_user +### `$__user` `${__user.id}` is the ID of the current user. `${__user.login}` is the login handle of the current user. `${__user.email}` is the email for the current user. -### $\_\_range +### `$__range` Currently only supported for Prometheus and Loki data sources. This variable represents the range for the current dashboard. It is calculated by `to - from`. It has a millisecond and a second representation called `$__range_ms` and `$__range_s`. -### $\_\_rate_interval +### `$__rate_interval` Currently only supported for Prometheus data sources. The `$__rate_interval` variable is meant to be used in the rate function. Refer to [Prometheus query variables](ref:prometheus-query-variables) for details. -### $\_\_rate_interval_ms +### `$__rate_interval_ms` This variable is the `$__rate_interval` variable in milliseconds, not a time-interval-formatted string. For example, if the `$__rate_interval` is `20m` then the `$__rate_interval_ms` is `1200000`. -### $timeFilter or $\_\_timeFilter +### `$timeFilter` or `$__timeFilter` The `$timeFilter` variable returns the currently selected time range as an expression. For example, the time range interval `Last 7 days` expression is `time > now() - 7d`. @@ -449,7 +459,7 @@ This is used in several places, including: - SQL queries in MySQL, Postgres, and MSSQL. - The `$__timeFilter` variable is used in the MySQL data source. -### $\_\_timezone +### `$__timezone` The `$__timezone` variable returns the currently selected time zone, either `utc` or an entry of the IANA time zone database (for example, `America/New_York`). @@ -485,9 +495,9 @@ In this example, there are several applications. Each application has a differen Now, you could make separate variables for each metric source, but then you have to know which server goes with which app. A better solution is to use one variable to filter another. In this example, when the user changes the value of the `app` variable, it changes the dropdown options returned by the `server` variable. Both variables use the **Multi-value** option and **Include all option**, enabling users to select some or all options presented at any time. -##### app variable +##### `app` variable -The query for this variable basically says, "Give me all the applications that exist." +The query for this variable basically says, "Find all the applications that exist." ``` apps.* @@ -495,9 +505,9 @@ apps.* The values returned are `backend`, `country`, `fakesite`, and `All`. -##### server variable +##### `server` variable -The query for this variable basically says, "Give me all servers for the currently chosen application." +The query for this variable basically says, "Find all servers for the currently chosen application." ``` apps.$app.* @@ -521,9 +531,9 @@ The query returns all servers associated with `fakesite`, including `web_server_ ##### More variables -{{% admonition type="note" %}} +{{< admonition type="note" >}} This example is theoretical. The Graphite server used in the example does not contain CPU metrics. -{{% /admonition %}} +{{< /admonition >}} The dashboard stops at two levels, but you could keep going. For example, if you wanted to get CPU metrics for selected servers, you could copy the `server` variable and extend the query so that it reads: @@ -531,7 +541,7 @@ The dashboard stops at two levels, but you could keep going. For example, if you apps.$app.$server.cpu.* ``` -This query basically says, "Show me the CPU metrics for the selected server." +This query basically says, "Find the CPU metrics for the selected server." Depending on what variable options the user selects, you could get queries like: @@ -547,9 +557,9 @@ In this example, you have several data centers. Each data center has a different In this example, when the user changes the value of the `datacenter` variable, it changes the dropdown options returned by the `host` variable. The `host` variable uses the **Multi-value** option and **Include all option**, allowing users to select some or all options presented at any time. The `datacenter` does not use either option, so you can only select one data center at a time. -##### datacenter variable +##### `datacenter` variable -The query for this variable basically says, "Give me all the data centers that exist." +The query for this variable basically says, "Find all the data centers that exist." ``` SHOW TAG VALUES WITH KEY = "datacenter" @@ -557,9 +567,9 @@ SHOW TAG VALUES WITH KEY = "datacenter" The values returned are `America`, `Africa`, `Asia`, and `Europe`. -##### host variable +##### `host` variable -The query for this variable basically says, "Give me all hosts for the currently chosen data center." +The query for this variable basically says, "Find all hosts for the currently chosen data center." ``` SHOW TAG VALUES WITH KEY = "hostname" WHERE "datacenter" =~ /^$datacenter$/ @@ -583,9 +593,9 @@ The query returns all servers associated with `Europe`, including `server3`, `se ##### More variables -{{% admonition type="note" %}} +{{< admonition type="note" >}} This example is theoretical. The InfluxDB server used in the example does not contain CPU metrics. -{{% /admonition %}} +{{< /admonition >}} The dashboard stops at two levels, but you could keep going. For example, if you wanted to get CPU metrics for selected hosts, you could copy the `host` variable and extend the query so that it reads: @@ -593,7 +603,7 @@ The dashboard stops at two levels, but you could keep going. For example, if you SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^$datacenter$/ AND "host" =~ /^$host$/ ``` -This query basically says, "Show me the CPU metrics for the selected host." +This query basically says, "Find the CPU metrics for the selected host." Depending on what variable options the user selects, you could get queries like: @@ -607,7 +617,7 @@ SHOW TAG VALUES WITH KEY = "cpu" WHERE "datacenter" =~ /^Europe/ AND "host" =~ / The following practices make your dashboards and variables easier to use. -#### Creating new linked variables +#### New linked variables creation - Chaining variables create parent/child dependencies. You can envision them as a ladder or a tree. - The easiest way to create a new chained variable is to copy the variable that you want to base the new one on. In the variable list, click the **Duplicate variable** icon to the right of the variable entry to create a copy. You can then add on to the query for the parent variable. @@ -627,13 +637,17 @@ The more layers of dependency you have in variables, the longer it takes to upda For example, if you have a series of four linked variables (country, region, server, metric) and you change a root variable value (country), then Grafana must run queries for all the dependent variables before it updates the visualizations in the dashboard. -## Filter variables with regex + -Using the Regex Query option, you filter the list of options returned by the variable query or modify the options returned. +## Filter variables with regular expressions {#filter-variables-with-regex} -This page shows how to use regex to filter/modify values in the variable dropdown. + -Using the Regex Query Option, you filter the list of options returned by the Variable query or modify the options returned. For more information, refer to the Mozilla guide on [Regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). +Using the **Regex** query option, you filter the list of options returned by the variable query or modify the options returned. + +This page shows how to use a regular expression to filter/modify values in the variable dropdown. + +Using the **Regex** query option, you filter the list of options returned by the Variable query or modify the options returned. For more information, refer to the Mozilla guide on [Regular expressions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions). Examples of filtering on the following list of options: @@ -646,7 +660,7 @@ backend_04 ### Filter so that only the options that end with `01` or `02` are returned: -Regex: +**Regex**: ```regex /(01|02)$/ @@ -659,9 +673,9 @@ backend_01 backend_02 ``` -### Filter and modify the options using a regex capture group to return part of the text: +### Filter and modify the options using a regular expression to capture group to return part of the text: -Regex: +**Regex**: ```regex /.*(01|02)/ @@ -684,7 +698,7 @@ up{instance="demo.robustperception.io:9093",job="alertmanager"} 1 1521630638000 up{instance="demo.robustperception.io:9100",job="node"} 1 1521630638000 ``` -Regex: +**Regex**: ```regex /.*instance="([^"]*).*/ @@ -711,7 +725,7 @@ node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_2",chip_name="enp216s0f0np2" node_hwmon_chip_names{chip="0000:d7:00_0_0000:d8:00_3",chip_name="enp216s0f0np3"} 1 ``` -Passed through the following Regex: +Passed through the following regular expression: ```regex /chip_name="(?[^"]+)|chip="(?[^"]+)/g diff --git a/docs/sources/datasources/_index.md b/docs/sources/datasources/_index.md index 89fe11e36e5..5543b37434a 100644 --- a/docs/sources/datasources/_index.md +++ b/docs/sources/datasources/_index.md @@ -117,7 +117,7 @@ Grafana includes three special data sources: ### Grafana -A built-in data source that generates random walk data and can poll the [Testdata]({{< relref "./testdata/" >}}) data source. Additionally, it can list files and get other data from a Grafana installation. This can be helpful for testing visualizations and running experiments. +A built-in data source that generates random walk data and can poll the [Testdata](testdata/) data source. Additionally, it can list files and get other data from a Grafana installation. This can be helpful for testing visualizations and running experiments. ### Mixed @@ -140,24 +140,24 @@ These built-in core data sources are also included in the Grafana documentation: {{< column-list >}} -- [Alertmanager]({{< relref "./alertmanager" >}}) -- [AWS CloudWatch]({{< relref "./aws-cloudwatch" >}}) -- [Azure Monitor]({{< relref "./azure-monitor" >}}) -- [Elasticsearch]({{< relref "./elasticsearch" >}}) -- [Google Cloud Monitoring]({{< relref "./google-cloud-monitoring" >}}) -- [Graphite]({{< relref "./graphite" >}}) -- [InfluxDB]({{< relref "./influxdb" >}}) -- [Jaeger]({{< relref "./jaeger" >}}) -- [Loki]({{< relref "./loki" >}}) -- [Microsoft SQL Server (MSSQL)]({{< relref "./mssql" >}}) -- [MySQL]({{< relref "./mysql" >}}) -- [OpenTSDB]({{< relref "./opentsdb" >}}) -- [PostgreSQL]({{< relref "./postgres" >}}) -- [Prometheus]({{< relref "./prometheus" >}}) -- [Pyroscope]({{< relref "./pyroscope" >}}) -- [Tempo]({{< relref "./tempo" >}}) -- [Testdata]({{< relref "./testdata" >}}) -- [Zipkin]({{< relref "./zipkin" >}}) +- [Alertmanager](alertmanager/) +- [AWS CloudWatch](aws-cloudwatch/) +- [Azure Monitor](azure-monitor/) +- [Elasticsearch](elasticsearch/) +- [Google Cloud Monitoring](google-cloud-monitoring/) +- [Graphite](graphite/) +- [InfluxDB](influxdb/) +- [Jaeger](jaeger/) +- [Loki](loki/) +- [Microsoft SQL Server (MSSQL)](mssql/) +- [MySQL](mysql/) +- [OpenTSDB](opentsdb/) +- [PostgreSQL](postgres/) +- [Prometheus](prometheus/) +- [Pyroscope](pyroscope/) +- [Tempo](tempo/) +- [Testdata](testdata/) +- [Zipkin](zipkin/) {{< /column-list >}} diff --git a/docs/sources/datasources/aws-cloudwatch/_index.md b/docs/sources/datasources/aws-cloudwatch/_index.md index 6e5d3a0618e..82aff4fb4ee 100644 --- a/docs/sources/datasources/aws-cloudwatch/_index.md +++ b/docs/sources/datasources/aws-cloudwatch/_index.md @@ -66,7 +66,7 @@ For instructions on how to add a data source to Grafana, refer to the [administr Only users with the organization administrator role can add data sources. Administrators can also [provision the data source](#provision-the-data-source) with Grafana's provisioning system, and should [control pricing](#control-pricing) and [manage service quotas](#manage-service-quotas) accordingly. -Once you've added the data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +Once you've added the data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). {{% admonition type="note" %}} To troubleshoot issues while setting up the CloudWatch data source, check the `/var/log/grafana/grafana.log` file. @@ -86,12 +86,12 @@ To troubleshoot issues while setting up the CloudWatch data source, check the `/ A Grafana plugin's requests to AWS are made on behalf of an AWS Identity and Access Management (IAM) role or IAM user. The IAM user or IAM role must have the associated policies to perform certain API actions. -For authentication options and configuration details, refer to [AWS authentication]({{< relref "./aws-authentication" >}}). +For authentication options and configuration details, refer to [AWS authentication](aws-authentication/). #### IAM policy examples To read CloudWatch metrics and EC2 tags, instances, regions, and alarms, you must grant Grafana permissions via IAM. -You can attach these permissions to the IAM role or IAM user you configured in [AWS authentication]({{< relref "./aws-authentication" >}}). +You can attach these permissions to the IAM role or IAM user you configured in [AWS authentication](aws-authentication/). ##### Metrics-only permissions @@ -354,7 +354,11 @@ datasources: The CloudWatch data source can query data from both CloudWatch metrics and CloudWatch Logs APIs, each with its own specialized query editor. -For details, see the [query editor documentation]({{< relref "./query-editor" >}}). +For details, see the [query editor documentation](query-editor/). + +## Query caching + +When you enable [query and resource caching](/docs/grafana//administration/data-source-management/#query-and-resource-caching), Grafana temporarily stores the results of data source queries and resource requests. Query caching is available in CloudWatch Metrics in Grafana Cloud and Grafana Enterprise. It is not available in CloudWatch Logs Insights due to how query results are polled from AWS. ## Use template variables @@ -362,7 +366,7 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). ## Import pre-configured dashboards @@ -438,7 +442,7 @@ For more information, refer to the AWS documentation for [Service Quotas](https: The CloudWatch plugin enables you to monitor and troubleshoot applications across multiple regional accounts. Using cross-account observability, you can seamlessly search, visualize and analyze metrics and logs without worrying about account boundaries. -To use this feature, configure in the [AWS console under Cloudwatch Settings](https://aws.amazon.com/blogs/aws/new-amazon-cloudwatch-cross-account-observability/), a monitoring and source account, and then add the necessary IAM permissions as described above. +To use this feature, configure in the [AWS console under CloudWatch Settings](https://aws.amazon.com/blogs/aws/new-amazon-cloudwatch-cross-account-observability/), a monitoring and source account, and then add the necessary IAM permissions as described above. ## CloudWatch Logs data protection diff --git a/docs/sources/datasources/aws-cloudwatch/aws-authentication/index.md b/docs/sources/datasources/aws-cloudwatch/aws-authentication/index.md index 58c02f1ccb0..9ae64f44856 100644 --- a/docs/sources/datasources/aws-cloudwatch/aws-authentication/index.md +++ b/docs/sources/datasources/aws-cloudwatch/aws-authentication/index.md @@ -79,7 +79,7 @@ For example, you may have one set of long term credentials for all of your AWS d Instead, using the assume role functionality, you could have one set of AWS credentials for all of your AWS data sources that has only one permission—the permission to assume a role with STS. Then you could create a separate IAM role for each data source that specifies which permissions that data source can temporarily assume. Since IAM roles are not credentials, there's no need to rotate them and they may be easier to manage. -The Grafana Assume Role also helps facilitate this. Using this role, Grafana's AWS account acts as the primary credential, having only the permission to assume roles in other accounts. You can then create IAM roles for Grafana's account to assume. For more information, refer to [Use Grafana assume role]({{< relref "#use-grafana-assume-role" >}}). +The Grafana Assume Role also helps facilitate this. Using this role, Grafana's AWS account acts as the primary credential, having only the permission to assume roles in other accounts. You can then create IAM roles for Grafana's account to assume. For more information, refer to [Use Grafana assume role](#use-grafana-assume-role). If the **Assume Role ARN** field is left empty, Grafana uses the provided credentials from the selected authentication method directly, and permissions to AWS data must be attached directly to those credentials. The **Assume Role ARN** field is optional for all authentication methods except for Grafana Assume Role. @@ -160,7 +160,7 @@ securityContext: ## Use Grafana Assume Role {{% admonition type="note" %}} -Grafana Assume Role is currently in [private preview]({{< relref "https://grafana.com/docs/release-life-cycle" >}}) for Grafana Cloud. +Grafana Assume Role is currently in [private preview](https://grafana.com/docs/release-life-cycle/) for Grafana Cloud. It's currently only available for Amazon CloudWatch. diff --git a/docs/sources/datasources/aws-cloudwatch/query-editor/index.md b/docs/sources/datasources/aws-cloudwatch/query-editor/index.md index b65bd308e77..f7cbce5a547 100644 --- a/docs/sources/datasources/aws-cloudwatch/query-editor/index.md +++ b/docs/sources/datasources/aws-cloudwatch/query-editor/index.md @@ -67,7 +67,7 @@ If you enable `Match Exact`, you must also specify all dimensions of the metric If `Match Exact` is disabled, you can specify any number of dimensions on which you'd like to filter. With `Match Exact` disabled the query returns any metrics that match the namespace, metric name, and all defined dimensions, whether or not they have additional dimensions. The data source returns up to 100 metrics matching your filter criteria. -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). #### Create dynamic queries with dimension wildcards @@ -157,7 +157,7 @@ For details about the Metrics Insights syntax, refer to the [AWS reference docum For information about Metrics Insights limits, refer to the [AWS feature documentation](https://docs.aws.amazon.com/console/cloudwatch/metricsinsights). -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). #### Use Metrics Insights keywords @@ -226,7 +226,7 @@ The label field allows you to override the default name of the metric legend usi ## Query CloudWatch Logs The logs query editor helps you write CloudWatch Logs Query Language queries across defined regions and log groups. -It supports querying Cloudwatch logs with Logs Insights Query Language, OpenSearch PPL and OpenSearch SQL. +It supports querying CloudWatch logs with Logs Insights Query Language, OpenSearch PPL and OpenSearch SQL. ### Create a CloudWatch Logs query @@ -237,7 +237,7 @@ It supports querying Cloudwatch logs with Logs Insights Query Language, OpenSear Region and log groups are mandatory fields when querying with Logs Insights QL and OpenSearch PPL. Log group selection is not necessary when querying with OpenSearch SQL. However, selecting log groups simplifies writing logs queries by populating syntax suggestions with discovered log group fields. {{< /admonition >}} -1. Use the main input area to write your logs query. AWS Cloudwatch only supports a subset of OpenSearch SQL and PPL commands. To find out more about the syntax supported, consult [Amazon CloudWatch Logs documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_Languages.html) +1. Use the main input area to write your logs query. AWS CloudWatch only supports a subset of OpenSearch SQL and PPL commands. To find out more about the syntax supported, consult [Amazon CloudWatch Logs documentation](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/CWL_AnalyzeLogData_Languages.html) #### Querying Log groups with OpenSearch SQL @@ -270,7 +270,7 @@ To enable cross-account observability, complete the following steps: 1. Go to the [Amazon CloudWatch docs](http://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch-Unified-Cross-Account.html) and follow the instructions on enabling cross-account observability. -1. Add [two API actions]({{< relref "../../aws-cloudwatch#cross-account-observability-permissions" >}}) to the IAM policy attached to the role/user running the plugin. +1. Add [two API actions](../#cross-account-observability-permissions) to the IAM policy attached to the role/user running the plugin. Cross-account querying is available in the plugin through the **Logs**, **Metric search**, and **Metric Insights** modes. After you have it configured, you'll see a **Monitoring account** badge in the query editor header. diff --git a/docs/sources/datasources/azure-monitor/_index.md b/docs/sources/datasources/azure-monitor/_index.md index cdc50ba8993..7814af16326 100644 --- a/docs/sources/datasources/azure-monitor/_index.md +++ b/docs/sources/datasources/azure-monitor/_index.md @@ -74,7 +74,7 @@ This topic explains configuring and querying specific to the Azure Monitor data For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:data-source-management). Only users with the organization administrator role can add data sources. -Once you've added the Azure Monitor data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +Once you've added the Azure Monitor data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). The Azure Monitor data source supports visualizing data from four Azure services: @@ -338,7 +338,7 @@ If a user tries to create an alert for a resource that the fallback credentials The Azure Monitor data source can query data from Azure Monitor Metrics and Logs, the Azure Resource Graph, and Application Insights Traces. Each source has its own specialized query editor. -For details, see the [query editor documentation]({{< relref "./query-editor" >}}). +For details, see the [query editor documentation](query-editor/). ## Use template variables @@ -346,7 +346,7 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). ## Application Insights and Insights Analytics (removed) diff --git a/docs/sources/datasources/azure-monitor/query-editor/index.md b/docs/sources/datasources/azure-monitor/query-editor/index.md index 28256b66000..662685ce7db 100644 --- a/docs/sources/datasources/azure-monitor/query-editor/index.md +++ b/docs/sources/datasources/azure-monitor/query-editor/index.md @@ -85,7 +85,7 @@ Optionally, you can apply further aggregations or filter by dimensions. The available options change depending on what is relevant to the selected metric. -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). ### Format legend aliases @@ -146,7 +146,7 @@ The Azure Monitor data source also supports querying of [Basic Logs](https://lea 1. Enter your KQL query. -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). **To create a Basic Logs query:** @@ -364,7 +364,7 @@ Selecting the trace format will filter events with the `trace` type. 1. Specify event types to filter by. 1. Specify event properties to filter by. -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). ## Working with large Azure resource data sets diff --git a/docs/sources/datasources/azure-monitor/template-variables/index.md b/docs/sources/datasources/azure-monitor/template-variables/index.md index 5eb2d9f983c..1db472a4251 100644 --- a/docs/sources/datasources/azure-monitor/template-variables/index.md +++ b/docs/sources/datasources/azure-monitor/template-variables/index.md @@ -48,19 +48,24 @@ For an introduction to templating and template variables, refer to the [Templati You can specify these Azure Monitor data source queries in the Variable edit view's **Query Type** field. -| Name | Description | -| ------------------- | ------------------------------------------------------------------------------------------------------------------ | -| **Subscriptions** | Returns subscriptions. | -| **Resource Groups** | Returns resource groups for a specified. Supports multi-value. subscription. | -| **Namespaces** | Returns metric namespaces for the specified subscription and resource group. | -| **Regions** | Returns regions for the specified subscription | -| **Resource Names** | Returns a list of resource names for a specified subscription, resource group and namespace. Supports multi-value. | -| **Metric Names** | Returns a list of metric names for a resource. | -| **Workspaces** | Returns a list of workspaces for the specified subscription. | -| **Logs** | Use a KQL query to return values. | -| **Resource Graph** | Use an ARG query to return values. | +| Name | Description | +| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- | +| **Subscriptions** | Returns subscriptions. | +| **Resource Groups** | Returns resource groups for a specified subscription. Supports multi-value. | +| **Namespaces** | Returns metric namespaces for the specified subscription. If a resource group is provided, only the namespaces within that group are returned. | +| **Regions** | Returns regions for the specified subscription | +| **Resource Names** | Returns a list of resource names for a specified subscription, resource group and namespace. Supports multi-value. | +| **Metric Names** | Returns a list of metric names for a resource. | +| **Workspaces** | Returns a list of workspaces for the specified subscription. | +| **Logs** | Use a KQL query to return values. | +| **Custom Namespaces** | Returns metric namespaces for the specified resource. | +| **Custom Metric Names** | Returns a list of custom metric names for the specified resource. | -Any Log Analytics Kusto Query Language (KQL) query that returns a single list of values can also be used in the Query field. +{{< admonition type="note" >}} +Custom metrics cannot be emitted against a subscription or resource group. Select resources only when you need to retrieve custom metric namespaces or custom metric names associated with a specific resource. +{{< /admonition >}} + +You can use any Log Analytics Kusto Query Language (KQL) query that returns a single list of values in the `Query` field. For example: | Query | List of values returned | diff --git a/docs/sources/datasources/elasticsearch/_index.md b/docs/sources/datasources/elasticsearch/_index.md index 69dcf9bf69a..e0bfbe560e7 100644 --- a/docs/sources/datasources/elasticsearch/_index.md +++ b/docs/sources/datasources/elasticsearch/_index.md @@ -48,8 +48,8 @@ The following will help you get started working with Elasticsearch and Grafana: - [What is Elasticsearch?](https://www.elastic.co/guide/en/elasticsearch/reference/current/elasticsearch-intro.html) - [Configure the Elasticsearch data source](/docs/grafana/latest/datasources/elasticsearch/configure-elasticsearch-data-source/) -- [Elasticsearch query editor]({{< relref "./query-editor" >}}) -- [Elasticsearch template variables]({{< relref "./template-variables" >}}) +- [Elasticsearch query editor](query-editor/) +- [Elasticsearch template variables](template-variables/) ## Supported Elasticsearch versions @@ -124,7 +124,7 @@ For details on AWS SigV4, refer to the [AWS documentation](https://docs.aws.amaz To sign requests to your Amazon Elasticsearch Service domain, you can enable SigV4 in Grafana's [configuration](ref:configuration). Once AWS SigV4 is enabled, you can configure it on the Elasticsearch data source configuration page. -For more information about AWS authentication options, refer to [AWS authentication]({{< relref "../aws-cloudwatch/aws-authentication" >}}). +For more information about AWS authentication options, refer to [AWS authentication](../aws-cloudwatch/aws-authentication/). {{< figure src="/static/img/docs/v73/elasticsearch-sigv4-config-editor.png" max-width="500px" class="docs-image--no-shadow" caption="SigV4 configuration for AWS Elasticsearch Service" >}} @@ -132,7 +132,7 @@ For more information about AWS authentication options, refer to [AWS authenticat You can select multiple metrics and group by multiple terms or filters when using the Elasticsearch query editor. -For details, see the [query editor documentation]({{< relref "./query-editor" >}}). +For details, see the [query editor documentation](query-editor/). ## Use template variables @@ -140,4 +140,4 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). diff --git a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md b/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md index 9741f03d072..eacc91861df 100644 --- a/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md +++ b/docs/sources/datasources/elasticsearch/configure-elasticsearch-data-source.md @@ -160,7 +160,7 @@ For example, set this to `1m` if Elasticsearch writes data every minute. You can also override this setting in a dashboard panel under its data source options. The default is `10s`. -- **X-Pack enabled** - Toggle to enable `X-Pack`-specific features and options, which provide the [query editor]({{< relref "./query-editor" >}}) with additional aggregations, such as `Rate` and `Top Metrics`. +- **X-Pack enabled** - Toggle to enable `X-Pack`-specific features and options, which provide the [query editor](../query-editor/) with additional aggregations, such as `Rate` and `Top Metrics`. - **Include frozen indices** - Toggle on when the `X-Pack enabled` setting is active. Includes frozen indices in searches. You can configure Grafana to include [frozen indices](https://www.elastic.co/guide/en/elasticsearch/reference/7.13/frozen-indices.html) when performing search requests. diff --git a/docs/sources/datasources/elasticsearch/query-editor/index.md b/docs/sources/datasources/elasticsearch/query-editor/index.md index e6ed22b542f..0e7b37d4708 100644 --- a/docs/sources/datasources/elasticsearch/query-editor/index.md +++ b/docs/sources/datasources/elasticsearch/query-editor/index.md @@ -143,7 +143,7 @@ The option to run a **raw document query** is deprecated as of Grafana v10.1. ## Use template variables -You can also augment queries by using [template variables]({{< relref "./template-variables/" >}}). +You can also augment queries by using [template variables](../template-variables/). Queries of `terms` have a 500-result limit by default. To set a custom limit, set the `size` property in your query. diff --git a/docs/sources/datasources/google-cloud-monitoring/_index.md b/docs/sources/datasources/google-cloud-monitoring/_index.md index efa07545e60..94dfe06d7a3 100644 --- a/docs/sources/datasources/google-cloud-monitoring/_index.md +++ b/docs/sources/datasources/google-cloud-monitoring/_index.md @@ -53,7 +53,7 @@ This topic describes queries, templates, variables, and other configuration spec For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:data-source-management). Only users with the organization administrator role can add data sources. -Once you've added the Google Cloud Monitoring data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) and apply [annotations](#annotations) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +Once you've added the Google Cloud Monitoring data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) and apply [annotations](#annotations) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). ## Configure the data source @@ -78,19 +78,19 @@ To configure basic settings for the data source, complete the following steps: Before you can request data from Google Cloud Monitoring, you must configure authentication. All requests to Google APIs are performed on the server-side by the Grafana backend. -For authentication options and configuration details, refer to [Google authentication]({{< relref "./google-authentication" >}}). +For authentication options and configuration details, refer to [Google authentication](google-authentication/). When configuring Google authentication, note these additional Google Cloud Monitoring-specific steps: #### Configure a GCP Service Account -When you [create a Google Cloud Platform (GCP) Service Account and key file]({{< relref "./google-authentication#create-a-gcp-service-account-and-key-file" >}}), the Service Account must have the **Monitoring Viewer** role (**Role > Select a role > Monitoring > Monitoring Viewer**): +When you [create a Google Cloud Platform (GCP) Service Account and key file](google-authentication/#create-a-gcp-service-account-and-key-file), the Service Account must have the **Monitoring Viewer** role (**Role > Select a role > Monitoring > Monitoring Viewer**): {{< figure src="/static/img/docs/v71/cloudmonitoring_service_account_choose_role.png" max-width="600px" class="docs-image--no-shadow" caption="Choose role" >}} #### Grant the GCE Default Service Account scope -If Grafana is running on a Google Compute Engine (GCE) virtual machine, then when you [Configure a GCE Default Service Account]({{< relref "./google-authentication#configure-a-gce-default-service-account" >}}), you must also grant that Service Account access to the "Cloud Monitoring API" scope. +If Grafana is running on a Google Compute Engine (GCE) virtual machine, then when you [Configure a GCE Default Service Account](google-authentication/#configure-a-gce-default-service-account), you must also grant that Service Account access to the "Cloud Monitoring API" scope. ### Enable necessary Google Cloud Platform APIs @@ -181,7 +181,7 @@ These curated dashboards are based on similar dashboards in the GCP dashboard sa 1. Select **Import** for the dashboard to import. -The dashboards include a [template variable]({{< relref "./template-variables" >}}) populated with the projects accessible by the configured [Service Account]({{< relref "./google-authentication" >}}) each time you load the dashboard. +The dashboards include a [template variable](template-variables/) populated with the projects accessible by the configured [Service Account](google-authentication/) each time you load the dashboard. After Grafana loads the dashboard, you can select a project from the dropdown list. **To customize an imported dashboard:** @@ -193,7 +193,7 @@ If you don't, upgrading Grafana can overwrite the customized dashboard with the The Google Cloud Monitoring query editor helps you build two types of queries: **Metric** and **Service Level Objective (SLO)**. -For details, refer to the [query editor documentation]({{< relref "./query-editor" >}}). +For details, refer to the [query editor documentation](query-editor/). ## Use template variables @@ -201,4 +201,4 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). diff --git a/docs/sources/datasources/graphite/_index.md b/docs/sources/datasources/graphite/_index.md index 7628935ae02..993f40b127d 100644 --- a/docs/sources/datasources/graphite/_index.md +++ b/docs/sources/datasources/graphite/_index.md @@ -56,7 +56,7 @@ This topic explains options, variables, querying, and other features specific to For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:data-source-management). Only users with the organization administrator role can add data sources. -Once you've added the Graphite data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +Once you've added the Graphite data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). {{< docs/play title="Graphite: Sample Website Dashboard" url="https://play.grafana.org/d/000000003/" >}} @@ -124,7 +124,7 @@ Grafana includes a Graphite-specific query editor to help you build queries. The query editor helps you quickly navigate the metric space, add functions, and change function parameters. It can handle all types of Graphite queries, including complex nested queries through the use of query references. -For details, refer to the [query editor documentation]({{< relref "./query-editor" >}}). +For details, refer to the [query editor documentation](query-editor/). ## Use template variables @@ -132,7 +132,7 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). ## Get Grafana metrics into Graphite diff --git a/docs/sources/datasources/jaeger/_index.md b/docs/sources/datasources/jaeger/_index.md index 444635b638c..1aa5f777e23 100644 --- a/docs/sources/datasources/jaeger/_index.md +++ b/docs/sources/datasources/jaeger/_index.md @@ -375,7 +375,7 @@ To only show the spans you have matched, you can press the `Show matches only` t You can link to Jaeger traces from logs in Loki, Elasticsearch, Splunk, and other logs data sources by configuring an internal link. -To configure this feature, see the [Derived fields]({{< relref "../loki#configure-derived-fields" >}}) section of the Loki data source docs or the [Data links]({{< relref "../elasticsearch#data-links" >}}) section of the Elasticsearch or Splunk data source docs. +To configure this feature, see the [Derived fields](../loki/#configure-derived-fields) section of the Loki data source docs or the [Data links](../elasticsearch/#data-links) section of the Elasticsearch or Splunk data source docs. ## Link to a trace ID from metrics diff --git a/docs/sources/datasources/loki/_index.md b/docs/sources/datasources/loki/_index.md index 1dc0024779d..38225509de1 100644 --- a/docs/sources/datasources/loki/_index.md +++ b/docs/sources/datasources/loki/_index.md @@ -56,7 +56,7 @@ The following guides will help you get started with Loki: - [Loki best practices](/docs/loki/latest/best-practices/#best-practices) - [Configure the Loki data source](/docs/grafana/latest/datasources/loki/configure-loki-data-source/) - [LogQL](/docs/loki/latest/logql/) -- [Loki query editor]({{< relref "./query-editor" >}}) +- [Loki query editor](query-editor/) ## Supported Loki versions @@ -70,7 +70,7 @@ For instructions on how to add a data source to Grafana, refer to the [administr 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. -Once you've added the Loki data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards), use [Explore](ref:explore), and [annotate visualizations]({{< relref "./query-editor#apply-annotations" >}}). +Once you've added the Loki data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards), use [Explore](ref:explore), and [annotate visualizations](query-editor/#apply-annotations). {{% admonition type="note" %}} To troubleshoot configuration and other issues, check the log file located at `/var/log/grafana/grafana.log` on Unix systems, or in `/data/log` on other platforms and manual installations. @@ -149,7 +149,7 @@ datasources: The Loki data source's query editor helps you create log and metric queries that use Loki's query language, [LogQL](/docs/loki/latest/logql/). -For details, refer to the [query editor documentation]({{< relref "./query-editor" >}}). +For details, refer to the [query editor documentation](query-editor/). ## Use template variables @@ -157,4 +157,4 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). diff --git a/docs/sources/datasources/loki/query-editor/index.md b/docs/sources/datasources/loki/query-editor/index.md index 4d638eb57db..ef3f8a55fe2 100644 --- a/docs/sources/datasources/loki/query-editor/index.md +++ b/docs/sources/datasources/loki/query-editor/index.md @@ -63,7 +63,7 @@ Each mode is synchronized, so you can switch between them without losing your wo When you switch from Code mode to Builder mode with such a query, the editor displays a warning message that explains how you might lose parts of the query if you continue. You can then decide whether you still want to switch to Builder mode. -You can also augment queries by using [template variables]({{< relref "./template-variables" >}}). +You can also augment queries by using [template variables](../template-variables/). ## Toolbar elements @@ -173,9 +173,7 @@ The following options are the same for both **Builder** and **Code** mode: - **Direction** - Determines the search order. **Backward** is a backward search starting at the end of the time range. **Forward** is a forward search starting at the beginning of the time range. The default is **Backward** -- **Step** Sets the step parameter of Loki metrics queries. The default value equals to the value of `$__interval` variable, which is calculated using the time range and the width of the graph (the number of pixels). - -- **Resolution** Deprecated. Sets the step parameter of Loki metrics range queries. With a resolution of `1/1`, each pixel corresponds to one data point. `1/2` retrieves one data point for every other pixel, `1/10` retrieves one data point per 10 pixels, and so on. Lower resolutions perform better. +- **Step** Sets the step parameter of Loki metrics queries. The default value equals to the value of `$__auto` variable, which is calculated using the time range and the width of the graph (the number of pixels). ## Create a log query @@ -263,6 +261,6 @@ For more information about metric queries, refer to the [Loki metric queries doc [Annotations](ref:annotate-visualizations) overlay rich event information on top of graphs. You can add annotation queries in the Dashboard menu's Annotations view. -You can use any non-metric Loki query as a source for annotations. +You can only use log queries as a source for annotations. Grafana automatically uses log content as annotation text and your log stream labels as tags. You don't need to create any additional mapping. diff --git a/docs/sources/datasources/mssql/_index.md b/docs/sources/datasources/mssql/_index.md index cdc2a64812f..9909696daee 100644 --- a/docs/sources/datasources/mssql/_index.md +++ b/docs/sources/datasources/mssql/_index.md @@ -62,7 +62,7 @@ For instructions on how to add a data source to Grafana, refer to the [administr 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. -Once you've added the Microsoft SQL Server data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). +Once you've added the Microsoft SQL Server data source, you can [configure it](#configure-the-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). ## Configure the data source @@ -185,7 +185,7 @@ datasources: You can create queries with the Microsoft SQL Server data source's query editor when editing a panel that uses a MS SQL data source. -For details, refer to the [query editor documentation]({{< relref "./query-editor" >}}). +For details, refer to the [query editor documentation](query-editor/). ## Use template variables @@ -193,4 +193,4 @@ Instead of hard-coding details such as server, application, and sensor names in Grafana lists these variables in dropdown select boxes at the top of the dashboard to help you change the data displayed in your dashboard. Grafana refers to such variables as template variables. -For details, see the [template variables documentation]({{< relref "./template-variables" >}}). +For details, see the [template variables documentation](template-variables/). diff --git a/docs/sources/datasources/opentsdb/_index.md b/docs/sources/datasources/opentsdb/_index.md index 560ba731bb5..07a5a66add0 100644 --- a/docs/sources/datasources/opentsdb/_index.md +++ b/docs/sources/datasources/opentsdb/_index.md @@ -62,7 +62,7 @@ To configure basic settings for the data source, complete the following steps: | **Default** | Default data source that will be be pre-selected for new panels. | | **URL** | The HTTP protocol, IP, and port of your OpenTSDB server (default port is usually 4242). | | **Allowed cookies** | Listing of cookies to forward to the data source. | -| **Version** | The OpenTSDB version. | +| **Version** | The OpenTSDB version (supported versions are: 2.4, 2.3, 2.2 and versions less than 2.1). | | **Resolution** | Metrics from OpenTSDB may have data points with either second or millisecond resolution. | | **Lookup limit** | Default is 1000. | @@ -98,9 +98,13 @@ can be used to query OpenTSDB. Fill Policy is also introduced in OpenTSDB 2.2. While using OpenTSDB 2.2 data source, make sure you use either Filters or Tags as they are mutually exclusive. If used together, might give you weird results. {{% /admonition %}} +{{% admonition type="note" %}} +When using OpenTSDB 2.4 with alerting, queries are executed with the parameter `arrays=true`. This causes OpenTSDB to return data points as an array of arrays instead of a map of key-value pairs. Grafana then converts this data into the appropriate data frame format. +{{% /admonition %}} + ### Auto complete suggestions -As soon as you start typing metric names, tag names and tag values , you should see highlighted auto complete suggestions for them. +As you begin typing metric names, tag names, or tag values, highlighted autocomplete suggestions will appear. The autocomplete only works if the OpenTSDB suggest API is enabled. ## Templating queries diff --git a/docs/sources/datasources/postgres/_index.md b/docs/sources/datasources/postgres/_index.md index 3489b760f70..868a2bb7d9e 100644 --- a/docs/sources/datasources/postgres/_index.md +++ b/docs/sources/datasources/postgres/_index.md @@ -2,7 +2,7 @@ aliases: - ../data-sources/postgres/ - ../features/datasources/postgres/ -description: Guide for using PostgreSQL in Grafana +description: Introduction to the PostgreSQL data source in Grafana. keywords: - grafana - postgresql @@ -16,506 +16,58 @@ menuTitle: PostgreSQL title: PostgreSQL data source weight: 1200 refs: - provisioning-data-sources: - - pattern: /docs/grafana/ - destination: /docs/grafana//administration/provisioning/#datasources - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//administration/provisioning/#datasources - variables: - - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/variables/ - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//dashboards/variables/ - add-template-variables-interval-ms: - - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval_ms - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval_ms - add-template-variables-interval: - - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval - - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval annotate-visualizations: - pattern: /docs/grafana/ destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana//dashboards/build-dashboards/annotate-visualizations/ - configure-standard-options-display-name: + configure-postgres-data-source: - pattern: /docs/grafana/ - destination: /docs/grafana//panels-visualizations/configure-standard-options/#display-name + destination: /docs/grafana//datasources/postgres/configure/ - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//panels-visualizations/configure-standard-options/#display-name - data-source-management: + destination: /docs/grafana//datasources/postgres/configure/ + postgres-query-editor: - pattern: /docs/grafana/ - destination: /docs/grafana//administration/data-source-management/ + destination: /docs/grafana//datasources/postgres/query-editor/ - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//administration/data-source-management/ - variable-syntax-advanced-variable-format-options: + destination: /docs/grafana//datasources/postgres/query-editor/ + alerting: - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/variables/variable-syntax/#advanced-variable-format-options + destination: /docs/grafana//alerting/ - pattern: /docs/grafana-cloud/ - destination: /docs/grafana//dashboards/variables/variable-syntax/#advanced-variable-format-options + destination: /docs/grafana-cloud/alerting-and-irm/alerting/ + transformations: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/transform-data/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/transform-data/ + visualizations: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/visualizations/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/ --- # PostgreSQL data source -Grafana ships with a built-in PostgreSQL data source plugin that allows you to query and visualize data from a PostgreSQL compatible database. +Grafana includes a built-in PostgreSQL data source plugin, enabling you to query and visualize data from any PostgreSQL-compatible database. You don't need to install a plugin to add the PostgreSQL data source to your Grafana instance. -For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref: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. +Grafana offers several configuration options for this data source as well as a visual and code-based query editor. + +## Get started with the PostgreSQL data source + +The following documents will help you get started with the PostgreSQL data source in Grafana: + +- [Configure the PostgreSQL data source](ref:configure-postgres-data-source) +- [PostgreSQL query editor](ref:postgres-query-editor) + +After you have configured the data source you can: + +- Create a variety of [visualizations](ref:visualizations) +- Add [annotations](ref:annotate-visualizations) +- Set up [alerting](ref:alerting) +- Add [transformations](ref:transformations) + +View a PostgreSQL overview on Grafana Play: {{< docs/play title="PostgreSQL Overview" url="https://play.grafana.org/d/ddvpgdhiwjvuod/postgresql-overview" >}} - -## PostgreSQL settings - -To configure basic settings for the data source, complete the following steps: - -1. Click **Connections** in the left-side menu. -1. Under Your connections, click **Data sources**. -1. Enter `PostgreSQL` in the search bar. -1. Select **PostgreSQL**. - - The **Settings** tab of the data source is displayed. - -1. Set the data source's basic configuration options: - -| Name | Description | -| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **Name** | The data source name. This is how you refer to the data source in panels and queries. | -| **Default** | Default data source means that it will be pre-selected for new panels. | -| **Host** | The IP address/hostname and optional port of your PostgreSQL instance. _Do not_ include the database name. The connection string for connecting to Postgres will not be correct and it may cause errors. | -| **Database** | Name of your PostgreSQL database. | -| **User** | Database user's login/username | -| **Password** | Database user's password | -| **SSL Mode** | Determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server. When SSL Mode is disabled, SSL Method and Auth Details would not be visible. | -| **SSL Auth Details Method** | Determines whether the SSL Auth details will be configured as a file path or file content. | -| **SSL Auth Details Value** | File path or file content of SSL root certificate, client certificate and client key | -| **Max open** | The maximum number of open connections to the database, default `100`. | -| **Max idle** | The maximum number of connections in the idle connection pool, default `100`. | -| **Auto (max idle)** | If set will set the maximum number of idle connections to the number of maximum open connections. Default is `true`. | -| **Max lifetime** | The maximum amount of time in seconds a connection may be reused, default `14400`/4 hours. | -| **Version** | Determines which functions are available in the query builder. | -| **TimescaleDB** | A time-series database built as a PostgreSQL extension. When enabled, Grafana uses `time_bucket` in the `$__timeGroup` macro to display TimescaleDB specific aggregate functions in the query builder. For more information, see [TimescaleDB documentation](https://docs.timescale.com/timescaledb/latest/tutorials/grafana/grafana-timescalecloud/#connect-timescaledb-and-grafana). | - -### Min time interval - -A lower limit for the [`$__interval`](ref:add-template-variables-interval) and [`$__interval_ms`](ref:add-template-variables-interval-ms) variables. -Recommended to be set to write frequency, for example `1m` if your data is written every minute. -This option can also be overridden/configured in a dashboard panel under data source options. It's important to note that this value **needs** to be formatted as a -number followed by a valid time identifier, e.g. `1m` (1 minute) or `30s` (30 seconds). The following time identifiers are supported: - -| Identifier | Description | -| ---------- | ----------- | -| `y` | year | -| `M` | month | -| `w` | week | -| `d` | day | -| `h` | hour | -| `m` | minute | -| `s` | second | -| `ms` | millisecond | - -### Database user permissions (Important!) - -The database user you specify when you add the data source should only be granted SELECT permissions on -the specified database and tables you want to query. Grafana does not validate that the query is safe. The query -could include any SQL statement. For example, statements like `DELETE FROM user;` and `DROP TABLE user;` would be -executed. To protect against this we **highly** recommend you create a specific PostgreSQL user with restricted permissions. - -Example: - -```sql - CREATE USER grafanareader WITH PASSWORD 'password'; - GRANT USAGE ON SCHEMA schema TO grafanareader; - GRANT SELECT ON schema.table TO grafanareader; -``` - -Make sure the user does not get any unwanted privileges from the public role. - -## Query builder - -{{< figure src="/static/img/docs/screenshot-postgres-query-editor.png" class="docs-image--no-shadow" caption="PostgreSQL query builder" >}} - -The PostgreSQL query builder is available when editing a panel using a PostgreSQL data source. The built query can be run by pressing the `Run query` button in the top right corner of the editor. - -### Format - -The response from PostgreSQL can be formatted as either a table or as a time series. To use the time series format one of the columns must be named `time`. - -### Dataset and table selection - -The dataset dropdown will be populated with the configured database to which the user has access. -The table dropdown is populated with the tables that are available within that database. - -### Columns and Aggregation functions (SELECT) - -Using the dropdown, select a column to include in the data. You can also specify an optional aggregation function. - -Add further value columns by clicking the plus button and another column dropdown appears. - -{{< docs/shared source="grafana" lookup="datasources/sql-query-builder-macros.md" version="" >}} - -### Filter data (WHERE) - -To add a filter, toggle the **Filter** switch at the top of the editor. -This reveals a **Filter by column value** section with two dropdown selectors. - -Use the first dropdown to choose whether all of the filters need to match (`AND`), or if only one of the filters needs to match (`OR`). -Use the second dropdown to choose a filter. - -To filter on more columns, click the plus (`+`) button to the right of the condition dropdown. - -To remove a filter, click the `x` button next to that filter's dropdown. - -After selecting a date type column, you can choose Macros from the operators list and select timeFilter which will add the $\_\_timeFilter macro to the query with the selected date column. - -### Group By - -To group the results by column, flip the group switch at the top of the editor. You can then choose which column to group the results by. The group by clause can be removed by pressing the X button. - -### Preview - -By flipping the preview switch at the top of the editor, you can get a preview of the SQL query generated by the query builder. - -### Provision the data source - -It's now possible to configure data sources using config files with Grafana's provisioning system. You can read more about how it works and all the settings you can set for data sources on the [provisioning docs page](ref:provisioning-data-sources). - -#### Provisioning example - -```yaml -apiVersion: 1 - -datasources: - - name: Postgres - type: postgres - url: localhost:5432 - user: grafana - secureJsonData: - password: 'Password!' - jsonData: - database: grafana - sslmode: 'disable' # disable/require/verify-ca/verify-full - maxOpenConns: 100 - maxIdleConns: 100 - maxIdleConnsAuto: true - connMaxLifetime: 14400 - postgresVersion: 903 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 - timescaledb: false -``` - -{{% admonition type="note" %}} -In the above code, the `postgresVersion` value of `10` refers to version PostgreSQL 10 and above. -{{% /admonition %}} - -#### Troubleshoot provisioning - -If you encounter metric request errors or other issues: - -- Make sure your data source YAML file parameters exactly match the example. This includes parameter names and use of quotation marks. -- Make sure the `database` name is not included in the `url`. - -## Code editor - -{{< figure src="/static/img/docs/v92/sql_code_editor.png" class="docs-image--no-shadow" >}} - -To make advanced queries, switch to the code editor by clicking `code` in the top right corner of the editor. The code editor support autocompletion of tables, columns, SQL keywords, standard sql functions, Grafana template variables and Grafana macros. Columns cannot be completed before a table has been specified. - -You can expand the code editor by pressing the `chevron` pointing downwards in the lower right corner of the code editor. - -`CTRL/CMD + Return` works as a keyboard shortcut to run the query. - -## Macros - -Macros can be used within a query to simplify syntax and allow for dynamic parts. - -| Macro example | Description | -| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `$__time(dateColumn)` | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, _UNIX_TIMESTAMP(dateColumn) as time_sec_ | -| `$__timeEpoch(dateColumn)` | Will be replaced by an expression to convert to a UNIX timestamp and rename the column to `time_sec`. For example, _UNIX_TIMESTAMP(dateColumn) as time_sec_ | -| `$__timeFilter(dateColumn)` | Will be replaced by a time range filter using the specified column name. For example, _dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)_ | -| `$__timeFrom()` | Will be replaced by the start of the currently active time selection. For example, _FROM_UNIXTIME(1494410783)_ | -| `$__timeTo()` | Will be replaced by the end of the currently active time selection. For example, _FROM_UNIXTIME(1494410983)_ | -| `$__timeGroup(dateColumn,'5m')` | Will be replaced by an expression usable in GROUP BY clause. For example, *cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) as signed)*300 as signed),\* | -| `$__timeGroup(dateColumn,'5m', 0)` | Same as above but with a fill parameter so missing points in that series will be added by grafana and 0 will be used as value (only works with time series queries). | -| `$__timeGroup(dateColumn,'5m', NULL)` | Same as above but NULL will be used as value for missing points (only works with time series queries). | -| `$__timeGroup(dateColumn,'5m', previous)` | Same as above but the previous value in that series will be used as fill value if no value has been seen yet NULL will be used (only works with time series queries). | -| `$__timeGroupAlias(dateColumn,'5m')` | Will be replaced identical to $\_\_timeGroup but with an added column alias. | -| `$__unixEpochFilter(dateColumn)` | Will be replaced by a time range filter using the specified column name with times represented as Unix timestamp. For example, _dateColumn > 1494410783 AND dateColumn < 1494497183_ | -| `$__unixEpochFrom()` | Will be replaced by the start of the currently active time selection as Unix timestamp. For example, _1494410783_ | -| `$__unixEpochTo()` | Will be replaced by the end of the currently active time selection as Unix timestamp. For example, _1494497183_ | -| `$__unixEpochNanoFilter(dateColumn)` | Will be replaced by a time range filter using the specified column name with times represented as nanosecond timestamp. For example, _dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872_ | -| `$__unixEpochNanoFrom()` | Will be replaced by the start of the currently active time selection as nanosecond timestamp. For example, _1494410783152415214_ | -| `$__unixEpochNanoTo()` | Will be replaced by the end of the currently active time selection as nanosecond timestamp. For example, _1494497183142514872_ | -| `$__unixEpochGroup(dateColumn,'5m', [fillmode])` | Same as $\_\_timeGroup but for times stored as Unix timestamp (`fillMode` only works with time series queries). | -| `$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])` | Same as above but also adds a column alias (`fillMode` only works with time series queries). | - -## Table queries - -If the `Format as` query option is set to `Table` then you can basically do any type of SQL query. The table panel will automatically show the results of whatever columns and rows your query returns. - -Query editor with example query: - -![](/static/img/docs/v46/postgres_table_query.png) - -The query: - -```sql -SELECT - title as "Title", - "user".login as "Created By", - dashboard.created as "Created On" -FROM dashboard -INNER JOIN "user" on "user".id = dashboard.created_by -WHERE $__timeFilter(dashboard.created) -``` - -You can control the name of the Table panel columns by using regular `as ` SQL column selection syntax. - -The resulting table panel: - -![postgres table](/static/img/docs/v46/postgres_table.png) - -## Time series queries - -If you set Format as to _Time series_, then the query must have a column named time that returns either a SQL datetime or any numeric datatype representing Unix epoch in seconds. In addition, result sets of time series queries must be sorted by time for panels to properly visualize the result. - -A time series query result is returned in a [wide data frame format](https://grafana.com/developers/plugin-tools/key-concepts/data-frames#wide-format). Any column except time or of type string transforms into value fields in the data frame query result. Any string column transforms into field labels in the data frame query result. - -> For backward compatibility, there's an exception to the above rule for queries that return three columns including a string column named metric. Instead of transforming the metric column into field labels, it becomes the field name, and then the series name is formatted as the value of the metric column. See the example with the metric column below. - -To optionally customize the default series name formatting, refer to [Standard options definitions](ref:configure-standard-options-display-name). - -**Example with `metric` column:** - -```sql -SELECT - $__timeGroupAlias("time_date_time",'5m'), - min("value_double"), - 'min' as metric -FROM test_data -WHERE $__timeFilter("time_date_time") -GROUP BY time -ORDER BY time -``` - -Data frame result: - -```text -+---------------------+-----------------+ -| Name: time | Name: min | -| Labels: | Labels: | -| Type: []time.Time | Type: []float64 | -+---------------------+-----------------+ -| 2020-01-02 03:05:00 | 3 | -| 2020-01-02 03:10:00 | 6 | -+---------------------+-----------------+ -``` - -**Example using the fill parameter in the $\_\_timeGroupAlias macro to convert null values to be zero instead:** - -```sql -SELECT - $__timeGroupAlias("createdAt",'5m',0), - sum(value) as value, - hostname -FROM test_data -WHERE - $__timeFilter("createdAt") -GROUP BY time, hostname -ORDER BY time -``` - -Given the data frame result in the following example and using the graph panel, you will get two series named _value 10.0.1.1_ and _value 10.0.1.2_. To render the series with a name of _10.0.1.1_ and _10.0.1.2_ , use a [Standard options definitions](ref:configure-standard-options-display-name) display value of `${__field.labels.hostname}`. - -Data frame result: - -```text -+---------------------+---------------------------+---------------------------+ -| Name: time | Name: value | Name: value | -| Labels: | Labels: hostname=10.0.1.1 | Labels: hostname=10.0.1.2 | -| Type: []time.Time | Type: []float64 | Type: []float64 | -+---------------------+---------------------------+---------------------------+ -| 2020-01-02 03:05:00 | 3 | 4 | -| 2020-01-02 03:10:00 | 6 | 7 | -+---------------------+---------------------------+---------------------------+ -``` - -**Example with multiple columns:** - -```sql -SELECT - $__timeGroupAlias("time_date_time",'5m'), - min("value_double") as "min_value", - max("value_double") as "max_value" -FROM test_data -WHERE $__timeFilter("time_date_time") -GROUP BY time -ORDER BY time -``` - -Data frame result: - -```text -+---------------------+-----------------+-----------------+ -| Name: time | Name: min_value | Name: max_value | -| Labels: | Labels: | Labels: | -| Type: []time.Time | Type: []float64 | Type: []float64 | -+---------------------+-----------------+-----------------+ -| 2020-01-02 03:04:00 | 3 | 4 | -| 2020-01-02 03:05:00 | 6 | 7 | -+---------------------+-----------------+-----------------+ -``` - -## Templating - -Instead of hard-coding things like server, application and sensor name in your metric queries you can use variables in their place. Variables are shown as dropdown select boxes at the top of the dashboard. These dropdowns make it easy to change the data being displayed in your dashboard. - -Refer to [Templates and variables](ref:variables) for an introduction to the templating feature and the different types of template variables. - -### Query variable - -If you add a template variable of the type `Query`, you can write a PostgreSQL query that can -return things like measurement names, key names or key values that are shown as a dropdown select box. - -For example, you can have a variable that contains all values for the `hostname` column in a table if you specify a query like this in the templating variable _Query_ setting. - -```sql -SELECT hostname FROM host -``` - -A query can return multiple columns and Grafana will automatically create a list from them. For example, the query below will return a list with values from `hostname` and `hostname2`. - -```sql -SELECT host.hostname, other_host.hostname2 FROM host JOIN other_host ON host.city = other_host.city -``` - -To use time range dependent macros like `$__timeFilter(column)` in your query the refresh mode of the template variable needs to be set to _On Time Range Change_. - -```sql -SELECT event_name FROM event_log WHERE $__timeFilter(time_column) -``` - -Another option is a query that can create a key/value variable. The query should return two columns that are named `__text` and `__value`. The `__text` column value should be unique (if it is not unique then the first value is used). The options in the dropdown will have a text and value that allows you to have a friendly name as text and an id as the value. An example query with `hostname` as the text and `id` as the value: - -```sql -SELECT hostname AS __text, id AS __value FROM host -``` - -You can also create nested variables. Using a variable named `region`, you could have -the hosts variable only show hosts from the current selected region with a query like this (if `region` is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values): - -```sql -SELECT hostname FROM host WHERE region IN($region) -``` - -#### Using `__searchFilter` to filter results in Query Variable - -Using `__searchFilter` in the query field will filter the query result based on what the user types in the dropdown select box. -When nothing has been entered by the user the default value for `__searchFilter` is `%`. - -> Important that you surround the `__searchFilter` expression with quotes as Grafana does not do this for you. - -The example below shows how to use `__searchFilter` as part of the query field to enable searching for `hostname` while the user types in the dropdown select box. - -Query - -```sql -SELECT hostname FROM my_host WHERE hostname LIKE '$__searchFilter' -``` - -### Using Variables in Queries - -Template variable values are only quoted when the template variable is a `multi-value`. - -If the variable is a multi-value variable then use the `IN` comparison operator rather than `=` to match against multiple values. - -There are two syntaxes: - -`$` Example with a template variable named `hostname`: - -```sql -SELECT - atimestamp as time, - aint as value -FROM table -WHERE $__timeFilter(atimestamp) and hostname in($hostname) -ORDER BY atimestamp ASC -``` - -`[[varname]]` Example with a template variable named `hostname`: - -```sql -SELECT - atimestamp as time, - aint as value -FROM table -WHERE $__timeFilter(atimestamp) and hostname in([[hostname]]) -ORDER BY atimestamp ASC -``` - -#### Disabling quoting for multi-value variables - -Grafana automatically creates a quoted, comma-separated string for multi-value variables. For example: if `server01` and `server02` are selected then it will be formatted as: `'server01', 'server02'`. To disable quoting, use the csv formatting option for variables: - -`${servers:csv}` - -Read more about variable formatting options in the [Variables](ref:variable-syntax-advanced-variable-format-options) documentation. - -## Annotations - -[Annotations](ref:annotate-visualizations) allow you to overlay rich event information on top of graphs. You add annotation queries via the Dashboard menu / Annotations view. - -**Example query using time column with epoch values:** - -```sql -SELECT - epoch_time as time, - metric1 as text, - concat_ws(', ', metric1::text, metric2::text) as tags -FROM - public.test_data -WHERE - $__unixEpochFilter(epoch_time) -``` - -**Example region query using time and timeend columns with epoch values:** - -```sql -SELECT - epoch_time as time, - epoch_time_end as timeend, - metric1 as text, - concat_ws(', ', metric1::text, metric2::text) as tags -FROM - public.test_data -WHERE - $__unixEpochFilter(epoch_time) -``` - -**Example query using time column of native SQL date/time data type:** - -```sql -SELECT - native_date_time as time, - metric1 as text, - concat_ws(', ', metric1::text, metric2::text) as tags -FROM - public.test_data -WHERE - $__timeFilter(native_date_time) -``` - -| Name | Description | -| --------- | ----------------------------------------------------------------------------------------------------------------- | -| `time` | The name of the date/time field. Could be a column with a native SQL date/time data type or epoch value. | -| `timeend` | Optional name of the end date/time field. Could be a column with a native SQL date/time data type or epoch value. | -| `text` | Event description field. | -| `tags` | Optional field name to use for event tags as a comma separated string. | - -## Alerting - -Time series queries should work in alerting conditions. Table formatted queries are not yet supported in alert rule -conditions. diff --git a/docs/sources/datasources/postgres/configure/_index.md b/docs/sources/datasources/postgres/configure/_index.md new file mode 100644 index 00000000000..7b6a66c0a70 --- /dev/null +++ b/docs/sources/datasources/postgres/configure/_index.md @@ -0,0 +1,194 @@ +--- +description: This document provides instructions for configuring the PostgreSQL data source. +keywords: + - grafana + - postgresql + - guide +labels: + products: + - cloud + - enterprise + - oss +menuTitle: Configure the PostgreSQL data source +title: Configure the PostgreSQL data source +weight: 10 +refs: + provisioning-data-sources: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/provisioning/#datasources + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/provisioning/#datasources + variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/ + add-template-variables-interval-ms: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval_ms + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval_ms + add-template-variables-interval: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval + data-source-management: + - pattern: /docs/grafana/ + destination: /docs/grafana//administration/data-source-management/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//administration/data-source-management/ + variable-syntax-advanced-variable-format-options: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/variable-syntax/#advanced-variable-format-options + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/variable-syntax/#advanced-variable-format-options +--- + +# Configure the PostgreSQL data source + +This document provides instructions for configuring the PostgreSQL data source and explains available configuration options. For general information on managing data sources refer to [Data source management](ref:data-source-management). + +## Before you begin + +You must have the `Organization administrator` role to configure the Postgres data source. +Organization administrators can also [configure the data source via YAML](#provision-the-data-source) with the Grafana provisioning system. + +Grafana comes with a built-in PostgreSQL data source plugin, eliminating the need to install a plugin. + +{{< admonition type="note" >}} +When adding a data source, the database user you specify should have only `SELECT` permissions on the relevant database and tables. Grafana does not validate the safety of queries, which means they can include potentially harmful SQL statements, such as `USE otherdb;` or `DROP TABLE user;`, that could be executed. To mitigate this risk, Grafana strongly recommends creating a dedicated PostgreSQL user with restricted permissions. +{{< /admonition >}} + +Example: + +```sql + CREATE USER grafanareader WITH PASSWORD 'password'; + GRANT USAGE ON SCHEMA schema TO grafanareader; + GRANT SELECT ON schema.table TO grafanareader; +``` + +## Add the PostgreSQL data source + +Complete the following steps to set up a new PostgreSQL data source: + +1. Click **Connections** in the left-side menu. +1. Click **Add new connection** +1. Type `PostgreSQL` in the search bar. +1. Select the **PostgreSQL data source**. +1. Click **Add new data source** in the upper right. + +You are taken to the **Settings** tab where you will configure the data source. + +## PostgreSQL configuration options + +Following is a list of PostgreSQL configuration options: + +- **Name** - Sets the name you use to refer to the data source in panels and queries. Examples: `PostgreSQL-DB-1`. +- **Default** - Toggle to set this specific PostgreSQL data source as the default pre-selected data source in panels and visualizations. + +**Connection section:** + +- **Host URL** - The IP address/hostname and optional port of your PostgreSQL instance. +- **Database name** - The name of your PostgreSQL database. + +**Authentication section:** + +- **Username** - Enter the username used to connect to your PostgreSQL database. +- **Password** - Enter the password used to connect to the PostgreSQL database. +- **TLS/SSL Mode** - Determines whether or with what priority a secure SSL TCP/IP connection will be negotiated with the server. When **TLS/SSL Mode** is disabled, **TLS/SSL Method** and **TLS/SSL Auth Details** aren't visible options. +- **TLS/SSL Method** - Determines how TLS/SSL certificates are configured. + - **File system path** - This option allows you to configure certificates by specifying paths to existing certificates on the local file system where Grafana is running. Ensure this file is readable by the user executing the Grafana process. + - **Certificate content** - This option allows you to configure certificate by specifying their content. The content is stored and encrypted in the Grafana database. When connecting to the database, the certificates are saved as files, on the local filesystem, in the Grafana data path. + +**TLS/SSL Auth Details** + +If you select the TLS/SSL Mode options **require**, **verify-ca** or **verify-full** and **file system path** the following are required: + +- **TLS/SSL Root Certificate** - Specify the path to the root certificate file. +- **TLS/SSL Client Certificate** - Specify the path to the client certificate and ensure the file is accessible to the user running the Grafana process. +- **TLS/SSL Client Key** - Specify the path to the client key file and ensure the file is accessible to the user running the Grafana process. + +If you select the TLS/SSL Mode option **require** and TLS/SSL Method certificate content the following are required: + +- **TLS/SSL Client Certificate** - Provide the client certificate. +- **TLS/SSL Client Key** - Provide the client key. + +If you select the TLS/SSL Mode options **verify-ca** or **verify-full** with the TLS/SSL Method certificate content the following are required: + +- **TLS/SSL Client Certificate** - Provide the client certificate. +- **TLS/SSL Root Certificate** - Provide the root certificate. +- **TLS/SSL Client Key** - Provide the client key. + +**PostgreSQL Options:** + +- **Version** - Determines which functions are available in the query builder. The default is the current version. +- **Min time interval** - Defines a lower limit for the auto group by by time interval. Grafana recommends aligning this setting with the data write frequency. For example, set it to `1m` if your data is written every minute. Refer to [Min time interval](#min-time-interval) for format examples. +- **TimescaleDB** - A time-series database built as a PostgreSQL extension. When enabled, Grafana uses `time_bucket` in the `$__timeGroup` macro to display TimescaleDB specific aggregate functions in the query builder. For more information, refer to [TimescaleDB documentation](https://docs.timescale.com/timescaledb/latest/tutorials/grafana/grafana-timescalecloud/#connect-timescaledb-and-grafana). + +**Connection limits:** + +- **Max open** - The maximum number of open connections to the database. The default `100`. +- **Auto max idle** - Toggle to set the maximum number of idle connections to the number of maximum open connections. This setting is toggled on by default. +- **Max idle** - The maximum number of connections in the idle connection pool. The default `100`. +- **Max lifetime** - The maximum amount of time in seconds a connection may be reused. The default is `14400`, or 4 hours. + +**Private data source connect** - _Only for Grafana Cloud users._ Private data source connect, or PDC, allows you to establish a private, secured connection between a Grafana Cloud instance, or stack, and data sources secured within a private network. Click the drop-down to locate the URL for PDC. For more information regarding Grafana PDC refer to [Private data source connect (PDC)](https://grafana.com/docs/grafana-cloud/connect-externally-hosted/private-data-source-connect/). + +Click **Manage private data source connect** to be taken to your PDC connection page, where you’ll find your PDC configuration details. + +After you have added your PostgreSQL connection settings, click **Save & test** to test and save the data source connection. + +### Min time interval + +The **Min time interval** setting defines a lower limit for the [`$__interval`](ref:add-template-variables-interval) and [`$__interval_ms`](ref:add-template-variables-interval-ms) variables. + +This option can also be configured or overridden in the dashboard panel under the data source settings. + +This value must be formatted as a number followed by a valid time identifier: + +| Identifier | Description | +| ---------- | ----------- | +| `y` | year | +| `M` | month | +| `w` | week | +| `d` | day | +| `h` | hour | +| `m` | minute | +| `s` | second | +| `ms` | millisecond | + +## Provision the data source + +You can define and configure the data source in YAML files with [provisioning](/docs/grafana//administration/provisioning/#data-sources). +For more information about provisioning, and available configuration options, refer to [Provision Grafana](ref:provisioning-data-sources). + +### PostgreSQL provisioning example + +```yaml +apiVersion: 1 + +datasources: + - name: Postgres + type: postgres + url: localhost:5432 + user: grafana + secureJsonData: + password: 'Password!' + jsonData: + database: grafana + sslmode: 'disable' # disable/require/verify-ca/verify-full + maxOpenConns: 100 + maxIdleConns: 100 + maxIdleConnsAuto: true + connMaxLifetime: 14400 + postgresVersion: 903 # 903=9.3, 904=9.4, 905=9.5, 906=9.6, 1000=10 + timescaledb: false +``` + +#### Troubleshoot provisioning issues + +If you encounter metric request errors or other issues: + +- Ensure that the parameters in your data source YAML file precisely match the example provided, including parameter names and the correct use of quotation marks. +- Verify that the database name _isn't_ included in the URL. diff --git a/docs/sources/datasources/postgres/query-editor/_index.md b/docs/sources/datasources/postgres/query-editor/_index.md new file mode 100644 index 00000000000..5c37f7047e7 --- /dev/null +++ b/docs/sources/datasources/postgres/query-editor/_index.md @@ -0,0 +1,410 @@ +--- +description: This document describes the PostgreSQL query editor in Grafana. +keywords: + - grafana + - postgresql + - guide +labels: + products: + - cloud + - enterprise + - oss +menuTitle: PostgreSQL query editor +title: PostgreSQL query editor +weight: 20 +refs: + variables: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/ + add-template-variables-interval: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//dashboards/variables/add-template-variables/#__interval + explore: + - pattern: /docs/grafana/ + destination: /docs/grafana//explore/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana//explore/ + query-transform-data: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/ + query-editor: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/query-transform-data/#query-editors + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/#query-editors + alert-rules: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/fundamentals/alert-rules/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/ + template-annotations-and-labels: + - pattern: /docs/grafana/ + destination: /docs/grafana//alerting/alerting-rules/templates/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/alerting-and-irm/alerting/alerting-rules/templates/ + templates: + - pattern: /docs/grafana/ + destination: /docs/grafana//dashboards/variables/#templates + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/dashboards/variables/#templates +--- + +# PostgreSQL query editor + +Grafana query editors are unique for each data source. + +For general information on Grafana query editors, refer to [Query editors](ref:query-editor). + +For general information on querying data sources in Grafana, refer to [Query and transform data](ref:query-transform-data). + +The PostgreSQL query editor is located on the [Explore page](ref:explore). You can also access the PostgreSQL query editor from a dashboard panel. Click the ellipsis in the upper right of the panel and select **Edit**. + +{{< figure src="/static/img/docs/screenshot-postgres-query-editor.png" class="docs-image--no-shadow" caption="PostgreSQL query builder" >}} + +## PostgreSQL query editor components + +The PostgreSQL query editor has two modes: **Builder** and **Code**. + +Builder mode helps you build a query using a visual interface. Code mode allows for advanced querying and offers support for complex SQL query writing. + +### PostgreSQL Builder mode + +The following components will help you build a PostgreSQL query: + +- **Format** - Select a format response from the drop-down for the PostgreSQL query. The default is **Table**. If you use the **Time series** format option, one of the columns must be `time`. Refer to [Time series queries](#time-series-queries) for more information. +- **Table** - Select a table from the drop-down. Tables correspond to the chosen database. +- **Data operations** - _Optional_ Select an aggregation from the drop-down. You can add multiple data operations by clicking the **+ sign**. Click the **garbage can icon** to remove data operations. +- **Column** - Select a column on which to run the aggregation. +- **Alias** - _Optional_ Add an alias from the drop-down. You can also add your own alias by typing it in the box and clicking **Enter**. Remove an alias by clicking the **X**. +- **Filter** - Toggle to add filters. +- **Filter by column value** - _Optional_ If you toggle **Filter** you can add a column to filter by from the drop-down. To filter on more columns, click the **+ sign** to the right of the condition drop-down. You can choose a variety of operators from the drop-down next to the condition. When multiple filters are added you can add an `AND` operator to display all true conditions or an `OR` operator to display any true conditions. Use the second drop-down to choose a filter. To remove a filter, click the `X` button next to that filter's drop-down. After selecting a date type column, you can choose **Macros** from the operators list and select `timeFilter` which will add the `$\_\_timeFilter` macro to the query with the selected date column. +- **Group** - Toggle to add **Group by column**. +- **Group by column** - Select a column to filter by from the drop-down. Click the **+sign** to filter by multiple columns. Click the **X** to remove a filter. +- **Order** - Toggle to add an `ORDER BY` statement. +- **Order by** - Select a column to order by from the drop-down. Select ascending (`ASC`) or descending (`DESC`) order. +- **Limit** - You can add an optional limit on the number of retrieved results. Default is 50. +- **Preview** - Toggle for a preview of the SQL query generated by the query builder. Preview is toggled on by default. + +## PostgreSQL Code mode + +To create advanced queries, switch to **Code mode** by clicking **Code** in the upper right of the editor window. Code mode supports the auto-completion of tables, columns, SQL keywords, standard SQL functions, Grafana template variables, and Grafana macros. Columns cannot be completed before a table has been specified. + +{{< figure src="/static/img/docs/v92/sql_code_editor.png" class="docs-image--no-shadow" >}} + +Select **Table** or **Time Series** as the format. Click the **{}** in the bottom right to format the query. Click the **downward caret** to expand the Code mode editor. **CTRL/CMD + Return** serves as a keyboard shortcut to execute the query. + +{{< admonition type="warning" >}} +Changes made to a query in Code mode will not transfer to Builder mode and will be discarded. You will be prompted to copy your code to the clipboard to save any changes. +{{< /admonition >}} + +## Macros + +You can add macros to your queries to simplify the syntax and enable dynamic elements, such as date range filters. + +| Macro example | Description | +| ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `$__time(dateColumn)` | Replaces the value with an expression to convert to a UNIX timestamp and renames the column to `time_sec`. Example: `UNIX_TIMESTAMP(dateColumn) AS time_sec`. | +| `$__timeEpoch(dateColumn)` | Replaces the value with an expression to convert to a UNIX Epoch timestamp and renames the column to `time_sec`. Example: `UNIX_TIMESTAMP(dateColumn) AS time_sec`. | +| `$__timeFilter(dateColumn)` | Replaces the value a time range filter using the specified column name. Example: `dateColumn BETWEEN FROM_UNIXTIME(1494410783) AND FROM_UNIXTIME(1494410983)` | +| `$__timeFrom()` | Replaces the value with the start of the currently active time selection. Example: `FROM_UNIXTIME(1494410783)` | +| `$__timeTo()` | Replaces the value with the end of the currently active time selection. Example: `FROM_UNIXTIME(1494410983)` | +| `$__timeGroup(dateColumn,'5m')` | Replaces the value with an expression suitable for use in a `GROUP BY` clause. Example: `cast(cast(UNIX_TIMESTAMP(dateColumn)/(300) AS signed)*300 AS signed)` | +| `$__timeGroup(dateColumn,'5m', 0)` | Same as the `$__timeGroup(dateColumn,'5m')` macro, but includes a fill parameter to ensure missing points in the series are added by Grafana, using 0 as the default value. **This applies only to time series queries.** | +| `$__timeGroup(dateColumn,'5m', NULL)` | Same as the `$__timeGroup(dateColumn,'5m', 0)` but `NULL` is used as the value for missing points. _This applies only to time series queries._ | +| `$__timeGroup(dateColumn,'5m', previous)` | Same as the `$__timeGroup(dateColumn,'5m', previous)` macro, but uses the previous value in the series as the fill value. If no previous value exists, it uses `NULL`. _This applies only to time series queries._ | +| `$__timeGroupAlias(dateColumn,'5m')` | Replaces the value identical to `$__timeGroup` but with an added column alias. | +| `$__unixEpochFilter(dateColumn)` | Replaces the value by a time range filter using the specified column name with times represented as a UNIX timestamp. Example: `dateColumn > 1494410783 AND dateColumn < 1494497183` | +| `$__unixEpochFrom()` | Replaces the value with the start of the currently active time selection as a UNIX timestamp. Example: `1494410783` | +| `$__unixEpochTo()` | Replaces the value with the end of the currently active time selection as a UNIX timestamp. Example: `1494497183` | +| `$__unixEpochNanoFilter(dateColumn)` | Replaces the value with a time range filter using the specified column name with time represented as a nanosecond timestamp. Example: `dateColumn > 1494410783152415214 AND dateColumn < 1494497183142514872` | +| `$__unixEpochNanoFrom()` | Replaces the value with the start of the currently active time selection as a nanosecond timestamp. Example: `1494410783152415214` | +| `$__unixEpochNanoTo()` | Replaces the value with the end of the currently active time selection as nanosecond timestamp. Example: `1494497183142514872` | +| `$__unixEpochGroup(dateColumn,'5m', [fillmode])` | Same as `$__timeGroup` but for times stored as Unix timestamp. `fillMode` only works with time series queries. | +| `$__unixEpochGroupAlias(dateColumn,'5m', [fillmode])` | Same as `$__timeGroup` but also adds a column alias. `fillMode` only works with time series queries. | + +## Table SQL queries + +If the **Format** option is set to **Table**, you can execute virtually any type of SQL query. The Table panel will automatically display the resulting columns and rows from your query. + +![Table query](/media/docs/postgres/PostgreSQL-query-editor-v11.4.png) + +You can change or customize the name of a Table panel column by using the SQL keyword `AS` syntax. + +```sql +SELECT + title as "Title", + "user".login as "Created By", + dashboard.created as "Created On" +FROM dashboard +INNER JOIN "user" on "user".id = dashboard.created_by +WHERE $__timeFilter(dashboard.created) +``` + +## Time series queries + +Set the **Format** option to **Time series** to create and run time series queries. + +{{< admonition type="note" >}} +To run a time series query you must include a column named `time` that returns either a SQL `datetime` value or a numeric datatype representing the UNIX epoch time in seconds. Additionally, the query results must be sorted by the `time` column for proper visualization in panels. +{{< /admonition >}} + +The examples in this section refer to the data in the following table: + +```text ++---------------------+--------------+---------------------+----------+ +| time_date_time | value_double | CreatedAt | hostname | ++---------------------+--------------+---------------------+----------+ +| 2020-01-02 03:05:00 | 3.0 | 2020-01-02 03:05:00 | 10.0.1.1 | +| 2020-01-02 03:06:00 | 4.0 | 2020-01-02 03:06:00 | 10.0.1.2 | +| 2020-01-02 03:10:00 | 6.0 | 2020-01-02 03:10:00 | 10.0.1.1 | +| 2020-01-02 03:11:00 | 7.0 | 2020-01-02 03:11:00 | 10.0.1.2 | +| 2020-01-02 03:20:00 | 5.0 | 2020-01-02 03:20:00 | 10.0.1.2 | ++---------------------+--------------+---------------------+----------+ +``` + +Time series query results are returned in [wide data frame format](https://grafana.com/developers/plugin-tools/key-concepts/data-frames#wide-format). In the data frame query result, any column, except for time or string-type columns, transforms into value fields. String columns, on the other hand, become field labels. + +{{< admonition type="note" >}} +For backward compatibility, an exception to this rule applies to queries that return three columns, one of which is a string column named `metric`. Instead of converting the metric column into field labels, it is used as the field name, while the series name is set to its value. See the following example for reference. +{{< /admonition >}} + +**Example with `metric` column:** + +```sql +SELECT + $__timeGroupAlias("time_date_time",'5m'), + min("value_double"), + 'min' as metric +FROM test_data +WHERE $__timeFilter("time_date_time") +GROUP BY time +ORDER BY time +``` + +Data frame result: + +```text ++---------------------+-----------------+ +| Name: time | Name: min | +| Labels: | Labels: | +| Type: []time.Time | Type: []float64 | ++---------------------+-----------------+ +| 2020-01-02 03:05:00 | 3 | +| 2020-01-02 03:10:00 | 6 | ++---------------------+-----------------+ +``` + +To customize default series name formatting, refer to [Standard options definitions](ref:configure-standard-options-display-name). + +Following are time series query examples. + +**Example using the fill parameter in the $\_\_timeGroupAlias macro to convert null values to be zero instead:** + +```sql +SELECT + $__timeGroupAlias("createdAt",'5m',0), + sum(value) as value, + hostname +FROM test_data +WHERE + $__timeFilter("createdAt") +GROUP BY time, hostname +ORDER BY time +``` + +Based on the data frame result in the following example, the time series panel will generate two series named _value 10.0.1.1_ and _value 10.0.1.2_. To display the series names as _10.0.1.1_ and _10.0.1.2_, use the [Standard options definitions](ref:configure-standard-options-display-name) display value `${__field.labels.hostname}`. + +Data frame result: + +```text ++---------------------+---------------------------+---------------------------+ +| Name: time | Name: value | Name: value | +| Labels: | Labels: hostname=10.0.1.1 | Labels: hostname=10.0.1.2 | +| Type: []time.Time | Type: []float64 | Type: []float64 | ++---------------------+---------------------------+---------------------------+ +| 2020-01-02 03:05:00 | 3 | 4 | +| 2020-01-02 03:10:00 | 6 | 7 | ++---------------------+---------------------------+---------------------------+ +``` + +**Example with multiple columns:** + +```sql +SELECT + $__timeGroupAlias("time_date_time",'5m'), + min("value_double") as "min_value", + max("value_double") as "max_value" +FROM test_data +WHERE $__timeFilter("time_date_time") +GROUP BY time +ORDER BY time +``` + +Data frame result: + +```text ++---------------------+-----------------+-----------------+ +| Name: time | Name: min_value | Name: max_value | +| Labels: | Labels: | Labels: | +| Type: []time.Time | Type: []float64 | Type: []float64 | ++---------------------+-----------------+-----------------+ +| 2020-01-02 03:04:00 | 3 | 4 | +| 2020-01-02 03:05:00 | 6 | 7 | ++---------------------+-----------------+-----------------+ +``` + +## Templating + +Instead of hard coding values like server, application, or sensor names in your metric queries, you can use variables. Variables appear as drop-down select boxes at the top of the dashboard. These drop-downs make it easy to change the data being displayed in your dashboard. + +Refer to [Templates](ref:templates) for an introduction to creating template variables as well as the different types. + +### Query variable + +If you add a `Query` template variable you can write a PostgreSQL query to retrieve items such as measurement names, key names, or key values, which will be displayed in the drop-down menu. + +For example, you can use a variable to retrieve all the values from the `hostname` column in a table by creating the following query in the templating variable _Query_ setting. + +```sql +SELECT hostname FROM host +``` + +A query can return multiple columns, and Grafana will automatically generate a list based on the query results. For example, the following query returns a list with values from `hostname` and `hostname2`. + +```sql +SELECT host.hostname, other_host.hostname2 FROM host JOIN other_host ON host.city = other_host.city +``` + +To use time range dependent macros like `$__timeFilter(column)` in your query, you must set the template variable's refresh mode to _On Time Range Change_. + +```sql +SELECT event_name FROM event_log WHERE $__timeFilter(time_column) +``` + +Another option is a query that can create a key/value variable. The query should return two columns that are named `__text` and `__value`. The `__text` column must contain unique values (if not, only the first value is used). This allows the drop-down options to display a text-friendly name as the text while using an ID as the value. For example, a query could use `hostname` as the text and `id` as the value: + +```sql +SELECT hostname AS __text, id AS __value FROM host +``` + +You can also create nested variables. For example, if you have a variable named `region`, you can configure the `hosts` variable to display only the hosts within the currently selected region as shown in the following example. If `region` is a multi-value variable, use the `IN` operator instead of `=` to match multiple values. + +```sql +SELECT hostname FROM host WHERE region IN($region) +``` + +#### Using `__searchFilter` to filter results in Query Variable + +Using `__searchFilter` in the query field allows the query results to be filtered based on the user’s input in the drop-down selection box. If you do not enter anything, the default value for `__searchFilter` is `%`. + +Note that you must enclose the `__searchFilter` expression in quotes as Grafana does not add them automatically. + +The following example demonstrates how to use `__searchFilter` in the query field to enable real-time searching for `hostname` as the user type in the drop-down selection box. + +```sql +SELECT hostname FROM my_host WHERE hostname LIKE '$__searchFilter' +``` + +### Using Variables in Queries + +Template variable values are only quoted when the template variable is a `multi-value`. + +If the variable is a multi-value variable, use the `IN` comparison operator instead of `=` to match against multiple values. + +You can use two different syntaxes: + +`$` Example with a template variable named `hostname`: + +```sql +SELECT + atimestamp as time, + aint as value +FROM table +WHERE $__timeFilter(atimestamp) and hostname in($hostname) +ORDER BY atimestamp ASC +``` + +`[[varname]]` Example with a template variable named `hostname`: + +```sql +SELECT + atimestamp as time, + aint as value +FROM table +WHERE $__timeFilter(atimestamp) and hostname in([[hostname]]) +ORDER BY atimestamp ASC +``` + +#### Disabling quoting for multi-value variables + +Grafana automatically formats multi-value variables as a quoted, comma-separated string. For example, if `server01` and `server02` are selected, they are formatted as `'server01'`, `'server02'`. To remove the quotes, enable the CSV formatting option for the variables: + +`${servers:csv}` + +Read more about variable formatting options in the [Variables](ref:variable-syntax-advanced-variable-format-options) documentation. + +## Annotations + +[Annotations](ref:annotate-visualizations) allow you to overlay rich event information on top of graphs. Add annotation queries via the **Dashboard settings > Annotations view**. + +**Example query using a `time` column with epoch values:** + +```sql +SELECT + epoch_time as time, + metric1 as text, + concat_ws(', ', metric1::text, metric2::text) as tags +FROM + public.test_data +WHERE + $__unixEpochFilter(epoch_time) +``` + +**Example region query using `time` and `timeend` columns with epoch values:** + +```sql +SELECT + epoch_time as time, + epoch_time_end as timeend, + metric1 as text, + concat_ws(', ', metric1::text, metric2::text) as tags +FROM + public.test_data +WHERE + $__unixEpochFilter(epoch_time) +``` + +**Example query using a `time` column with a native SQL date/time data type:** + +```sql +SELECT + native_date_time as time, + metric1 as text, + concat_ws(', ', metric1::text, metric2::text) as tags +FROM + public.test_data +WHERE + $__timeFilter(native_date_time) +``` + +| Name | Description | +| --------- | --------------------------------------------------------------------------------------------------------------------- | +| `time` | The name of the date/time field, which can be a column with a native SQL date/time data type or epoch value. | +| `timeend` | Optional name of the end date/time field, which can be a column with a native SQL date/time data type or epoch value. | +| `text` | Event description field. | +| `tags` | Optional field name to use for event tags as a comma-separated string. | + +## Alerting + +Use time series queries to create alerts. Table formatted queries aren't yet supported in alert rule conditions. + +For more information regarding alerting refer to the following: + +- [Alert rules](ref:alert-rules) +- [Template annotations and labels](ref:template-annotations-and-labels) diff --git a/docs/sources/datasources/prometheus/_index.md b/docs/sources/datasources/prometheus/_index.md index cd5cbb04ac1..46015e7a0af 100644 --- a/docs/sources/datasources/prometheus/_index.md +++ b/docs/sources/datasources/prometheus/_index.md @@ -89,13 +89,13 @@ For instructions on how to add a data source to Grafana, refer to the [administr Only users with the organization `administrator` role can add data sources and edit existing data sources. Administrators can also [configure the data source via YAML](#provision-the-data-source) with Grafana's provisioning system. -Once you've added the Prometheus data source, you can [configure it](ref:configure-prometheus-data-source) so that your Grafana instance's users can create queries in its [query editor]({{< relref "./query-editor" >}}) when they [build dashboards](ref:build-dashboards), use [Explore](ref:explore), and [annotate visualizations](ref:annotate-visualizations). +Once you've added the Prometheus data source, you can [configure it](ref:configure-prometheus-data-source) so that your Grafana instance's users can create queries in its [query editor](query-editor/) when they [build dashboards](ref:build-dashboards), use [Explore](ref:explore), and [annotate visualizations](ref:annotate-visualizations). The following guides will help you get started with the Prometheus data source: - [Configure the Prometheus data source](ref:configure-prometheus-data-source) -- [Prometheus query editor]({{< relref "./query-editor" >}}) -- [Template variables]({{< relref "./template-variables" >}}) +- [Prometheus query editor](query-editor/) +- [Template variables](template-variables/) ## Prometheus API diff --git a/docs/sources/datasources/prometheus/configure-prometheus-data-source.md b/docs/sources/datasources/prometheus/configure-prometheus-data-source.md index 077b6aeff04..a0888659638 100644 --- a/docs/sources/datasources/prometheus/configure-prometheus-data-source.md +++ b/docs/sources/datasources/prometheus/configure-prometheus-data-source.md @@ -48,13 +48,18 @@ Grafana ships with built-in support for Prometheus. If you are new to Prometheus ## Configure the data source +{{< shared id="add-prom-data-source" >}} + To add the Prometheus data source, complete the following steps: 1. Click **Connections** in the left-side menu. 1. Under **Connections**, click **Add new connection**. 1. Enter `Prometheus` in the search bar. -1. Select **Prometheus**. +1. Click **Prometheus data source**. 1. Click **Add new data source** in the upper right. +1. Enter a name for the data source. + +{{< /shared >}} You will be taken to the **Settings** tab where you will set up your Prometheus configuration. @@ -70,7 +75,8 @@ The first option to configure is the name of your connection: ### Connection section -- **Prometheus server URL** - The URL of your Prometheus server. If your Prometheus server is local, use `http://localhost:9090`. If it is on a server within a network, this is the URL with port where you are running Prometheus. Example: `http://prometheus.example.orgname:9090`. +- **Prometheus server URL** - The URL of your Prometheus server. {{< shared id="prom-data-source-url" >}} + If your Prometheus server is local, use `http://localhost:9090`. If it's on a server within a network, this is the URL with the port where you are running Prometheus. Example: `http://prometheus.example.orgname:9090`. {{< admonition type="note" >}} @@ -80,6 +86,8 @@ You should use the IP address of the Prometheus container, or the hostname if yo {{< /admonition >}} +{{< /shared >}} + ### Authentication section There are several authentication methods you can choose in the Authentication section. @@ -124,7 +132,7 @@ Following are additional configuration options. {{% admonition type="note" %}} -The **Manage alerts via Alerting UI** toggle is enabled by default. You can change this behavior by setting the [default_manage_alerts_ui_toggle]({{< relref "../../setup-grafana/configure-grafana/#default_manage_alerts_ui_toggle" >}}) option in the Grafana configuration file. +The **Manage alerts via Alerting UI** toggle is enabled by default. You can change this behavior by setting the [default_manage_alerts_ui_toggle](../../../setup-grafana/configure-grafana/#default_manage_alerts_ui_toggle) option in the Grafana configuration file. {{% /admonition %}} @@ -136,7 +144,7 @@ The **Manage alerts via Alerting UI** toggle is enabled by default. You can chan ### Query editor -- **Default editor** - Sets a default editor. Options are `Builder` or `Code`. For information on query editor types see [Prometheus query editor]({{< relref "./query-editor" >}}). +- **Default editor** - Sets a default editor. Options are `Builder` or `Code`. For information on query editor types see [Prometheus query editor](../query-editor/). - **Disable metrics lookup** - Toggle on to disable the metrics chooser and metric/label support in the query field's autocomplete. This helps if you have performance issues with large Prometheus instances. @@ -171,3 +179,22 @@ Support for exemplars is available only for the Prometheus data source. If this - **Label name** - The name of the field in the `labels` object used to obtain the traceID property. - **Remove exemplar link** - Click to remove existing links. + +### Troubleshooting + +Refer to the following troubleshooting information, as required. + +#### Data doesn't appear in Explore metrics + + + +If metric data doesn't appear in Explore after you've successfully tested a connection to a Prometheus data source or sent +metrics to Grafana Cloud, ensure that you've selected the correct data source in the **Data source** drop-down menu. If +you've used remote_write to send metrics to Grafana Cloud, the data source name follows the convention +`grafanacloud-stackname-prom`. + + + +The following image shows the **Data source** field in Explore metrics. + +![Image that shows Prometheus metrics in Explore](/media/docs/grafana/data-sources/prometheus/troubleshoot-connection-1.png) diff --git a/docs/sources/datasources/pyroscope/_index.md b/docs/sources/datasources/pyroscope/_index.md index 069902bfc0a..60efe8f3f33 100644 --- a/docs/sources/datasources/pyroscope/_index.md +++ b/docs/sources/datasources/pyroscope/_index.md @@ -56,7 +56,7 @@ To use profiling data, you should: - [Configure your application to send profiles](/docs/pyroscope//configure-client/) - [Configure the Grafana Pyroscope data source](./configure-pyroscope-data-source/). -- [View and query profiling data using Explore Profiles or the query editor ](./query-profile-data/) +- [View and query profiling data using Profiles Drilldown or the query editor ](./query-profile-data/) ## Continuous profiling diff --git a/docs/sources/datasources/pyroscope/configure-pyroscope-data-source.md b/docs/sources/datasources/pyroscope/configure-pyroscope-data-source.md index 8a344f6a7e6..0acfd01df3c 100644 --- a/docs/sources/datasources/pyroscope/configure-pyroscope-data-source.md +++ b/docs/sources/datasources/pyroscope/configure-pyroscope-data-source.md @@ -33,11 +33,11 @@ refs: destination: /docs/grafana//datasources/tempo/configure-tempo-data-source/ - pattern: /docs/grafana-cloud/ destination: docs/grafana-cloud/connect-externally-hosted/data-sources/tempo/configure-tempo-data-source/ - provisioning-data-sources: + explore-profiles: - pattern: /docs/grafana/ - destination: /docs/grafana//administration/provisioning/#data-sources - - pattern: /docs/grafana-cloud/provision - destination: /docs/grafana//administration/provisioning/#data-sources + destination: /docs/grafana//explore/simplified-exploration/profiles/ + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana-cloud/visualizations/simplified-exploration/profiles/ --- # Configure the Grafana Pyroscope data source @@ -73,7 +73,7 @@ To configure basic settings for the data source, complete the following steps: 1. On the **Settings** tab, complete the **Name**, **Connection**, and **Authentication** sections. - Use the **Name** field to specify the name used for the data source in panels, queries, and Explore. Toggle the **Default** switch for the data source to be pre-selected for new panels. -- Under **Connection**, enter the **URL** of the Pyroscope instance. For example, `https://example.com:4100`. +- Under **Connection**, enter the **URL** of the Pyroscope instance. For example, `https://example.com:4100`. Refer to [Connection URL](#connection-url) for more information. - Complete the [**Authentication** section](#authentication). 1. Optional: Use **Additional settings** to configure other options. @@ -89,6 +89,24 @@ To modify an existing Pyroscope data source: 1. Optional: Use **Additional settings** to configure or modify other options. 1. After completing your updates, select **Save & test**. +#### Connection URL + +The data source connection URL should point to a location of a running Pyroscope backend. + +**Grafana Cloud Profiles** + +Your Grafana Cloud instance automatically includes a fully provisioned data source. + +If you are running a self-managed Grafana instance or need to configure an additional Pyroscope data source pointing to Grafana Cloud Profiles, you can find the Pyroscope URL under the **Manage your stack** section for your organization. + +**Self-managed Pyroscope backend** + +The connection URL for a self-managed Pyroscope backend depends on how Pyroscope is deployed. +Refer to the steps under [Query profiles in Grafana](https://grafana.com/docs/pyroscope//deploy-kubernetes/helm/#query-profiles-in-grafana) for more information on how to configure the data source. + +If you plan to use the [Profiles Drilldown](ref:explore-profiles) application and you are running a self-managed Pyroscope backend in microservices mode, the data source connection URL should point to a gateway or proxy that routes requests to the corresponding Pyroscope service. +Refer to the [Helm ingress configuration](https://github.com/grafana/pyroscope/blob/main/operations/pyroscope/helm/pyroscope/templates/ingress.yaml) for specific routing requirements. + ## Authentication Use this section to select an authentication method to access the data source. diff --git a/docs/sources/datasources/pyroscope/query-profile-data.md b/docs/sources/datasources/pyroscope/query-profile-data.md index d56a629d42d..d0917ccfe12 100644 --- a/docs/sources/datasources/pyroscope/query-profile-data.md +++ b/docs/sources/datasources/pyroscope/query-profile-data.md @@ -1,5 +1,5 @@ --- -description: Explore your profiling data using Explore Profiles or the Pyroscope query editor. +description: Explore your profiling data using Profiles Drilldown or the Pyroscope query editor. keywords: - query - profiling @@ -33,7 +33,7 @@ refs: destination: /docs/grafana//explore/simplified-exploration/profiles/ - pattern: /docs/grafana-cloud/ destination: /docs/grafana-cloud/visualizations/simplified-exploration/profiles/ - explore-profile-install: + explore-profiles-install: - pattern: /docs/grafana/ destination: /docs/grafana//explore/simplified-exploration/profiles/access/ - pattern: /docs/grafana-cloud/ @@ -54,22 +54,22 @@ https://grafana.com/docs/grafana-cloud/visualizations/panels-visualizations/visu # Query profile data -You can query your profile data using the open source Grafana Explore Profiles app or the built-in Grafana Pyroscope data source query editor. +You can query your profile data using the open source Grafana Profiles Drilldown app or the built-in Grafana Pyroscope data source query editor. -- Explore Profiles provides a queryless experience for inspecting your profiling data with opinionated workflows to assist your investigation. +- Profiles Drilldown provides a queryless experience for inspecting your profiling data with opinionated workflows to assist your investigation. - Data source query editor provides complete control over your data exploration and is recommended for experienced users. In addition, you can embed flame graph panels in Grafana dashboards. Refer to the [Flame graph panel](ref:flame-graph-panel) documentation for details. -## Explore Profiles +## Profiles Drilldown -[Explore Profiles](ref:explore-profiles) is a native Grafana application designed to integrate seamlessly with Pyroscope, the open source continuous profiling platform, providing a smooth, queryless experience for browsing and analyzing profiling data. +[Grafana Profiles Drilldown](ref:explore-profiles) is a native Grafana application designed to integrate seamlessly with Pyroscope, the open source continuous profiling platform, providing a smooth, queryless experience for browsing and analyzing profiling data. -You can use Explore Profiles in Grafana Cloud or in your own Grafana instance. -For more information, refer to [Access or install Explore Profiles](ref:explore-profiles-install). +You can use Profiles Drilldown in Grafana Cloud or in your own Grafana instance. +For more information, refer to [Access or install Profiles Drilldown](ref:explore-profiles-install). -![Explore Profiles home screen](/media/docs/explore-profiles/explore-profiles-homescreen-v0.1.17.png) +![Profiles Drilldown home screen](/media/docs/explore-profiles/explore-profiles-homescreen-v0.1.17.png) ### Use cases @@ -80,10 +80,10 @@ The main use cases are the following: - Proactive: Cutting costs, addressing latency issues, or optimizing memory usage for applications - Reactive: Resolving incidents with line-level accuracy or debugging active latency/memory issues -Explore Profiles provides an intuitive interface to specifically support proactivee and reactive use cases. +Profiles Drilldown provides an intuitive interface to specifically support proactivee and reactive use cases. You get a holistic view of all of your services and how they're functioning, but also the ability to drill down for more targeted root cause analysis. -Explore Profiles offers a convenient platform to analyze profiles and get insights that are impossible to get from using other traditional signals like logs, metrics, or tracing. +Profiles Drilldown offers a convenient platform to analyze profiles and get insights that are impossible to get from using other traditional signals like logs, metrics, or tracing. {{< youtube id="x9aPw_CbIQc" >}} @@ -93,7 +93,7 @@ Explore Profiles offers a convenient platform to analyze profiles and get insigh The Pyroscope data source query editor gives you access to a profile type selector, a label selector, and collapsible options. -Like Explore Profiles, the query editor also provides a flame graph to visualize data. +Like Profiles Drilldown, the query editor also provides a flame graph to visualize data. ![Query editor](/media/docs/pyroscope/query-editor/query-editor.png 'Query editor') diff --git a/docs/sources/datasources/tempo/_index.md b/docs/sources/datasources/tempo/_index.md index 8b2123b5cd4..836db6cac14 100644 --- a/docs/sources/datasources/tempo/_index.md +++ b/docs/sources/datasources/tempo/_index.md @@ -71,7 +71,14 @@ refs: # 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//), a high-volume, minimal-dependency trace storage, open source tracing solution from Grafana Labs. + +To learn more about traces, refer to [Introduction to tracing](https://grafana.com/docs/tempo//introduction/). + +To use traces, you need you have an application or service that is instrumented to emit traces. +Refer to the [Instrument for tracing](https://grafana.com/docs/tempo//getting-started/instrumentation/) for more information. + +## Add a data source For instructions on how to add a data source to Grafana, refer to the [administration documentation](ref:data-source-management). Only users with the organization administrator role can add data sources. @@ -81,6 +88,8 @@ This video explains how to add data sources, including Loki, Tempo, and Mimir, t {{< youtube id="cqHO0oYW6Ic" start="298" >}} -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](ref:build-dashboards) and use [Explore](ref:explore). +## Learn more + +After you've added the data source, you can [configure it](./configure-tempo-data-source/) so that your Grafana instance's users can create queries in its [query editor](./query-editor/) when they [build dashboards](ref:build-dashboards) and use [Explore](ref:explore). {{< section withDescriptions="true">}} diff --git a/docs/sources/datasources/tempo/configure-tempo-data-source.md b/docs/sources/datasources/tempo/configure-tempo-data-source.md index 157238122f1..39d3cdf751a 100644 --- a/docs/sources/datasources/tempo/configure-tempo-data-source.md +++ b/docs/sources/datasources/tempo/configure-tempo-data-source.md @@ -131,7 +131,7 @@ To use streaming, you need to: - Run Tempo version 2.2 or later, or Grafana Enterprise Traces (GET) version 2.2 or later, or use Grafana Cloud Traces. - Tempo must have `stream_over_http_enabled: true` for streaming to work. - For more information, refer to [Tempo GRPC API](https://grafana.com/docs/tempo//api_docs/#tempo-grpc-api). + For more information, refer to [Tempo gRPC API](https://grafana.com/docs/tempo//api_docs/#tempo-grpc-api). - For self-managed Tempo or GET instances: If your Tempo or GET instance is behind a load balancer or proxy that doesn't supporting gRPC or HTTP2, streaming may not work and should be deactivated. @@ -333,6 +333,10 @@ You can choose one of three options: | **Duration** | _(Default)_ Displays the span duration on the span bar row. | | **Tag** | Displays the span tag on the span bar row. You must also specify which tag key to use to get the tag value, such as `component`. | +### Tag limit + +The **Tag limit** setting modifies the max number of tags and tag values to retrieve from Tempo. Default: 5000 + ### Private data source connect [//]: # 'Shared content for authentication section procedure in data sources' diff --git a/docs/sources/datasources/tempo/query-editor/_index.md b/docs/sources/datasources/tempo/query-editor/_index.md index b561a54bdcd..022364549e0 100644 --- a/docs/sources/datasources/tempo/query-editor/_index.md +++ b/docs/sources/datasources/tempo/query-editor/_index.md @@ -61,7 +61,7 @@ The queries use [TraceQL](/docs/tempo/latest/traceql), the query language design For general documentation on querying data sources in Grafana, refer to [Query and transform data](ref:query-transform-data). {{< admonition type="tip" >}} -Don't know TraceQL? Try [Explore Traces](ref:explore-traces-app), an intuitive, queryless app that lets you explore your tracing data using RED metrics. +Don't know TraceQL? Try [Grafana Traces Drilldown](ref:explore-traces-app), an intuitive, queryless app that lets you explore your tracing data using RED metrics. {{< /admonition >}} ## Before you begin @@ -97,7 +97,7 @@ The three query types are: The **Search** query builder provides drop-down lists and text fields to help you write a query. The query builder is ideal for people who aren't familiar with or want to learn TraceQL. -Refer to the [Search using the TraceQL query builder documentation]({{< relref "./traceql-search" >}}) to learn more about creating queries using convenient drop-down menus. +Refer to the [Search using the TraceQL query builder documentation](traceql-search/) to learn more about creating queries using convenient drop-down menus. ![The Search query builder](/media/docs/grafana/data-sources/tempo/query-editor/tempo-ds-query-search-v11.png) @@ -105,7 +105,7 @@ Refer to the [Search using the TraceQL query builder documentation]({{< relref " The **TraceQL** query editor lets you search by trace ID and write TraceQL queries using autocomplete. -Refer to the [TraceQL query editor documentation]({{< relref "./traceql-editor" >}}) to learn more about constructing queries using a code-editor-like experience. +Refer to the [TraceQL query editor documentation](./traceql-editor) to learn more about constructing queries using a code-editor-like experience. ![The TraceQL query editor](/media/docs/grafana/data-sources/tempo/query-editor/tempo-ds-query-traceql-v11.png) @@ -113,8 +113,8 @@ You can also search for a trace ID by entering it into the query field. ### Service graph view -Grafana’s **Service Graph** view uses metrics to display span request rates, error rates, and durations, as well as service graphs. -Once the requirements are set up, this preconfigured view is immediately available. +The **Service Graph** view uses metrics to display span request rates, error rates, and durations, as well as service graphs. +After the requirements are set up, this preconfigured view is immediately available. Using the service graph view, you can: diff --git a/docs/sources/datasources/tempo/query-editor/traceql-editor.md b/docs/sources/datasources/tempo/query-editor/traceql-editor.md index 7752a290229..cc5b38beaaa 100644 --- a/docs/sources/datasources/tempo/query-editor/traceql-editor.md +++ b/docs/sources/datasources/tempo/query-editor/traceql-editor.md @@ -12,7 +12,7 @@ labels: - oss menuTitle: Write TraceQL queries title: Write TraceQL queries with the editor -weight: 300 +weight: 400 refs: explore: - pattern: /docs/grafana/ @@ -41,4 +41,4 @@ refs: [//]: # 'Shared content for the TraceQL query editor' [//]: # 'This content is located in /docs/sources/shared/datasources/tempo-editor-traceql.md' -{{< docs/shared source="grafana" lookup="datasources/tempo-editor-traceql.md" version="" >}} +{{< docs/shared source="grafana" lookup="datasources/tempo-editor-traceql.md" version="" >}} diff --git a/docs/sources/datasources/tempo/query-editor/traceql-search.md b/docs/sources/datasources/tempo/query-editor/traceql-search.md index b885f1239d8..84ac0b396c4 100644 --- a/docs/sources/datasources/tempo/query-editor/traceql-search.md +++ b/docs/sources/datasources/tempo/query-editor/traceql-search.md @@ -56,4 +56,4 @@ To enable the TraceQL query builder in self-hosted Grafana through version 10.1, [//]: # 'Shared content for the Search - TraceQL query builder' -{{< docs/shared source="grafana" lookup="datasources/tempo-search-traceql.md" leveloffset="+1" version="" >}} +{{< docs/shared source="grafana" lookup="datasources/tempo-search-traceql.md" leveloffset="+1" version="" >}} diff --git a/docs/sources/datasources/tempo/query-editor/traceql-structure.md b/docs/sources/datasources/tempo/query-editor/traceql-structure.md new file mode 100644 index 00000000000..b67d57cedf3 --- /dev/null +++ b/docs/sources/datasources/tempo/query-editor/traceql-structure.md @@ -0,0 +1,21 @@ +--- +description: Learn how to create TraceQL queries are structured. +keywords: + - queries + - TraceQL +labels: + products: + - cloud + - enterprise + - oss +menuTitle: TraceQL query structure +title: TraceQL query structure +weight: 200 +--- + +# TraceQL query structure + +[//]: # 'Shared content for best practices for traces' +[//]: # 'This content is located in /tempo/docs/sources/shared/trace-structure.md' + +{{< docs/shared source="tempo" lookup="traceql-query-structure.md" version="" >}} diff --git a/docs/sources/datasources/tempo/service-graph.md b/docs/sources/datasources/tempo/service-graph.md index 0e6c1f8b657..59b1445f4f0 100644 --- a/docs/sources/datasources/tempo/service-graph.md +++ b/docs/sources/datasources/tempo/service-graph.md @@ -72,8 +72,8 @@ You use the Service Graph to detect performance issues; track increases in error ## Display the Service Graph -1. [Configure Grafana Alloy](https://grafana.com/docs/tempo/latest/configuration/grafana-alloy/) or [Tempo or GET](https://grafana.com/docs/tempo/latest/metrics-generator/service_graphs/#tempo) to generate Service Graph data. -1. Link a Prometheus data source in the Tempo data source's [Service Graph]({{< relref "./configure-tempo-data-source#configure-service-graph" >}}) settings. +1. [Configure Grafana Alloy](https://grafana.com/docs/tempo//configuration/grafana-alloy/) or [Tempo or GET](https://grafana.com/docs/tempo//metrics-generator/service_graphs/#tempo) to generate Service Graph data. +1. Link a Prometheus data source in the Tempo data source's [Service Graph](../configure-tempo-data-source#configure-service-graph) settings. 1. Navigate to [Explore](ref:explore). 1. Select the Tempo data source. 1. Select the **Service Graph** query type. @@ -113,10 +113,10 @@ To open the Service Graph view: 1. Run the query. 1. _(Optional)_ Filter your results. -{{% admonition type="note" %}} +{{< admonition type="note" >}} Grafana uses the `traces_spanmetrics_calls_total` metric to display the name, rate, and error rate columns, and `traces_spanmetrics_latency_bucket` to display the duration column. These metrics must exist in your Prometheus data source. -{{% /admonition %}} +{{< /admonition >}} To open a query in Prometheus with the span name of that row automatically set in the query, click a row in the **rate**, **error rate**, or **duration** columns. diff --git a/docs/sources/datasources/tempo/traces-in-grafana/_index.md b/docs/sources/datasources/tempo/traces-in-grafana/_index.md new file mode 100644 index 00000000000..c3f622bb57d --- /dev/null +++ b/docs/sources/datasources/tempo/traces-in-grafana/_index.md @@ -0,0 +1,23 @@ +--- +description: Learn about how you can use tracing data in Grafana Cloud to query data, + generate metrics, and link your tracing data with logs, metrics, and profiles. +keywords: + - Grafana + - traces + - tracing +title: Use traces in Grafana +weight: 275 +--- + +# Use traces in Grafana + +Using traces, you can search for traces, generate metrics from spans, and link your tracing data with logs, metrics, and profiles. + +This page provides a summary of how you can use tracing data in Grafana. + +For general documentation on querying data sources in Grafana, refer to [Query and transform data](https://grafana.com/docs/grafana-cloud/visualizations/panels-visualizations/query-transform-data/). + +[//]: # 'Shared content for best practices for traces' +[//]: # 'This content is located in /tempo/docs/sources/shared/tempo-in-grafana.md' + +{{< docs/shared source="tempo" lookup="tempo-in-grafana.md" version="" >}} diff --git a/docs/sources/datasources/tempo/json-trace-file.md b/docs/sources/datasources/tempo/traces-in-grafana/json-trace-file.md similarity index 82% rename from docs/sources/datasources/tempo/json-trace-file.md rename to docs/sources/datasources/tempo/traces-in-grafana/json-trace-file.md index 0387eab883a..77b45011a2f 100644 --- a/docs/sources/datasources/tempo/json-trace-file.md +++ b/docs/sources/datasources/tempo/traces-in-grafana/json-trace-file.md @@ -12,7 +12,9 @@ labels: - oss menuTitle: Upload JSON trace file title: Upload a JSON trace file -weight: 400 +weight: 900 +aliases: + - ../json-trace-file/ # /docs/grafana/latest/datasources/tempo/json-trace-file --- # Upload a JSON trace file @@ -20,7 +22,15 @@ weight: 400 You can upload a JSON file that contains a single trace and visualize it. If the file has multiple traces, Grafana visualizes the first trace. -**To download a trace or Service Graph through the inspector:** +To upload a trace file: + +1. Select **Explore** in Grafana. +1. Select **Import trace** in the right corner. +1. Upload your JSON trace file. + +## Download a trace or service graph + +To download a trace or Service Graph through the [Inspector panel](https://grafana.com/docs/grafana//explore/explore-inspector/): 1. Open the inspector. 1. Navigate to the **Data** tab. diff --git a/docs/sources/datasources/tempo/link-trace-id.md b/docs/sources/datasources/tempo/traces-in-grafana/link-trace-id.md similarity index 87% rename from docs/sources/datasources/tempo/link-trace-id.md rename to docs/sources/datasources/tempo/traces-in-grafana/link-trace-id.md index d53496e3784..6570377bbc7 100644 --- a/docs/sources/datasources/tempo/link-trace-id.md +++ b/docs/sources/datasources/tempo/traces-in-grafana/link-trace-id.md @@ -12,7 +12,10 @@ labels: - oss menuTitle: Link to a trace ID title: Link to a trace ID -weight: 700 +weight: 800 +aliases: + - ../link-trace-id/ # /docs/grafana/latest/datasources/tempo/link-trace-id/ + refs: configure-grafana-feature-toggles: - pattern: /docs/grafana/ @@ -69,10 +72,10 @@ You can link to Tempo traces from logs or metrics. You can link to Tempo traces from logs in Loki, Elasticsearch, Splunk, and other logs data sources by configuring an internal link. -To configure this feature, see the [Derived fields]({{< relref "../loki#configure-derived-fields" >}}) section of the Loki data source docs or the [Data links]({{< relref "../elasticsearch#data-links" >}}) section of the Elasticsearch or Splunk data source docs. +To configure this feature, refer to the [Derived fields](../../../loki#configure-derived-fields) section of the Loki data source docs or the [Data links](../../../elasticsearch#data-links) section of the Elasticsearch or Splunk data source docs. ## Link to a trace ID from metrics You can link to Tempo traces from metrics in Prometheus data sources by configuring an exemplar. -To configure this feature, see the [introduction to exemplars](ref:exemplars) documentation. +To configure this feature, refer to the [Exemplars](ref:exemplars) documentation. diff --git a/docs/sources/datasources/zipkin/_index.md b/docs/sources/datasources/zipkin/_index.md index 99047f46e58..e289b621819 100644 --- a/docs/sources/datasources/zipkin/_index.md +++ b/docs/sources/datasources/zipkin/_index.md @@ -339,10 +339,10 @@ To only show the spans you have matched, you can press the `Show matches only` t You can link to Zipkin traces from logs in Loki, Elasticsearch, Splunk, and other logs data sources by configuring an internal link. -To configure this feature, see the [Derived fields]({{< relref "../loki#configure-derived-fields" >}}) section of the Loki data source docs or the [Data links]({{< relref "../elasticsearch#data-links" >}}) section of the Elasticsearch or Splunk data source docs. +To configure this feature, see the [Derived fields](../loki/#configure-derived-fields) section of the Loki data source docs or the [Data links](../elasticsearch/#data-links) section of the Elasticsearch or Splunk data source docs. ## Link to a trace ID from metrics You can link to Zipkin traces from metrics in Prometheus data sources by configuring an exemplar. -To configure this feature, see the [introduction to exemplars]({{< relref "docs/grafana/latest/fundamentals/exemplars" >}}) documentation. +To configure this feature, see the [introduction to exemplars](../../fundamentals/exemplars/) documentation. diff --git a/docs/sources/developers/angular_deprecation/_index.md b/docs/sources/developers/angular_deprecation/_index.md index 7b596b88308..cdd8c172c5e 100644 --- a/docs/sources/developers/angular_deprecation/_index.md +++ b/docs/sources/developers/angular_deprecation/_index.md @@ -25,9 +25,9 @@ Warning messages are displayed if a dashboard depends on an a panel visualizatio To avoid disruption: -- Ensure that you are running the latest version of plugins by following this guide on [updating]({{< relref "../../administration/plugin-management/#update-a-plugin" >}}). Many panels and data sources have migrated from AngularJS. -- If you are using legacy Core Grafana visualizations such as Graph or Table-old, migrate to their replacements using the provided [automatic migrations]({{< relref "./angular-plugins/#automatic-migration-of-plugins" >}}). -- Review the [list of current Angular plugins]({{< relref "./angular-plugins/" >}}) to discover which Core and external plugins are impacted, and whether an update or alternative is required. +- Ensure that you are running the latest version of plugins by following this guide on [updating](../../administration/plugin-management/#update-a-plugin). Many panels and data sources have migrated from AngularJS. +- If you are using legacy Core Grafana visualizations such as Graph or Table-old, migrate to their replacements using the provided [automatic migrations](angular-plugins/#automatic-migration-of-plugins). +- Review the [list of current Angular plugins](angular-plugins/) to discover which Core and external plugins are impacted, and whether an update or alternative is required. ## Why are we deprecating Angular support? @@ -35,7 +35,7 @@ AngularJS is an old frontend framework whose active development stopped many yea ## When will Angular plugins stop working? -In Grafana 11, which will be released in preview in April 2024 and generally available in May, we will change the default behavior of the [angular_support_enabled](https://github.com/grafana/grafana/blob/d61bcdf4ca5e69489e0067c56fbe7f0bfdf84ee4/conf/defaults.ini#L362) configuration parameter to turn off support for AngularJS based plugins. In case you still rely on [AngularJS-based plugins]({{< relref "./angular-plugins/" >}}) developed internally or by the community, you will need to enable this option to continue using them. +In Grafana 11, which will be released in preview in April 2024 and generally available in May, we will change the default behavior of the [angular_support_enabled](https://github.com/grafana/grafana/blob/d61bcdf4ca5e69489e0067c56fbe7f0bfdf84ee4/conf/defaults.ini#L362) configuration parameter to turn off support for AngularJS based plugins. In case you still rely on [AngularJS-based plugins](angular-plugins/) developed internally or by the community, you will need to enable this option to continue using them. New Grafana Cloud users will be unable to request for support to be added to their instance. @@ -63,4 +63,4 @@ We encourage you to locate the repository of the corresponding plugin and create - [Migrate Angular to React](https://grafana.com/developers/plugin-tools/migration-guides/angular-react/) - [Build a panel plugin](https://grafana.com/tutorials/build-a-panel-plugin/) - [Build a data source plugin](https://grafana.com/tutorials/build-a-data-source-plugin/) -- [List of current Angular plugins]({{< relref "./angular-plugins/" >}}) +- [List of current Angular plugins](angular-plugins/) diff --git a/docs/sources/developers/angular_deprecation/angular-plugins.md b/docs/sources/developers/angular_deprecation/angular-plugins.md index d565cb5a2e1..bbb61da3c44 100644 --- a/docs/sources/developers/angular_deprecation/angular-plugins.md +++ b/docs/sources/developers/angular_deprecation/angular-plugins.md @@ -16,7 +16,7 @@ description: An annotated list of Grafana plugins using AngularJS. # Plugins using AngularJS -The use of AngularJS in Grafana has been [deprecated]({{< relref "../angular_deprecation" >}}) in favor of React. Support for AngularJS will be turned off by default in Grafana 11. +The use of AngularJS in Grafana has been [deprecated](../) in favor of React. Support for AngularJS will be turned off by default in Grafana 11. This page explains how Grafana users might be impacted by the removal of Angular support based on plugins dependent on this legacy framework. You will also see if there is a migration option available for a given plugin. @@ -30,8 +30,8 @@ Refer to the [table below](#angularjs-based-plugins) and take the appropriate ac - Consider the advice on whether to update, migrate to a listed alternative, or explore the Grafana plugins [catalog](/grafana/plugins) to find the most suitable option for your use case. - Use our [detect-angular-dashboards](https://github.com/grafana/detect-angular-dashboards) open source tooling to list dashboards which have a dependency on Angular plugins. -- Check your Grafana instances for usage of these plugins. Refer to the documentation on [browsing installed plugins]({{< relref "../../administration/plugin-management/#browse-plugins" >}}). -- Customers of Grafana Enterprise and users of Grafana Cloud can also leverage [usage insights]({{< relref "../../dashboards/assess-dashboard-usage/" >}}) to prioritize any migration efforts. +- Check your Grafana instances for usage of these plugins. Refer to the documentation on [browsing installed plugins](../../../administration/plugin-management/#browse-plugins). +- Customers of Grafana Enterprise and users of Grafana Cloud can also leverage [usage insights](../../../dashboards/assess-dashboard-usage/) to prioritize any migration efforts. - Review the plugin source repositories to add your support to any migration issues or consider forking the repo. {{% admonition type="note" %}} @@ -64,144 +64,144 @@ A dashboard must still be saved with the new plugin ID to persist the change. # AngularJS-based plugins -This table lists plugins which we have detected as having a dependency on AngularJS. For alternatives, consider included [Visualizations]({{< relref "../../panels-visualizations/visualizations" >}}) and [Data sources]({{< relref "../../datasources" >}}), as well as external plugins from the [catalog](/grafana/plugins). +This table lists plugins which we have detected as having a dependency on AngularJS. For alternatives, consider included [Visualizations](../../../panels-visualizations/visualizations/) and [Data sources](../../../datasources/), as well as external plugins from the [catalog](/grafana/plugins). -| Plugin ID | Name | Action | -| ----------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| grafana-worldmap-panel | Worldmap Panel | Migrate - [Geomap]({{< relref "../../panels-visualizations/visualizations/geomap" >}}) (core) replaced Worldmap - Note this should migrate when Angular is disabled. | -| natel-discrete-panel | Discrete | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| vonage-status-panel | Status Panel | Migrate - Consider [Stat]({{< relref "../../panels-visualizations/visualizations/stat" >}}) (core) or [Polystat](https://grafana.com/grafana/plugins/grafana-polystat-panel/) as potential alternatives. | -| grafana-simple-json-datasource | SimpleJson | Migrate - Consider [Infinity](https://grafana.com/grafana/plugins/yesoreyeram-infinity-datasource/) as a potential alternative. | -| natel-plotly-panel | Plotly | Migrate - Consider alternative [nline-plotlyjs-panel](https://grafana.com/grafana/plugins/nline-plotlyjs-panel/) plugin. | -| agenty-flowcharting-panel | FlowCharting | Migrate - Consider [Canvas]({{< relref "../../panels-visualizations/visualizations/canvas" >}}) (core) or [Diagram](https://grafana.com/grafana/plugins/jdbranham-diagram-panel/) as potential alternatives. | -| camptocamp-prometheus-alertmanager-datasource | Prometheus AlertManager | Update - Note the minimum version for React is 2.0.0. | -| briangann-gauge-panel | D3 Gauge | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| yesoreyeram-boomtable-panel | Boom Table | Migrate - Consider [Table]({{< relref "../../panels-visualizations/visualizations/table" >}}) (core) and [transformations]({{< relref "../../panels-visualizations/query-transform-data/transform-data/" >}}) as appropriate. | -| briangann-datatable-panel | Datatable Panel | Wait - New version with React migration is planned. | -| flant-statusmap-panel | Statusmap | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| michaeldmoore-multistat-panel | Multistat | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| pr0ps-trackmap-panel | TrackMap | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| snuids-trafficlights-panel | Traffic Lights | Migrate - Consider [Traffic Light](https://grafana.com/grafana/plugins/heywesty-trafficlight-panel/) as a potential alternative. | -| vertamedia-clickhouse-datasource | Altinity plugin for ClickHouse | Update - Note the minimum version for React is 3.0.0. | -| petrslavotinek-carpetplot-panel | Carpet plot | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| ryantxu-ajax-panel | AJAX | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| michaeldmoore-annunciator-panel | Annunciator | Migrate - Consider [Stat]({{< relref "../../panels-visualizations/visualizations/stat" >}}) (core). | -| marcuscalidus-svg-panel | SVG | Migrate - Consider alternatives such as [Canvas]({{< relref "../../panels-visualizations/visualizations/canvas" >}}) (core), [Colored SVG](https://grafana.com/grafana/plugins/snuids-svg-panel/), or others. | -| neocat-cal-heatmap-panel | Cal-HeatMap | Migrate - Consider [Heatmap]({{< relref "../../panels-visualizations/visualizations/heatmap" >}}) (core) visualization. | -| blackmirror1-singlestat-math-panel | Singlestat Math | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| scadavis-synoptic-panel | SCADAvis Synoptic Panel | Update - Note the minimum version for React is 2.0. | -| farski-blendstat-panel | Blendstat | Migrate - Consider [Stat]({{< relref "../../panels-visualizations/visualizations/stat" >}}) (core) and [transformations]({{< relref "../../panels-visualizations/query-transform-data/transform-data/" >}}) as appropriate. | -| savantly-heatmap-panel | Heatmap | Migrate - Consider [Heatmap]({{< relref "../../panels-visualizations/visualizations/heatmap" >}}) (core) visualization. | -| mtanda-histogram-panel | Histogram | Migrate - Consider included [Histogram]({{< relref "../../panels-visualizations/visualizations/histogram" >}}) visualization. | -| snuids-radar-panel | Radar Graph | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| fatcloud-windrose-panel | WindRose | Migrate - Consider alternative [Operator Windrose](https://grafana.com/grafana/plugins/operato-windrose-panel/) plugin. | -| bessler-pictureit-panel | PictureIt | Migrate - Consider alternative [ePict](https://grafana.com/grafana/plugins/larona-epict-panel/) plugin. | -| digrich-bubblechart-panel | Bubble Chart | Update - Note the minimum version for React is 2.0.1. We recommend the latest. | -| corpglory-progresslist-panel | Progress List | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| aidanmountford-html-panel | HTML | Migrate - Consider alternatives such as [Text]({{< relref "../../panels-visualizations/visualizations/text" >}}) (core), [HTML](https://grafana.com/grafana/plugins/gapit-htmlgraphics-panel), or others. | -| fifemon-graphql-datasource | GraphQL Data Source | Wait - Removal of AngularJS is planned. Consider [Infinity](https://grafana.com/grafana/plugins/yesoreyeram-infinity-datasource/) plugin as alternative. | -| goshposh-metaqueries-datasource | MetaQueries | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| mxswat-separator-panel | Separator | Migrate - Consider alternative [Text]({{< relref "../../panels-visualizations/visualizations/text" >}}) panel (core) which can be empty and used as a separator. | -| natel-influx-admin-panel | Influx Admin | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| doitintl-bigquery-datasource | Google BigQuery | Migrate - Consider [Grafana Big Query](https://grafana.com/grafana/plugins/grafana-bigquery-datasource/) plugin. | -| satellogic-3d-globe-panel | 3D Globe Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| foursquare-clouderamanager-datasource | Cloudera Manager | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| grafana-splunk-datasource | Splunk | Update - Note the minimum version for React is 4.1.0. We recommend the latest. | -| grafana-singlestat-panel | Singlestat | Migrate - Consider [Stat]({{< relref "../../panels-visualizations/visualizations/stat" >}}) panel (core). | -| blackmirror1-statusbygroup-panel | Status By Group Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| novalabs-annotations-panel | Annotation Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| jasonlashua-prtg-datasource | PRTG | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| ryantxu-annolist-panel | Annotation List | Migrate - Consider [annotations list]({{< relref "../../panels-visualizations/visualizations/annotations" >}}) (core). | -| cloudflare-app | Cloudflare Grafana App | Migrate - Consider using the [Cloudflare Dashboard](https://dash.cloudflare.com/?to=/:account/:zone/analytics/dns) or [DNS Analytics API](https://developers.cloudflare.com/api/operations/dns-analytics-table). | -| smartmakers-trafficlight-panel | TrafficLight | Migrate - Consider [Traffic Light](https://grafana.com/grafana/plugins/heywesty-trafficlight-panel/) as a potential alternative. | -| zuburqan-parity-report-panel | Parity Report | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| citilogics-geoloop-panel | GeoLoop | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| xginn8-pagerduty-datasource | Pagerduty | Wait - We are developing an Enterprise plugin for Pagerduty targeted for availability in Q1 2024. Note that all roadmap items are subject to change. | -| gretamosa-topology-panel | Topology Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| fzakaria-simple-annotations-datasource | Simple Annotations | Migrate - Check for annotations support within your data sources to remove dependency on this plugin. | -| oci-metrics-datasource | Oracle Cloud Infrastructure Metrics | Update - Note the minimum version for React is 5.0.0. | -| abhisant-druid-datasource | Druid | Migrate - Migrate to replacement [Druid](https://grafana.com/grafana/plugins/grafadruid-druid-datasource/) plugin. | -| devopsprodigy-kubegraf-app | DevOpsProdigy KubeGraf | Migrate - Consider [Grafana Kubernetes Monitoring](https://grafana.com/solutions/kubernetes/) (Grafana Cloud only). | -| mtanda-heatmap-epoch-panel | HeatmapEpoch | Migrate - Consider [Heatmap]({{< relref "../../panels-visualizations/visualizations/heatmap" >}}) (core) visualization. | -| alexandra-trackmap-panel | Track Map | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| gnocchixyz-gnocchi-datasource | Gnocchi | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| tencentcloud-monitor-app | Tencent Cloud Monitor | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| andig-darksky-datasource | DarkSky | Remove - Note that support for the DarkSky API was ended by Apple in March 2023. | -| mtanda-google-calendar-datasource | GoogleCalendar | Wait - Migration to React is planned. | -| ntop-ntopng-datasource | ntopng | Migrate - Consider [InfluxDB]({{< relref "../../datasources/influxdb/" >}}) (core), with additional guidance available [here](https://www.ntop.org/guides/ntopng/basic_concepts/timeseries.html#influxdb-driver). | -| ayoungprogrammer-finance-datasource | Finance | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| grafana-kairosdb-datasource | KairosDB | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| fastweb-openfalcon-datasource | Open-Falcon | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| praj-ams-datasource | Ambari Metrics | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| monasca-datasource | Monasca | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| grafana-strava-datasource | Strava | Update - Note the minimum version for React is 1.6.0. We recommend the latest. | -| gridprotectionalliance-osisoftpi-datasource | OSIsoft-PI | Update - Note the minimum version for React is 4.0.0. We recommend the latest. | -| monitoringartist-monitoringart-datasource | Monitoring Art | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | -| hawkular-datasource | Hawkular | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| ovh-warp10-datasource | Warp 10 | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| natel-usgs-datasource | USGS Water Services | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| radensolutions-netxms-datasource | NetXMS | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| ibm-apm-datasource | IBM APM | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| cognitedata-datasource | Cognite Data Fusion | Update - Note the minimum version for React is 4.0.0. We recommend the latest. | -| linksmart-sensorthings-datasource | LinkSmart SensorThings | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| pue-solr-datasource | Solr | Migrate - Consider this [guidance](https://solr.apache.org/guide/solr/latest/deployment-guide/monitoring-with-prometheus-and-grafana.html) on using solr-exporter for prometheus. | -| paytm-kapacitor-datasource | KapacitorSimpleJson | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| oci-logs-datasource | Oracle Cloud Infrastructure Logs | Update - Note the minimum version for React is 4.0.0. | -| gridprotectionalliance-openhistorian-datasource | openHistorian | Wait - Note that new version with React migration is planned. | -| devicehive-devicehive-datasource | DeviceHive | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| rackerlabs-blueflood-datasource | Blueflood | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| udoprog-heroic-datasource | Heroic | Migrate - Note that Heroic DB has been discontinued. | -| akumuli-datasource | Akumuli | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| bmchelix-ade-datasource | BMC Helix | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| sidewinder-datasource | Sidewinder | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| linksmart-hds-datasource | LinkSmart HDS Datasource | Migrate - browse included data sources and plugins catalog for potential alternatives. | -| skydive-datasource | Skydive | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| quasardb-datasource | QuasarDB | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| spotify-heroic-datasource | Heroic | Migrate - Note that Heroic DB has been discontinued. | -| grafana-es-open-distro-datasource | Open Distro for Elasticsearch | Migrate - Note that [OpenSearch](https://grafana.com/grafana/plugins/grafana-opensearch-datasource/) replaced Open Distro for Elasticseach. | -| humio-datasource | Humio | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| yeya24-chaosmesh-datasource | Chaos Mesh | Migrate - Note that plugin was replaced by [chaosmeshorg-datasource](https://grafana.com/grafana/plugins/chaosmeshorg-datasource/). | -| kentik-connect-app | Kentik Connect Pro | Update - Note the minimum version for React is 1.7.0. | -| chaosmeshorg-datasource | Chaos Mesh | Update - Note the minimum version for React is 3.0.0. | -| aquaqanalytics-kdbadaptor-datasource | kdb+ | Migrate - Note that [kdb+ backend](https://grafana.com/grafana/plugins/aquaqanalytics-kdbbackend-datasource) replaced kdb.+. | -| alexanderzobnin-zabbix-app | Zabbix | Update - Note the minimum version for React is 4.3.0. We recommend the latest. Recently brought under Grafana signature. | -| bosun-app | Bosun | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| belugacdn-app | BelugaCDN | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| grafana-azure-data-explorer-datasource | Azure Data Explorer Datasource | Update - The minimum supported version is 3.5.1. We recommend the latest. | -| ddurieux-glpi-app | glpi | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| fetzerch-sunandmoon-datasource | Sun and Moon | Update - Note the minimum version for React is 0.3.0. | -| grafana-clock-panel | Clock | Update - Note the minimum version for React is 1.1.0. We recommend the latest. | -| grafana-github-datasource | GitHub | Update - Note the minimum version for React is 1.3.3. We recommend the latest. | -| grafana-datadog-datasource | Datadog | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | -| grafana-gitlab-datasource | Gitlab | Update - Note the minimum version for React is 1.1.0. We recommend the latest. | -| grafana-iot-twinmaker-app | AWS IoT TwinMaker App | Update - Note the minimum version for React is 1.6.3. We recommend the latest. | -| grafana-newrelic-datasource | New Relic | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | -| grafana-opensearch-datasource | Opensearch | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| grafana-oracle-datasource | Oracle | Update - Note the minimum version for React is 2.0.6. We recommend the latest. | -| grafana-piechart-panel | Pie Chart | Migrate - Note that [Pie Chart]({{< relref "../../panels-visualizations/visualizations/pie-chart" >}}) (core) replaced Pie Chart. | -| grafana-polystat-panel | Polystat | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| grafana-servicenow-datasource | ServiceNow | Update - Note the minimum version for React is 2.0.2. We recommend the latest. | -| grafana-synthetic-monitoring-app | Synthetic Monitoring | Update - Note the minimum version for React is 0.7.3. We recommend the latest. | -| grafana-wavefront-datasource | Wavefront | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| hadesarchitect-cassandra-datasource | Apache Cassandra | Update - Note the minimum version for React is 2.1.1. We recommend the latest. | -| instana-datasource | Instana | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | -| jdbranham-diagram-panel | Diagram | Update - Note the minimum version for React is 1.7.1. We recommend the latest. | -| larona-epict-panel | ePict | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| moogsoft-aiops-app | Moogsoft AIOps | Update - Note the minimum version for React is 9.0.0. | -| opennms-helm-app | OpenNMS Helm | Migrate - Note that [OpenNMS Plugin for Grafana](https://grafana.com/grafana/plugins/opennms-opennms-app/) replaced OpenNMS Helm. | -| percona-percona-app | Percona | Migrate - Consider use of [Percona dashboards](https://github.com/percona/grafana-dashboards/). | -| novatec-sdg-panel | Service Dependency Graph | Update - Note the minimum version for React is 4.0.3. | -| pierosavi-imageit-panel | ImageIt | Migrate - Consider [ePict](https://grafana.com/grafana/plugins/larona-epict-panel/) or browse plugins catalog for potential alternatives. | -| redis-app | Redis Application | Update - Note the minimum version for React is 1.2.0. We recommend the latest. | -| sbueringer-consul-datasource | Consul | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| simpod-json-datasource | JSON | Update - Note the minimum version for React is 0.3.0. We recommend the latest. | -| singlestat | Singlestat | Migrate - Note that [Stat]({{< relref "../../panels-visualizations/visualizations/stat" >}}) (core) replaced Singlestat. | -| sni-pnp-datasource | PNP | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| sni-thruk-datasource | Thruk | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| stagemonitor-elasticsearch-app | stagemonitor Elasticsearch | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| tdengine-datasource | TDengine Datasource | Update - Note the minimum version for React is 3.3.0. We recommend the latest. | -| vertica-grafana-datasource | Vertica | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | -| voxter-app | Voxter VoIP Platform Metrics | Migrate - Browse included data sources and plugins catalog for potential alternatives. | -| graph | Graph (old) | Migrate - Note that this is replaced by [Time Series]({{< relref "../../panels-visualizations/visualizations/time-series" >}}) (core) - This plugin should migrate when Angular is disabled. Also consider Bar Chart or Histogram if appropriate. | -| table-old | Table (old) | Migrate - Note that this is replaced by [Table]({{< relref "../../panels-visualizations/visualizations/table" >}}) (core) - This plugin should migrate when AngularJS is disabled. | -| shorelinesoftware-shoreline-datasource | Shoreline Data Source | Update - Note the minimum version for React is 1.2.1. We recommend the latest. | +| Plugin ID | Name | Action | +| ----------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| grafana-worldmap-panel | Worldmap Panel | Migrate - [Geomap](../../../panels-visualizations/visualizations/geomap/) (core) replaced Worldmap - Note this should migrate when Angular is disabled. | +| natel-discrete-panel | Discrete | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| vonage-status-panel | Status Panel | Migrate - Consider [Stat](../../../panels-visualizations/visualizations/stat/) (core) or [Polystat](https://grafana.com/grafana/plugins/grafana-polystat-panel/) as potential alternatives. | +| grafana-simple-json-datasource | SimpleJson | Migrate - Consider [Infinity](https://grafana.com/grafana/plugins/yesoreyeram-infinity-datasource/) as a potential alternative. | +| natel-plotly-panel | Plotly | Migrate - Consider alternative [nline-plotlyjs-panel](https://grafana.com/grafana/plugins/nline-plotlyjs-panel/) plugin. | +| agenty-flowcharting-panel | FlowCharting | Migrate - Consider [Canvas](../../../panels-visualizations/visualizations/canvas/) (core) or [Diagram](https://grafana.com/grafana/plugins/jdbranham-diagram-panel/) as potential alternatives. | +| camptocamp-prometheus-alertmanager-datasource | Prometheus AlertManager | Update - Note the minimum version for React is 2.0.0. | +| briangann-gauge-panel | D3 Gauge | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| yesoreyeram-boomtable-panel | Boom Table | Migrate - Consider [Table](../../../panels-visualizations/visualizations/table/) (core) and [transformations](../../../panels-visualizations/query-transform-data/transform-data/) as appropriate. | +| briangann-datatable-panel | Datatable Panel | Wait - New version with React migration is planned. | +| flant-statusmap-panel | Statusmap | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| michaeldmoore-multistat-panel | Multistat | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| pr0ps-trackmap-panel | TrackMap | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| snuids-trafficlights-panel | Traffic Lights | Migrate - Consider [Traffic Light](https://grafana.com/grafana/plugins/heywesty-trafficlight-panel/) as a potential alternative. | +| vertamedia-clickhouse-datasource | Altinity plugin for ClickHouse | Update - Note the minimum version for React is 3.0.0. | +| petrslavotinek-carpetplot-panel | Carpet plot | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| ryantxu-ajax-panel | AJAX | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| michaeldmoore-annunciator-panel | Annunciator | Migrate - Consider [Stat](../../../panels-visualizations/visualizations/stat/) (core). | +| marcuscalidus-svg-panel | SVG | Migrate - Consider alternatives such as [Canvas](../../../panels-visualizations/visualizations/canvas/) (core), [Colored SVG](https://grafana.com/grafana/plugins/snuids-svg-panel/), or others. | +| neocat-cal-heatmap-panel | Cal-HeatMap | Migrate - Consider [Heatmap](../../../panels-visualizations/visualizations/heatmap/) (core) visualization. | +| blackmirror1-singlestat-math-panel | Singlestat Math | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| scadavis-synoptic-panel | SCADAvis Synoptic Panel | Update - Note the minimum version for React is 2.0. | +| farski-blendstat-panel | Blendstat | Migrate - Consider [Stat](../../../panels-visualizations/visualizations/stat/) (core) and [transformations](../../../panels-visualizations/query-transform-data/transform-data/) as appropriate. | +| savantly-heatmap-panel | Heatmap | Migrate - Consider [Heatmap](../../../panels-visualizations/visualizations/heatmap/) (core) visualization. | +| mtanda-histogram-panel | Histogram | Migrate - Consider included [Histogram](../../../panels-visualizations/visualizations/histogram/) visualization. | +| snuids-radar-panel | Radar Graph | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| fatcloud-windrose-panel | WindRose | Migrate - Consider alternative [Operator Windrose](https://grafana.com/grafana/plugins/operato-windrose-panel/) plugin. | +| bessler-pictureit-panel | PictureIt | Migrate - Consider alternative [ePict](https://grafana.com/grafana/plugins/larona-epict-panel/) plugin. | +| digrich-bubblechart-panel | Bubble Chart | Update - Note the minimum version for React is 2.0.1. We recommend the latest. | +| corpglory-progresslist-panel | Progress List | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| aidanmountford-html-panel | HTML | Migrate - Consider alternatives such as [Text](../../../panels-visualizations/visualizations/text/) (core), [HTML](https://grafana.com/grafana/plugins/gapit-htmlgraphics-panel), or others. | +| fifemon-graphql-datasource | GraphQL Data Source | Wait - Removal of AngularJS is planned. Consider [Infinity](https://grafana.com/grafana/plugins/yesoreyeram-infinity-datasource/) plugin as alternative. | +| goshposh-metaqueries-datasource | MetaQueries | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| mxswat-separator-panel | Separator | Migrate - Consider alternative [Text](../../../panels-visualizations/visualizations/text/) panel (core) which can be empty and used as a separator. | +| natel-influx-admin-panel | Influx Admin | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| doitintl-bigquery-datasource | Google BigQuery | Migrate - Consider [Grafana Big Query](https://grafana.com/grafana/plugins/grafana-bigquery-datasource/) plugin. | +| satellogic-3d-globe-panel | 3D Globe Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| foursquare-clouderamanager-datasource | Cloudera Manager | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| grafana-splunk-datasource | Splunk | Update - Note the minimum version for React is 4.1.0. We recommend the latest. | +| grafana-singlestat-panel | Singlestat | Migrate - Consider [Stat](../../../panels-visualizations/visualizations/stat/) panel (core). | +| blackmirror1-statusbygroup-panel | Status By Group Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| novalabs-annotations-panel | Annotation Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| jasonlashua-prtg-datasource | PRTG | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| ryantxu-annolist-panel | Annotation List | Migrate - Consider [annotations list](../../../panels-visualizations/visualizations/annotations/) (core). | +| cloudflare-app | Cloudflare Grafana App | Migrate - Consider using the [Cloudflare Dashboard](https://dash.cloudflare.com/?to=/:account/:zone/analytics/dns) or [DNS Analytics API](https://developers.cloudflare.com/api/operations/dns-analytics-table). | +| smartmakers-trafficlight-panel | TrafficLight | Migrate - Consider [Traffic Light](https://grafana.com/grafana/plugins/heywesty-trafficlight-panel/) as a potential alternative. | +| zuburqan-parity-report-panel | Parity Report | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| citilogics-geoloop-panel | GeoLoop | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| xginn8-pagerduty-datasource | Pagerduty | Wait - We are developing an Enterprise plugin for Pagerduty targeted for availability in Q1 2024. Note that all roadmap items are subject to change. | +| gretamosa-topology-panel | Topology Panel | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| fzakaria-simple-annotations-datasource | Simple Annotations | Migrate - Check for annotations support within your data sources to remove dependency on this plugin. | +| oci-metrics-datasource | Oracle Cloud Infrastructure Metrics | Update - Note the minimum version for React is 5.0.0. | +| abhisant-druid-datasource | Druid | Migrate - Migrate to replacement [Druid](https://grafana.com/grafana/plugins/grafadruid-druid-datasource/) plugin. | +| devopsprodigy-kubegraf-app | DevOpsProdigy KubeGraf | Migrate - Consider [Grafana Kubernetes Monitoring](https://grafana.com/solutions/kubernetes/) (Grafana Cloud only). | +| mtanda-heatmap-epoch-panel | HeatmapEpoch | Migrate - Consider [Heatmap](../../../panels-visualizations/visualizations/heatmap/) (core) visualization. | +| alexandra-trackmap-panel | Track Map | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| gnocchixyz-gnocchi-datasource | Gnocchi | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| tencentcloud-monitor-app | Tencent Cloud Monitor | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| andig-darksky-datasource | DarkSky | Remove - Note that support for the DarkSky API was ended by Apple in March 2023. | +| mtanda-google-calendar-datasource | GoogleCalendar | Wait - Migration to React is planned. | +| ntop-ntopng-datasource | ntopng | Migrate - Consider [InfluxDB](../../../datasources/influxdb/) (core), with additional guidance available [here](https://www.ntop.org/guides/ntopng/basic_concepts/timeseries.html#influxdb-driver). | +| ayoungprogrammer-finance-datasource | Finance | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| grafana-kairosdb-datasource | KairosDB | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| fastweb-openfalcon-datasource | Open-Falcon | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| praj-ams-datasource | Ambari Metrics | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| monasca-datasource | Monasca | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| grafana-strava-datasource | Strava | Update - Note the minimum version for React is 1.6.0. We recommend the latest. | +| gridprotectionalliance-osisoftpi-datasource | OSIsoft-PI | Update - Note the minimum version for React is 4.0.0. We recommend the latest. | +| monitoringartist-monitoringart-datasource | Monitoring Art | Migrate - Browse included visualizations and plugins catalog for potential alternatives. | +| hawkular-datasource | Hawkular | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| ovh-warp10-datasource | Warp 10 | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| natel-usgs-datasource | USGS Water Services | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| radensolutions-netxms-datasource | NetXMS | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| ibm-apm-datasource | IBM APM | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| cognitedata-datasource | Cognite Data Fusion | Update - Note the minimum version for React is 4.0.0. We recommend the latest. | +| linksmart-sensorthings-datasource | LinkSmart SensorThings | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| pue-solr-datasource | Solr | Migrate - Consider this [guidance](https://solr.apache.org/guide/solr/latest/deployment-guide/monitoring-with-prometheus-and-grafana.html) on using solr-exporter for prometheus. | +| paytm-kapacitor-datasource | KapacitorSimpleJson | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| oci-logs-datasource | Oracle Cloud Infrastructure Logs | Update - Note the minimum version for React is 4.0.0. | +| gridprotectionalliance-openhistorian-datasource | openHistorian | Wait - Note that new version with React migration is planned. | +| devicehive-devicehive-datasource | DeviceHive | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| rackerlabs-blueflood-datasource | Blueflood | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| udoprog-heroic-datasource | Heroic | Migrate - Note that Heroic DB has been discontinued. | +| akumuli-datasource | Akumuli | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| bmchelix-ade-datasource | BMC Helix | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| sidewinder-datasource | Sidewinder | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| linksmart-hds-datasource | LinkSmart HDS Datasource | Migrate - browse included data sources and plugins catalog for potential alternatives. | +| skydive-datasource | Skydive | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| quasardb-datasource | QuasarDB | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| spotify-heroic-datasource | Heroic | Migrate - Note that Heroic DB has been discontinued. | +| grafana-es-open-distro-datasource | Open Distro for Elasticsearch | Migrate - Note that [OpenSearch](https://grafana.com/grafana/plugins/grafana-opensearch-datasource/) replaced Open Distro for Elasticseach. | +| humio-datasource | Humio | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| yeya24-chaosmesh-datasource | Chaos Mesh | Migrate - Note that plugin was replaced by [chaosmeshorg-datasource](https://grafana.com/grafana/plugins/chaosmeshorg-datasource/). | +| kentik-connect-app | Kentik Connect Pro | Update - Note the minimum version for React is 1.7.0. | +| chaosmeshorg-datasource | Chaos Mesh | Update - Note the minimum version for React is 3.0.0. | +| aquaqanalytics-kdbadaptor-datasource | kdb+ | Migrate - Note that [kdb+ backend](https://grafana.com/grafana/plugins/aquaqanalytics-kdbbackend-datasource) replaced kdb.+. | +| alexanderzobnin-zabbix-app | Zabbix | Update - Note the minimum version for React is 4.3.0. We recommend the latest. Recently brought under Grafana signature. | +| bosun-app | Bosun | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| belugacdn-app | BelugaCDN | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| grafana-azure-data-explorer-datasource | Azure Data Explorer Datasource | Update - The minimum supported version is 3.5.1. We recommend the latest. | +| ddurieux-glpi-app | glpi | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| fetzerch-sunandmoon-datasource | Sun and Moon | Update - Note the minimum version for React is 0.3.0. | +| grafana-clock-panel | Clock | Update - Note the minimum version for React is 1.1.0. We recommend the latest. | +| grafana-github-datasource | GitHub | Update - Note the minimum version for React is 1.3.3. We recommend the latest. | +| grafana-datadog-datasource | Datadog | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | +| grafana-gitlab-datasource | Gitlab | Update - Note the minimum version for React is 1.1.0. We recommend the latest. | +| grafana-iot-twinmaker-app | AWS IoT TwinMaker App | Update - Note the minimum version for React is 1.6.3. We recommend the latest. | +| grafana-newrelic-datasource | New Relic | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | +| grafana-opensearch-datasource | Opensearch | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| grafana-oracle-datasource | Oracle | Update - Note the minimum version for React is 2.0.6. We recommend the latest. | +| grafana-piechart-panel | Pie Chart | Migrate - Note that [Pie Chart](../../../panels-visualizations/visualizations/pie-chart/) (core) replaced Pie Chart. | +| grafana-polystat-panel | Polystat | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| grafana-servicenow-datasource | ServiceNow | Update - Note the minimum version for React is 2.0.2. We recommend the latest. | +| grafana-synthetic-monitoring-app | Synthetic Monitoring | Update - Note the minimum version for React is 0.7.3. We recommend the latest. | +| grafana-wavefront-datasource | Wavefront | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| hadesarchitect-cassandra-datasource | Apache Cassandra | Update - Note the minimum version for React is 2.1.1. We recommend the latest. | +| instana-datasource | Instana | Update - Note the minimum version for React is 3.0.0. We recommend the latest. | +| jdbranham-diagram-panel | Diagram | Update - Note the minimum version for React is 1.7.1. We recommend the latest. | +| larona-epict-panel | ePict | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| moogsoft-aiops-app | Moogsoft AIOps | Update - Note the minimum version for React is 9.0.0. | +| opennms-helm-app | OpenNMS Helm | Migrate - Note that [OpenNMS Plugin for Grafana](https://grafana.com/grafana/plugins/opennms-opennms-app/) replaced OpenNMS Helm. | +| percona-percona-app | Percona | Migrate - Consider use of [Percona dashboards](https://github.com/percona/grafana-dashboards/). | +| novatec-sdg-panel | Service Dependency Graph | Update - Note the minimum version for React is 4.0.3. | +| pierosavi-imageit-panel | ImageIt | Migrate - Consider [ePict](https://grafana.com/grafana/plugins/larona-epict-panel/) or browse plugins catalog for potential alternatives. | +| redis-app | Redis Application | Update - Note the minimum version for React is 1.2.0. We recommend the latest. | +| sbueringer-consul-datasource | Consul | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| simpod-json-datasource | JSON | Update - Note the minimum version for React is 0.3.0. We recommend the latest. | +| singlestat | Singlestat | Migrate - Note that [Stat](../../../panels-visualizations/visualizations/stat/) (core) replaced Singlestat. | +| sni-pnp-datasource | PNP | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| sni-thruk-datasource | Thruk | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| stagemonitor-elasticsearch-app | stagemonitor Elasticsearch | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| tdengine-datasource | TDengine Datasource | Update - Note the minimum version for React is 3.3.0. We recommend the latest. | +| vertica-grafana-datasource | Vertica | Update - Note the minimum version for React is 2.0.0. We recommend the latest. | +| voxter-app | Voxter VoIP Platform Metrics | Migrate - Browse included data sources and plugins catalog for potential alternatives. | +| graph | Graph (old) | Migrate - Note that this is replaced by [Time Series](../../../panels-visualizations/visualizations/time-series/) (core) - This plugin should migrate when Angular is disabled. Also consider Bar Chart or Histogram if appropriate. | +| table-old | Table (old) | Migrate - Note that this is replaced by [Table](../../../panels-visualizations/visualizations/table/) (core) - This plugin should migrate when AngularJS is disabled. | +| shorelinesoftware-shoreline-datasource | Shoreline Data Source | Update - Note the minimum version for React is 1.2.1. We recommend the latest. | diff --git a/docs/sources/developers/http_api/_index.md b/docs/sources/developers/http_api/_index.md index 13f1ca5aac9..8889f1670c1 100644 --- a/docs/sources/developers/http_api/_index.md +++ b/docs/sources/developers/http_api/_index.md @@ -49,44 +49,44 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk ## HTTP APIs -- [Admin API]({{< relref "admin/" >}}) +- [Admin API](admin/) - [Alerting API (unstable)](https://editor.swagger.io/?url=https://raw.githubusercontent.com/grafana/grafana/main/pkg/services/ngalert/api/tooling/post.json) -- [Alerting provisioning API]({{< relref "alerting_provisioning/" >}}) -- [Annotations API]({{< relref "annotations/" >}}) -- [Correlations API]({{< relref "correlations/" >}}) -- [Dashboard API]({{< relref "dashboard/" >}}) -- [Dashboard permissions API]({{< relref "dashboard_permissions/" >}}) -- [Dashboard versions API]({{< relref "dashboard_versions/" >}}) -- [Data source API]({{< relref "data_source/" >}}) -- [Folder API]({{< relref "folder/" >}}) -- [Folder permissions API]({{< relref "folder_permissions/" >}}) -- [Folder/Dashboard search API]({{< relref "folder_dashboard_search/" >}}) -- [Library element API]({{< relref "library_element/" >}}) -- [Organization API]({{< relref "org/" >}}) -- [Other API]({{< relref "other/" >}}) -- [Playlists API]({{< relref "playlist/" >}}) -- [Preferences API]({{< relref "preferences/" >}}) -- [Shared dashboards API]({{< relref "dashboard_public/" >}}) -- [Query history API]({{< relref "query_history/" >}}) -- [Service account API]({{< relref "serviceaccount/" >}}) -- [Short URL API]({{< relref "short_url/" >}}) -- [Snapshot API]({{< relref "snapshot/" >}}) -- [SSO settings API]({{< relref "sso-settings/" >}}) -- [Team API]({{< relref "team/" >}}) -- [User API]({{< relref "user/" >}}) +- [Alerting provisioning API](alerting_provisioning/) +- [Annotations API](annotations/) +- [Correlations API](correlations/) +- [Dashboard API](dashboard/) +- [Dashboard permissions API](dashboard_permissions/) +- [Dashboard versions API](dashboard_versions/) +- [Data source API](data_source/) +- [Folder API](folder/) +- [Folder permissions API](folder_permissions/) +- [Folder/Dashboard search API](folder_dashboard_search/) +- [Library element API](library_element/) +- [Organization API](org/) +- [Other API](other/) +- [Playlists API](playlist/) +- [Preferences API](preferences/) +- [Shared dashboards API](dashboard_public/) +- [Query history API](query_history/) +- [Service account API](serviceaccount/) +- [Short URL API](short_url/) +- [Snapshot API](snapshot/) +- [SSO settings API](sso-settings/) +- [Team API](team/) +- [User API](user/) ## Deprecated HTTP APIs -- [Authentication API]({{< relref "auth/" >}}) +- [Authentication API](auth/) ## Grafana Enterprise HTTP APIs Grafana Enterprise includes all of the Grafana OSS APIs as well as the following APIs: -- [Data source permissions API]({{< relref "datasource_permissions/" >}}) -- [Group attribute sync API]({{< relref "group_attribute_sync/" >}}) -- [License API]({{< relref "licensing/" >}}) -- [Query and resource caching API]({{< relref "query_and_resource_caching/" >}}) -- [Reporting API]({{< relref "reporting/" >}}) -- [Role-based access control API]({{< relref "access_control/" >}}) -- [Team sync API]({{< relref "team_sync/" >}}) +- [Data source permissions API](datasource_permissions/) +- [Group attribute sync API](group_attribute_sync/) +- [License API](licensing/) +- [Query and resource caching API](query_and_resource_caching/) +- [Reporting API](reporting/) +- [Role-based access control API](access_control/) +- [Team sync API](team_sync/) diff --git a/docs/sources/developers/http_api/access_control.md b/docs/sources/developers/http_api/access_control.md index ecd0ac62d52..e4d0dc2d5a3 100644 --- a/docs/sources/developers/http_api/access_control.md +++ b/docs/sources/developers/http_api/access_control.md @@ -21,11 +21,11 @@ title: RBAC HTTP API # RBAC API -> Role-based access control API is only available in Grafana Cloud or Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}). +> Role-based access control API is only available in Grafana Cloud or Grafana Enterprise. Read more about [Grafana Enterprise](/docs/grafana/latest/introduction/grafana-enterprise/). The API can be used to create, update, delete, get, and list roles. -To check which basic or fixed roles have the required permissions, refer to [RBAC role definitions]({{< ref "/docs/grafana/latest/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions" >}}). +To check which basic or fixed roles have the required permissions, refer to [RBAC role definitions](/docs/grafana/latest/administration/roles-and-permissions/access-control/rbac-fixed-basic-role-definitions). ## Get status @@ -226,7 +226,7 @@ Content-Type: application/json; charset=UTF-8 `POST /api/access-control/roles` -Creates a new custom role and maps given permissions to that role. Note that roles with the same prefix as [Fixed roles]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control#fixed-roles" >}}) can't be created. +Creates a new custom role and maps given permissions to that role. Note that roles with the same prefix as [Fixed roles](/docs/grafana/latest/administration/roles-and-permissions/access-control/#fixed-roles) can't be created. #### Required permissions @@ -264,24 +264,24 @@ Content-Type: application/json #### JSON body schema -| Field Name | Date Type | Required | Description | -| ----------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| uid | string | No | UID of the role. If not present, the UID will be automatically created for you and returned in response. Refer to the [Custom roles]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control#custom-roles" >}}) for more information. | -| global | boolean | No | A flag indicating if the role is global or not. If set to `false`, the default org ID of the authenticated user will be used from the request. | -| version | number | No | Version of the role. If not present, version 0 will be assigned to the role and returned in the response. Refer to the [Custom roles]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/#custom-roles" >}}) for more information. | -| name | string | Yes | Name of the role. Refer to [Custom roles]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control#custom-roles" >}}) for more information. | -| description | string | No | Description of the role. | -| displayName | string | No | Display name of the role, visible in the UI. | -| group | string | No | The group name the role belongs to. | -| hidden | boolean | No | Specify whether the role is hidden or not. If set to `true`, then the role does not show in the role picker. It will not be listed by API endpoints unless explicitly specified. | -| permissions | Permission | No | If not present, the role will be created without any permissions. | +| Field Name | Date Type | Required | Description | +| ----------- | ---------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| uid | string | No | UID of the role. If not present, the UID will be automatically created for you and returned in response. Refer to the [Custom roles](/docs/grafana/latest/administration/roles-and-permissions/access-control/#custom-roles) for more information. | +| global | boolean | No | A flag indicating if the role is global or not. If set to `false`, the default org ID of the authenticated user will be used from the request. | +| version | number | No | Version of the role. If not present, version 0 will be assigned to the role and returned in the response. Refer to the [Custom roles](/docs/grafana/latest/administration/roles-and-permissions/access-control/#custom-roles) for more information. | +| name | string | Yes | Name of the role. Refer to [Custom roles](/docs/grafana/latest/administration/roles-and-permissions/access-control/#custom-roles) for more information. | +| description | string | No | Description of the role. | +| displayName | string | No | Display name of the role, visible in the UI. | +| group | string | No | The group name the role belongs to. | +| hidden | boolean | No | Specify whether the role is hidden or not. If set to `true`, then the role does not show in the role picker. It will not be listed by API endpoints unless explicitly specified. | +| permissions | Permission | No | If not present, the role will be created without any permissions. | **Permission** -| Field Name | Data Type | Required | Description | -| ---------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| action | string | Yes | Refer to [Custom role actions and scopes]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for full list of available actions. | -| scope | string | No | If not present, no scope will be mapped to the permission. Refer to [Custom role actions and scopes]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for full list of available scopes. | +| Field Name | Data Type | Required | Description | +| ---------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| action | string | Yes | Refer to [Custom role actions and scopes](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for full list of available actions. | +| scope | string | No | If not present, no scope will be mapped to the permission. Refer to [Custom role actions and scopes](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for full list of available scopes. | #### Example response @@ -449,10 +449,10 @@ Content-Type: application/json **Permission** -| Field Name | Data Type | Required | Description | -| ---------- | --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| action | string | Yes | Refer to [Custom role actions and scopes]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for full list of available actions. | -| scope | string | No | If not present, no scope will be mapped to the permission. Refer to [Custom role actions and scopes]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for full list of available scopes. | +| Field Name | Data Type | Required | Description | +| ---------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| action | string | Yes | Refer to [Custom role actions and scopes](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for full list of available actions. | +| scope | string | No | If not present, no scope will be mapped to the permission. Refer to [Custom role actions and scopes](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for full list of available scopes. | #### Example response @@ -494,7 +494,7 @@ Permission validation only occurs when permission validation is enabled (`rbac.p > It has been enabled by default since Grafana 10.2. -For more information, refer to [Create role validation errors]({{< ref "#create-role-validation-errors" >}}). +For more information, refer to [Create role validation errors](#create-role-validation-errors). #### Status codes @@ -530,10 +530,10 @@ Accept: application/json #### Query parameters -| Param | Type | Required | Description | -| ------ | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| force | boolean | No | When set to `true`, the role will be deleted with all its assignments. | -| global | boolean | No | A flag indicating if the role is global or not. If set to false, the default org ID of the authenticated user will be used from the request. Refer to the [About RBAC]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control" >}}) for more information. | +| Param | Type | Required | Description | +| ------ | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| force | boolean | No | When set to `true`, the role will be deleted with all its assignments. | +| global | boolean | No | A flag indicating if the role is global or not. If set to false, the default org ID of the authenticated user will be used from the request. Refer to the [About RBAC](/docs/grafana/latest/administration/roles-and-permissions/access-control/) for more information. | #### Example response @@ -711,7 +711,7 @@ Content-Type: application/json; charset=UTF-8 Assign a role to a specific user. For bulk updates consider -[Set user role assignments]({{< ref "#set-user-role-assignments" >}}). +[Set user role assignments](#set-user-role-assignments). #### Required permissions @@ -769,7 +769,7 @@ Content-Type: application/json; charset=UTF-8 Revoke a role from a user. For bulk updates consider -[Set user role assignments]({{< ref "#set-user-role-assignments" >}}). +[Set user role assignments](#set-user-role-assignments). #### Required permissions @@ -821,8 +821,8 @@ This will remove any assigned roles that aren't in the request and add roles that are in the set but are not already assigned to the user. If you want to add or remove a single role, consider using -[Add a user role assignment]({{< ref "#add-a-user-role-assignment" >}}) or -[Remove a user role assignment]({{< ref "#remove-a-user-role-assignment" >}}) +[Add a user role assignment](#add-a-user-role-assignment) or +[Remove a user role assignment](#remove-a-user-role-assignment) instead. #### Required permissions @@ -985,7 +985,7 @@ Content-Type: application/json; charset=UTF-8 Assign a role to a specific service account. For bulk updates consider -[Set service account role assignments]({{< ref "#set-service-account-role-assignments" >}}). +[Set service account role assignments](#set-service-account-role-assignments). #### Required permissions @@ -1043,7 +1043,7 @@ Content-Type: application/json; charset=UTF-8 Revoke a role from a service account. For bulk updates consider -[Set service account role assignments]({{< ref "#set-service-account-role-assignments" >}}). +[Set service account role assignments](#set-service-account-role-assignments). #### Required permissions @@ -1095,8 +1095,8 @@ This will remove any assigned roles that aren't in the request and add roles that are in the set but are not already assigned to the service account. If you want to add or remove a single role, consider using -[Add a service account role assignment]({{< ref "#add-a-service-account-role-assignment" >}}) or -[Remove a service account role assignment]({{< ref "#remove-a-service-account-role-assignment" >}}) +[Add a service account role assignment](#add-a-service-account-role-assignment) or +[Remove a service account role assignment](#remove-a-service-account-role-assignment) instead. #### Required permissions @@ -1213,7 +1213,7 @@ Content-Type: application/json; charset=UTF-8 Assign a role to a specific team. -For bulk updates consider [Set team role assignments]({{< ref "#set-team-role-assignments" >}}). +For bulk updates consider [Set team role assignments](#set-team-role-assignments). #### Required permissions @@ -1268,7 +1268,7 @@ Content-Type: application/json; charset=UTF-8 Revoke a role from a team. -For bulk updates consider [Set team role assignments]({{< ref "#set-team-role-assignments" >}}). +For bulk updates consider [Set team role assignments](#set-team-role-assignments). #### Required permissions @@ -1314,8 +1314,8 @@ This will remove any assigned roles that aren't in the request and add roles that are in the set but are not already assigned to the user. If you want to add or remove a single role, consider using -[Add a team role assignment]({{< ref "#add-a-team-role-assignment" >}}) or -[Remove a team role assignment]({{< ref "#remove-a-team-role-assignment" >}}) +[Add a team role assignment](#add-a-team-role-assignment) or +[Remove a team role assignment](#remove-a-team-role-assignment) instead. #### Required permissions diff --git a/docs/sources/developers/http_api/admin.md b/docs/sources/developers/http_api/admin.md index eb96ebecf95..62a64c19cec 100644 --- a/docs/sources/developers/http_api/admin.md +++ b/docs/sources/developers/http_api/admin.md @@ -28,17 +28,17 @@ To use these API endpoints you have to use Basic authentication and the Grafana The `admin` user that Grafana is provisioned with by default has permissions to use these API endpoints. {{< /admonition >}} -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "../../administration/roles-and-permissions/access-control/custom-role-actions-scopes/" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](../../../administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Fetch settings `GET /api/admin/settings` -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ------------- | ----------------------------------------------------------------------------------- | @@ -213,7 +213,7 @@ This endpoint only supports changes to `auth.saml` configuration. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | -------------- | ----------------------------------------------------------------------------------- | @@ -263,11 +263,11 @@ Status codes: `GET /api/admin/stats` -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ----------------- | ----- | @@ -307,7 +307,7 @@ Content-Type: application/json Preview usage report to be sent to vendor. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Example Request**: @@ -345,11 +345,11 @@ Content-Type: application/json `POST /api/admin/users` -Create new user. Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Create new user. Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ------------ | ----- | @@ -371,7 +371,7 @@ Content-Type: application/json } ``` -Note that `OrgId` is an optional parameter that can be used to assign a new user to a different organization when [auto_assign_org]({{< relref "../../setup-grafana/configure-grafana/#auto-assign-org" >}}) is set to `true`. +Note that `OrgId` is an optional parameter that can be used to assign a new user to a different organization when [auto_assign_org](../../../setup-grafana/configure-grafana/#auto-assign-org) is set to `true`. **Example Response**: @@ -386,12 +386,12 @@ Content-Type: application/json `PUT /api/admin/users/:id/password` -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. Change password for a specific user. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | -------------------- | --------------- | @@ -420,11 +420,11 @@ Content-Type: application/json `PUT /api/admin/users/:id/permissions` -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ----------------------- | --------------- | @@ -453,11 +453,11 @@ Content-Type: application/json `DELETE /api/admin/users/:id` -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ------------ | --------------- | @@ -486,11 +486,11 @@ Content-Type: application/json Return a list of all auth tokens (devices) that the user currently have logged in from. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | -------------------- | --------------- | @@ -545,11 +545,11 @@ Content-Type: application/json Revokes the given auth token (device) for the user. User of issued auth token (device) will no longer be logged in and will be required to authenticate again upon next activity. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | --------------------- | --------------- | @@ -585,11 +585,11 @@ Content-Type: application/json Logout user revokes all auth tokens (devices) for the user. User of issued auth tokens (devices) will no longer be logged in and will be required to authenticate again upon next activity. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | | ------------ | --------------- | @@ -630,11 +630,11 @@ Reloads the provisioning config files for specified type and provision entities until the new provisioned entities are already stored in the database. In case of dashboards, it will stop polling for changes in dashboard files and then restart it with new configurations after returning. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Required permissions** -See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation. +See note in the [introduction](#admin-api) for an explanation. | Action | Scope | Provision entity | | ------------------- | -------------------------- | ---------------- | @@ -669,7 +669,7 @@ Content-Type: application/json Reloads the LDAP configuration. -Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation. +Only works with Basic Authentication (username and password). See [introduction](/docs/grafana//http_api/admin/#admin-api) for an explanation. **Example Request**: @@ -694,7 +694,7 @@ Content-Type: application/json `POST /api/admin/encryption/rotate-data-keys` -[Rotates]({{< relref "../../setup-grafana/configure-security/configure-database-encryption/#rotate-data-keys" >}}) data encryption keys. +[Rotates](../../../setup-grafana/configure-security/configure-database-encryption/#rotate-data-keys) data encryption keys. **Example Request**: @@ -715,7 +715,7 @@ Content-Type: application/json `POST /api/admin/encryption/reencrypt-data-keys` -[Re-encrypts]({{< relref "../../setup-grafana/configure-security/configure-database-encryption/#re-encrypt-data-keys" >}}) data encryption keys. +[Re-encrypts](../../../setup-grafana/configure-security/configure-database-encryption/#re-encrypt-data-keys) data encryption keys. **Example Request**: @@ -736,7 +736,7 @@ Content-Type: application/json `POST /api/admin/encryption/reencrypt-secrets` -[Re-encrypts]({{< relref "../../setup-grafana/configure-security/configure-database-encryption/#re-encrypt-secrets" >}}) secrets. +[Re-encrypts](../../../setup-grafana/configure-security/configure-database-encryption/#re-encrypt-secrets) secrets. **Example Request**: @@ -757,7 +757,7 @@ Content-Type: application/json `POST /api/admin/encryption/rollback-secrets` -[Rolls back]({{< relref "../../setup-grafana/configure-security/configure-database-encryption/#roll-back-secrets" >}}) secrets. +[Rolls back](../../../setup-grafana/configure-security/configure-database-encryption/#roll-back-secrets) secrets. **Example Request**: diff --git a/docs/sources/developers/http_api/annotations.md b/docs/sources/developers/http_api/annotations.md index 974b0c6c6d5..0fb5c4a5d1a 100644 --- a/docs/sources/developers/http_api/annotations.md +++ b/docs/sources/developers/http_api/annotations.md @@ -22,7 +22,7 @@ title: Annotations HTTP API Annotations are saved in the Grafana database (sqlite, mysql or postgres). Annotations can be organization annotations that can be shown on any dashboard by configuring an annotation data source - they are filtered by tags. Or they can be tied to a panel on a dashboard and are then only shown on that panel. -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Find Annotations @@ -30,7 +30,7 @@ Annotations are saved in the Grafana database (sqlite, mysql or postgres). Annot **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | @@ -123,7 +123,7 @@ The format for `time` and `timeEnd` should be epoch numbers in millisecond resol **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | @@ -178,7 +178,7 @@ format (string with multiple tags being separated by a space). **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | | -------------------- | ------------------------------- | @@ -219,7 +219,7 @@ Updates all properties of an annotation that matches the specified id. To only u **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | @@ -265,7 +265,7 @@ This operation currently supports updating of the `text`, `tags`, `time` and `ti **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | @@ -307,7 +307,7 @@ Deletes the annotation that matches the specified id. **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | @@ -344,7 +344,7 @@ Find all the event tags created in the annotations. **Required permissions** -See note in the [introduction]({{< ref "#annotations-api" >}}) for an explanation. +See note in the [introduction](#annotations-api) for an explanation. | Action | Scope | | ------------------ | ----- | diff --git a/docs/sources/developers/http_api/auth.md b/docs/sources/developers/http_api/auth.md index be88ae5ccd0..898def0691b 100644 --- a/docs/sources/developers/http_api/auth.md +++ b/docs/sources/developers/http_api/auth.md @@ -22,10 +22,10 @@ title: 'Authentication HTTP API ' The Authentication HTTP API is used to manage API keys. {{% admonition type="note" %}} -Grafana recommends using service accounts instead of API keys. For more information, refer to [Grafana service account API reference]({{< relref "./serviceaccount/" >}}). +Grafana recommends using service accounts instead of API keys. For more information, refer to [Grafana service account API reference](../serviceaccount/). {{% /admonition %}} -> If you are running Grafana Enterprise, for some endpoints you would need to have relevant permissions. Refer to [Role-based access control permissions]({{< relref "../../administration/roles-and-permissions/access-control/custom-role-actions-scopes/" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you would need to have relevant permissions. Refer to [Role-based access control permissions](../../../administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## List API keys @@ -38,7 +38,7 @@ This endpoint is deprecated. **Required permissions** -See note in the [introduction]({{< ref "#authentication-api" >}}) for an explanation. +See note in the [introduction](#authentication-api) for an explanation. | Action | Scope | | -------------- | ----------- | @@ -85,7 +85,7 @@ This endpoint has been made obsolete in Grafana 11.3.0. {{% /admonition %}} -Endpoint is obsolete and has been moved to [Grafana service account API]({{< relref "./serviceaccount/" >}}). For more information, refer to [Migrate to Grafana service account API](/docs/grafana//administration/service-accounts/migrate-api-keys/). +Endpoint is obsolete and has been moved to [Grafana service account API](../serviceaccount/). For more information, refer to [Migrate to Grafana service account API](/docs/grafana//administration/service-accounts/migrate-api-keys/). `POST /api/auth/keys` @@ -110,7 +110,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#authentication-api" >}}) for an explanation. +See note in the [introduction](#authentication-api) for an explanation. | Action | Scope | | ---------------- | ---------- | diff --git a/docs/sources/developers/http_api/dashboard.md b/docs/sources/developers/http_api/dashboard.md index d37b0e080c9..75d1f8a50d3 100644 --- a/docs/sources/developers/http_api/dashboard.md +++ b/docs/sources/developers/http_api/dashboard.md @@ -18,7 +18,7 @@ title: Dashboard HTTP API # Dashboard API -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Identifier (id) vs unique identifier (uid) @@ -26,7 +26,7 @@ The identifier (id) of a dashboard is an auto-incrementing numeric value and is The unique identifier (uid) of a dashboard can be used for uniquely identify a dashboard between multiple Grafana installs. It's automatically generated if not provided when creating a dashboard. The uid allows having consistent URLs for accessing -dashboards and when syncing dashboards between multiple Grafana installs, see [dashboard provisioning]({{< relref "/docs/grafana/latest/administration/provisioning#dashboards" >}}) +dashboards and when syncing dashboards between multiple Grafana installs, see [dashboard provisioning](/docs/grafana/latest/administration/provisioning/#dashboards) for more information. This means that changing the title of a dashboard will not break any bookmarked links to that dashboard. The uid can have a maximum length of 40 characters. @@ -41,7 +41,7 @@ Creates a new dashboard or updates an existing dashboard. When updating existing **Required permissions** -See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation. +See note in the [introduction](#dashboard-api) for an explanation. | Action | Scope | @@ -80,7 +80,7 @@ JSON Body schema: - **dashboard** – The complete dashboard model. - **dashboard.id** – id = null to create a new dashboard. - **dashboard.uid** – Optional unique identifier when creating a dashboard. uid = null will generate a new uid. -- **dashboard.refresh** - Set the dashboard refresh interval. If this is lower than [the minimum refresh interval]({{< relref "/docs/grafana/latest/setup-grafana/configure-grafana#min_refresh_interval" >}}), then Grafana will ignore it and will enforce the minimum refresh interval. +- **dashboard.refresh** - Set the dashboard refresh interval. If this is lower than [the minimum refresh interval](/docs/grafana/latest/setup-grafana/configure-grafana/#min_refresh_interval), then Grafana will ignore it and will enforce the minimum refresh interval. - **folderId** – The id of the folder to save the dashboard in. - **folderUid** – The UID of the folder to save the dashboard in. Overrides the `folderId`. - **overwrite** – Set to true if you want to overwrite an existing dashboard with a given dashboard UID. @@ -139,7 +139,6 @@ The **412** status code is used for explaining that you cannot create the dashbo There can be different reasons for this: - The dashboard has been changed by someone else, `status=version-mismatch` -- A dashboard with the same name in the folder already exists, `status=name-exists` - A dashboard with the same uid already exists, `status=name-exists` - The dashboard belongs to plugin ``, `status=plugin-dashboard` @@ -156,8 +155,6 @@ Content-Length: 97 } ``` -In case of title already exists the `status` property will be `name-exists`. - ## Get dashboard by uid `GET /api/dashboards/uid/:uid` @@ -166,7 +163,7 @@ Will return the dashboard given the dashboard unique identifier (uid). Informati **Required permissions** -See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation. +See note in the [introduction](#dashboard-api) for an explanation. | Action | Scope | @@ -225,7 +222,7 @@ Will delete the dashboard given the specified unique identifier (uid). **Required permissions** -See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation. +See note in the [introduction](#dashboard-api) for an explanation. | Action | Scope | @@ -275,7 +272,7 @@ Will delete permanently the dashboard given the specified unique identifier (uid **Required permissions** -See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation. +See note in the [introduction](#dashboard-api) for an explanation. | Action | Scope | @@ -325,7 +322,7 @@ Will restore a deleted dashboard given the specified unique identifier (uid). **Required permissions** -See note in the [introduction]({{< ref "#dashboard-api" >}}) for an explanation. +See note in the [introduction](#dashboard-api) for an explanation. | Action | Scope | @@ -358,7 +355,7 @@ Content-Type: application/json Status Codes: -- **200** – Deleted +- **200** – Restored - **401** – Unauthorized - **403** – Access denied - **404** – Not found @@ -453,4 +450,4 @@ Content-Type: application/json ## Dashboard Search -See [Folder/Dashboard Search API]({{< relref "folder_dashboard_search/" >}}). +See [Folder/Dashboard Search API](../folder_dashboard_search/). diff --git a/docs/sources/developers/http_api/dashboard_permissions.md b/docs/sources/developers/http_api/dashboard_permissions.md index 07242307875..3a12656faf5 100644 --- a/docs/sources/developers/http_api/dashboard_permissions.md +++ b/docs/sources/developers/http_api/dashboard_permissions.md @@ -32,7 +32,7 @@ The permission levels for the permission field: - 2 = Edit - 4 = Admin -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Get permissions for a dashboard @@ -42,7 +42,7 @@ Gets all existing permissions for the dashboard with the given `uid`. **Required permissions** -See note in the [introduction]({{< ref "#dashboard-permission-api" >}}) for an explanation. +See note in the [introduction](#dashboard-permission-api) for an explanation. | Action | Scope | @@ -124,7 +124,7 @@ Updates permissions for a dashboard. This operation will remove existing permiss **Required permissions** -See note in the [introduction]({{< ref "#dashboard-permission-api" >}}) for an explanation. +See note in the [introduction](#dashboard-permission-api) for an explanation. | Action | Scope | diff --git a/docs/sources/developers/http_api/data_source.md b/docs/sources/developers/http_api/data_source.md index e9d8a8b35ab..ddda447bcfc 100644 --- a/docs/sources/developers/http_api/data_source.md +++ b/docs/sources/developers/http_api/data_source.md @@ -19,7 +19,7 @@ title: Data source HTTP API # Data source API -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Get all data sources @@ -31,7 +31,7 @@ This API currently doesn't handle pagination. The default maximum number of data **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ---------------- | -------------- | @@ -90,7 +90,7 @@ This API is deprecated since Grafana v9.0.0 and will be removed in a future rele **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ---------------- | ---------------------------------------------------------------------------- | @@ -146,7 +146,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ---------------- | -------------------------------------------------------------------------------------- | @@ -202,7 +202,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ---------------- | ---------------------------------------------------------------------------------------------- | @@ -258,7 +258,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ------------------- | ---------------------------------------------------------------------------------------------- | @@ -292,7 +292,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ------------------ | ----- | @@ -446,7 +446,7 @@ This API is deprecated since Grafana v9.0.0 and will be removed in a future rele **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ----------------- | ---------------------------------------------------------------------------- | @@ -529,7 +529,7 @@ Similar to [creating a data source](#create-a-data-source), `password` and `basi **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ----------------- | -------------------------------------------------------------------------------------- | @@ -617,7 +617,7 @@ This API is deprecated since Grafana v9.0.0 and will be removed in a future rele **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ------------------ | ---------------------------------------------------------------------------- | @@ -649,7 +649,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ------------------ | -------------------------------------------------------------------------------------- | @@ -684,7 +684,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#data-source-api" >}}) for an explanation. +See note in the [introduction](#data-source-api) for an explanation. | Action | Scope | | ------------------ | ---------------------------------------------------------------------------------------------- | diff --git a/docs/sources/developers/http_api/datasource_permissions.md b/docs/sources/developers/http_api/datasource_permissions.md index 9c0a0fc3ee8..b65464d0dba 100644 --- a/docs/sources/developers/http_api/datasource_permissions.md +++ b/docs/sources/developers/http_api/datasource_permissions.md @@ -23,9 +23,9 @@ title: Datasource Permissions HTTP API # Data Source Permissions API -> The Data Source Permissions is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}). +> The Data Source Permissions is only available in Grafana Enterprise. Read more about [Grafana Enterprise](/docs/grafana/latest/introduction/grafana-enterprise/). -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. This API can be used to list, add and remove permissions for a data source. @@ -39,7 +39,7 @@ Gets all existing permissions for the data source with the given `uid`. **Required permissions** -See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation. +See note in the [introduction](#data-source-permissions-api) for an explanation. | Action | Scope | | ---------------------------- | ------------------------------------------------------------------------------------------ | @@ -134,7 +134,7 @@ To remove a permission, set the `permission` field to an empty string. **Required permissions** -See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation. +See note in the [introduction](#data-source-permissions-api) for an explanation. | Action | Scope | | ----------------------------- | ------------------------------------------------------------------------------------------ | @@ -206,7 +206,7 @@ To remove a permission, set the `permission` field to an empty string. **Required permissions** -See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation. +See note in the [introduction](#data-source-permissions-api) for an explanation. | Action | Scope | | ----------------------------- | ------------------------------------------------------------------------------------------ | @@ -280,7 +280,7 @@ To remove a permission, set the `permission` field to an empty string. **Required permissions** -See note in the [introduction]({{< ref "#data-source-permissions-api" >}}) for an explanation. +See note in the [introduction](#data-source-permissions-api) for an explanation. | Action | Scope | | ----------------------------- | ------------------------------------------------------------------------------------------ | diff --git a/docs/sources/developers/http_api/examples/create-api-tokens-for-org.md b/docs/sources/developers/http_api/examples/create-api-tokens-for-org.md index d5b2ded16a4..caa6bc90243 100644 --- a/docs/sources/developers/http_api/examples/create-api-tokens-for-org.md +++ b/docs/sources/developers/http_api/examples/create-api-tokens-for-org.md @@ -32,7 +32,7 @@ There are two authentication methods to access the API: The task is to create a new organization and then add a Token that can be used by other users. In the examples below which use basic auth, the user is `admin` and the password is `admin`. -1. [Create the org](http://docs.grafana.org/http_api/org/#create-organization). Here is an example using curl: +1. [Create the org](/docs/grafana//http_api/org/#create-organization). Here is an example using curl: ```bash curl -X POST -H "Content-Type: application/json" -d '{"name":"apiorg"}' http://admin:admin@localhost:3000/api/orgs @@ -40,25 +40,25 @@ The task is to create a new organization and then add a Token that can be used b This should return a response: `{"message":"Organization created","orgId":6}`. Use the orgId for the next steps. -1. Optional step. If the org was created previously and/or step 3 fails then first [add your Admin user to the org](http://docs.grafana.org/http_api/org/#add-user-in-organization): +1. Optional step. If the org was created previously and/or step 3 fails then first [add your Admin user to the org](/docs/grafana//http_api/org/#add-user-in-organization): ```bash curl -X POST -H "Content-Type: application/json" -d '{"loginOrEmail":"admin", "role": "Admin"}' http://admin:admin@localhost:3000/api/orgs//users ``` -1. [Switch the org context for the Admin user to the new org](http://docs.grafana.org/http_api/user/#switch-user-context-for-signed-in-user): +1. [Switch the org context for the Admin user to the new org](/docs/grafana//http_api/user/#switch-user-context-for-signed-in-user): ```bash curl -X POST http://admin:admin@localhost:3000/api/user/using/ ``` -1. [Create a Service Account]({{< relref "./serviceaccount/#create-service-account" >}}): +1. [Create a Service Account](../../serviceaccount/#create-service-account): ```bash curl -X POST -H "Content-Type: application/json" -d '{"name":"test", "role": "Admin"}' http://admin:admin@localhost:3000/api/serviceaccounts ``` -1. [Create a Service Account token]({{< relref "./serviceaccount/#create-service-account-tokens" >}}) for the service account created in the previous step: +1. [Create a Service Account token](../../serviceaccount/#create-service-account-tokens) for the service account created in the previous step: ```bash curl -X POST -H "Content-Type: application/json" -d '{"name":"test-token"}' http://admin:admin@localhost:3000/api/serviceaccounts//tokens @@ -83,7 +83,7 @@ The task is to create a new organization and then add a Token that can be used b Using the Token that was created in the previous step, you can create a dashboard or carry out other actions without having to switch organizations. -1. [Add a dashboard](http://docs.grafana.org/http_api/dashboard/#create-update-dashboard) using the key (or bearer token as it is also called): +1. [Add a dashboard](/docs/grafana//http_api/dashboard/#create-update-dashboard) using the key (or bearer token as it is also called): ```bash curl -X POST --insecure -H "Authorization: Bearer eyJrIjoiR0ZXZmt1UFc0OEpIOGN5RWdUalBJTllUTk83VlhtVGwiLCJuIjoiYXBpa2V5Y3VybCIsImlkIjo2fQ==" -H "Content-Type: application/json" -d '{ diff --git a/docs/sources/developers/http_api/examples/curl-examples.md b/docs/sources/developers/http_api/examples/curl-examples.md index a7f3c1ca2e8..b00e59feb4a 100644 --- a/docs/sources/developers/http_api/examples/curl-examples.md +++ b/docs/sources/developers/http_api/examples/curl-examples.md @@ -27,16 +27,16 @@ The most basic example for a dashboard for which there is no authentication. You curl http://localhost:3000/api/search ``` -Here's a cURL command that works for getting the home dashboard when you are running Grafana locally with [basic authentication]({{< relref "/docs/grafana/latest/setup-grafana/configure-security/configure-authentication#basic-auth" >}}) enabled using the default admin credentials: +Here's a cURL command that works for getting the home dashboard when you are running Grafana locally with [basic authentication](/docs/grafana/latest/setup-grafana/configure-security/configure-authentication/#basic-auth) enabled using the default admin credentials: ``` curl http://admin:admin@localhost:3000/api/search ``` -To pass a username and password with [HTTP basic authorization]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/manage-rbac-roles" >}}), encode them as base64. +To pass a username and password with [HTTP basic authorization](/docs/grafana/latest/administration/roles-and-permissions/access-control/manage-rbac-roles/), encode them as base64. You can't use authorization tokens in the request. -For example, to [list permissions associated with roles]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/manage-rbac-roles" >}}) given a username of `user` and password of `password`, use: +For example, to [list permissions associated with roles](/docs/grafana/latest/administration/roles-and-permissions/access-control/manage-rbac-roles/) given a username of `user` and password of `password`, use: ``` curl --location '/api/access-control/builtin-roles' --user 'user:password' diff --git a/docs/sources/developers/http_api/folder.md b/docs/sources/developers/http_api/folder.md index dce1ff7eea7..73a9c54ba39 100644 --- a/docs/sources/developers/http_api/folder.md +++ b/docs/sources/developers/http_api/folder.md @@ -18,7 +18,7 @@ title: Folder HTTP API # Folder API -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Identifier (id) vs unique identifier (uid) @@ -40,7 +40,7 @@ that the authenticated user has permission to view. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. | Action | Scope | | -------------- | ----------- | @@ -83,7 +83,7 @@ Will return the folder given the folder uid. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. | Action | Scope | | -------------- | ----------- | @@ -141,7 +141,7 @@ Creates a new folder. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. `folders:create` allows creating folders and subfolders. If granted with scope `folders:uid:general`, allows creating root level folders. Otherwise, allows creating subfolders under the specified folders. @@ -167,7 +167,7 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk JSON Body schema: -- **uid** – Optional [unique identifier]({{< ref "#identifier-id-vs-unique-identifier-uid" >}}). +- **uid** – Optional [unique identifier](#identifier-id-vs-unique-identifier-uid). - **title** – The title of the folder. - **parentUid** - Optional field, the unique identifier of the parent folder under which the folder should be created. Requires nested folders to be enabled. @@ -215,7 +215,7 @@ Updates an existing folder identified by uid. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. | Action | Scope | | --------------- | ----------- | @@ -302,11 +302,11 @@ Content-Length: 97 Deletes an existing folder identified by UID along with all dashboards (and their alerts) stored in the folder. This operation cannot be reverted. -If [Grafana Alerting]({{< relref "/docs/grafana/latest/alerting" >}}) is enabled, you can set an optional query parameter `forceDeleteRules=false` so that requests will fail with 400 (Bad Request) error if the folder contains any Grafana alerts. However, if this parameter is set to `true` then it will delete any Grafana alerts under this folder. +If [Grafana Alerting](/docs/grafana/latest/alerting/) is enabled, you can set an optional query parameter `forceDeleteRules=false` so that requests will fail with 400 (Bad Request) error if the folder contains any Grafana alerts. However, if this parameter is set to `true` then it will delete any Grafana alerts under this folder. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. | Action | Scope | | ---------------- | ----------- | @@ -352,7 +352,7 @@ This is relevant only if nested folders are enabled. **Required permissions** -See note in the [introduction]({{< ref "#folder-api" >}}) for an explanation. +See note in the [introduction](#folder-api) for an explanation. If moving the folder under another folder: @@ -367,7 +367,7 @@ If moving the folder under root: JSON body schema: -- **parentUid** – Optional [unique identifier]({{< relref "#identifier-id-vs-unique-identifier-uid" >}}) of the new parent folder. If this is empty, then the folder is moved under the root. +- **parentUid** – Optional [unique identifier](#identifier-id-vs-unique-identifier-uid) of the new parent folder. If this is empty, then the folder is moved under the root. **Example Request**: diff --git a/docs/sources/developers/http_api/folder_dashboard_search.md b/docs/sources/developers/http_api/folder_dashboard_search.md index 5f945a60a03..af741927365 100644 --- a/docs/sources/developers/http_api/folder_dashboard_search.md +++ b/docs/sources/developers/http_api/folder_dashboard_search.md @@ -24,7 +24,7 @@ title: Folder/Dashboard Search HTTP API `GET /api/search/` -> Note: When using [Role-based access control]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control" >}}), search results will contain only dashboards and folders which you have access to. +> Note: When using [Role-based access control](/docs/grafana/latest/administration/roles-and-permissions/access-control/), search results will contain only dashboards and folders which you have access to. Query parameters: diff --git a/docs/sources/developers/http_api/folder_permissions.md b/docs/sources/developers/http_api/folder_permissions.md index 4e7b3ed31ff..74eeffff35a 100644 --- a/docs/sources/developers/http_api/folder_permissions.md +++ b/docs/sources/developers/http_api/folder_permissions.md @@ -32,7 +32,7 @@ The permission levels for the permission field: - 2 = Edit - 4 = Admin -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Get permissions for a folder @@ -42,7 +42,7 @@ Gets all existing permissions for the folder with the given `uid`. **Required permissions** -See note in the [introduction]({{< ref "#folder-permission-api" >}}) for an explanation. +See note in the [introduction](#folder-permission-api) for an explanation. | Action | Scope | | -------------------------- | ----------- | @@ -121,7 +121,7 @@ Updates permissions for a folder. This operation will remove existing permission **Required permissions** -See note in the [introduction]({{< ref "#folder-permission-api" >}}) for an explanation. +See note in the [introduction](#folder-permission-api) for an explanation. | Action | Scope | | --------------------------- | ----------- | diff --git a/docs/sources/developers/http_api/group_attribute_sync.md b/docs/sources/developers/http_api/group_attribute_sync.md index 82f4f67c0f8..f6d5e752297 100644 --- a/docs/sources/developers/http_api/group_attribute_sync.md +++ b/docs/sources/developers/http_api/group_attribute_sync.md @@ -22,8 +22,7 @@ The Group Attribute Sync API allows you to configure [group attribute sync featu > **Note:** Available in [Grafana Enterprise](https://grafana.com/docs/grafana//introduction/grafana-enterprise) and [Grafana Cloud](https://grafana.com/docs/grafana-cloud/) {{% admonition type="note" %}} -This feature is behind the `groupAttributeSync` feature toggle. -You can enable feature toggles through configuration file or environment variables. See configuration [docs](/docs/grafana//setup-grafana/configure-grafana/#feature_toggles) for details. +This feature is currently in [private preview](https://grafana.com/docs/release-life-cycle/#private-preview) and behind the `groupAttributeSync` feature toggle. Please contact support to have this feature enabled. {{% /admonition %}} ## List group mappings diff --git a/docs/sources/developers/http_api/library_element.md b/docs/sources/developers/http_api/library_element.md index c6efb1df45a..19a5577c202 100644 --- a/docs/sources/developers/http_api/library_element.md +++ b/docs/sources/developers/http_api/library_element.md @@ -286,7 +286,7 @@ JSON Body schema: - `name`: Optional, the name of the library element. - `model`: The JSON model for the library element. - `kind`: Kind of element to create, Use `1` for library panels or `2` for library variables. -- `uid`: Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid). +- `uid`: Optional, the [unique identifier](#identifier-id-vs-unique-identifier-uid). **Example Request**: @@ -366,7 +366,7 @@ JSON Body schema: - `model`: The JSON model for the library element. - `kind`: Kind of element to create. Use `1` for library panels or `2` for library variables. - `version`: Version of the library element you are updating. -- `uid`: Optional, the [unique identifier](/http_api/library_element/#identifier-id-vs-unique-identifier-uid). +- `uid`: Optional, the [unique identifier](#identifier-id-vs-unique-identifier-uid). **Example Request**: diff --git a/docs/sources/developers/http_api/licensing.md b/docs/sources/developers/http_api/licensing.md index 937f25a8468..0d09183750c 100644 --- a/docs/sources/developers/http_api/licensing.md +++ b/docs/sources/developers/http_api/licensing.md @@ -19,7 +19,7 @@ title: Licensing HTTP API # Enterprise License API -Licensing is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}). +Licensing is only available in Grafana Enterprise. Read more about [Grafana Enterprise](/docs/grafana/latest/introduction/grafana-enterprise/). {{< admonition type="caution" >}} You can't authenticate to the Licensing HTTP API with service account tokens. @@ -31,7 +31,7 @@ To use these API endpoints you have to use Basic authentication and the Grafana The `admin` user that Grafana is provisioned with by default has permissions to use these API endpoints. {{< /admonition >}} -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Check license availability @@ -43,7 +43,7 @@ Checks if a valid license is available. **Required permissions** -See note in the [introduction]({{< ref "#enterprise-license-api" >}}) for an explanation. +See note in the [introduction](#enterprise-license-api) for an explanation. | Action | Scope | | -------------- | ----- | @@ -85,7 +85,7 @@ Applies a license to a Grafana instance. **Required permissions** -See note in the [introduction]({{< ref "#enterprise-license-api" >}}) for an explanation. +See note in the [introduction](#enterprise-license-api) for an explanation. | Action | Scope | | --------------- | ----- | @@ -147,7 +147,7 @@ Manually ask license issuer for a new token. **Required permissions** -See note in the [introduction]({{< ref "#enterprise-license-api" >}}) for an explanation. +See note in the [introduction](#enterprise-license-api) for an explanation. | Action | Scope | | --------------- | ----- | @@ -208,7 +208,7 @@ Removes the license stored in the Grafana database. **Required permissions** -See note in the [introduction]({{< ref "#enterprise-license-api" >}}) for an explanation. +See note in the [introduction](#enterprise-license-api) for an explanation. | Action | Scope | | ---------------- | ----- | diff --git a/docs/sources/developers/http_api/org.md b/docs/sources/developers/http_api/org.md index d79a60f95ef..d5fb8ab9cb5 100644 --- a/docs/sources/developers/http_api/org.md +++ b/docs/sources/developers/http_api/org.md @@ -23,7 +23,7 @@ The Organization HTTP API is divided in two resources, `/api/org` (current organ and `/api/orgs` (admin organizations). One big difference between these are that the admin of all organizations API only works with basic authentication, see [Admin Organizations API](#admin-organizations-api) for more information. -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Current Organization API @@ -33,7 +33,7 @@ the admin of all organizations API only works with basic authentication, see [Ad **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | --------- | ----- | @@ -69,7 +69,7 @@ Accessible to users with org admin role. **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | -------------- | -------- | @@ -115,7 +115,7 @@ when editing folder/dashboard permissions. **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | -------------- | -------- | @@ -151,7 +151,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | --------------- | -------- | @@ -185,7 +185,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ---------------- | -------- | @@ -215,7 +215,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ---------- | ----- | @@ -251,7 +251,7 @@ Adds a global user to the current organization. **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ------------- | -------- | @@ -300,7 +300,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | --------- | ----- | @@ -342,7 +342,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | Note | | --------- | ----- | ------------------------------ | @@ -384,7 +384,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | Note | | ----------- | ----- | ------------------------------ | @@ -427,7 +427,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | Note | | --------- | ----- | ------------------------------ | @@ -469,7 +469,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ---------- | ----- | @@ -504,7 +504,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ----------- | ----- | @@ -534,7 +534,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | -------------- | -------- | @@ -575,7 +575,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ------------- | -------- | @@ -611,7 +611,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | --------------- | -------- | @@ -646,7 +646,7 @@ Only works with Basic Authentication (username and password), see [introduction] **Required permissions** -See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation. +See note in the [introduction](#organization-api) for an explanation. | Action | Scope | | ---------------- | -------- | diff --git a/docs/sources/developers/http_api/query_and_resource_caching.md b/docs/sources/developers/http_api/query_and_resource_caching.md index 826292decb6..0b24456e2e2 100644 --- a/docs/sources/developers/http_api/query_and_resource_caching.md +++ b/docs/sources/developers/http_api/query_and_resource_caching.md @@ -24,7 +24,7 @@ title: Query and Resource Caching HTTP API # Query and resource caching API {{% admonition type="note" %}} -If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. {{% /admonition %}} ## Enable caching for a data source @@ -33,7 +33,7 @@ If you are running Grafana Enterprise, for some endpoints you'll need to have sp **Required permissions** -See note in the [introduction]({{< ref "#query-and-resource-caching-api" >}}) for an explanation. +See note in the [introduction](#query-and-resource-caching-api) for an explanation. | Action | Scope | | ------------------------- | -------------- | @@ -83,7 +83,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#query-and-resource-caching-api" >}}) for an explanation. +See note in the [introduction](#query-and-resource-caching-api) for an explanation. | Action | Scope | | ------------------------- | -------------- | @@ -135,7 +135,7 @@ Will clean cached data for _all_ data sources with caching enabled. The `dataSou **Required permissions** -See note in the [introduction]({{< ref "#query-and-resource-caching-api" >}}) for an explanation. +See note in the [introduction](#query-and-resource-caching-api) for an explanation. | Action | Scope | | ------------------------- | -------------- | @@ -185,7 +185,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#query-and-resource-caching-api" >}}) for an explanation. +See note in the [introduction](#query-and-resource-caching-api) for an explanation. | Action | Scope | | ------------------------- | -------------- | @@ -256,7 +256,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#query-and-resource-caching-api" >}}) for an explanation. +See note in the [introduction](#query-and-resource-caching-api) for an explanation. | Action | Scope | | ------------------------ | -------------- | diff --git a/docs/sources/developers/http_api/reporting.md b/docs/sources/developers/http_api/reporting.md index 871775fe15a..8666f253e63 100644 --- a/docs/sources/developers/http_api/reporting.md +++ b/docs/sources/developers/http_api/reporting.md @@ -17,13 +17,13 @@ title: Reporting API # Reporting API -This API allows you to interact programmatically with the [Reporting]({{< relref "/docs/grafana/latest/dashboards/create-reports" >}}) feature. +This API allows you to interact programmatically with the [Reporting](/docs/grafana/latest/dashboards/create-reports/) feature. > The Reporting API is not stabilized yet, it is still in active development and may change without prior notice. -> Reporting is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}). +> Reporting is only available in Grafana Enterprise. Read more about [Grafana Enterprise](/docs/grafana/latest/introduction/grafana-enterprise/). -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## List all reports @@ -31,7 +31,7 @@ This API allows you to interact programmatically with the [Reporting]({{< relref #### Required permissions -See note in the [introduction]({{< relref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ------------ | --------------------------- | @@ -103,7 +103,7 @@ Content-Length: 1840 ### Status Codes - **200** – OK -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **500** – Unexpected error or server misconfiguration. Refer to server logs for more details. ## Get a report @@ -112,7 +112,7 @@ Content-Length: 1840 #### Required permissions -See note in the [introduction]({{< relref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ------------ | ---------------------------------------------------------- | @@ -187,7 +187,7 @@ Content-Length: 940 - **200** – OK - **400** – Bad request (invalid report ID). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **403** – Forbidden (access denied to a report or a dashboard used in the report). - **404** – Not found (such report does not exist). - **500** – Unexpected error or server misconfiguration. Refer to server logs for more details. @@ -198,7 +198,7 @@ Content-Length: 940 #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | -------------- | ----- | @@ -308,7 +308,7 @@ Content-Length: 35 #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ------------- | --------------------------------------------------------- | @@ -316,7 +316,7 @@ See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. ### Example request -See [JSON body schema]({{< ref "#config-json-body-schema" >}}) for fields description. +See [JSON body schema](#config-json-body-schema) for fields description. ```http GET /api/reports HTTP/1.1 @@ -381,7 +381,7 @@ Content-Length: 28 - **200** – OK - **400** – Bad request (invalid json, missing or invalid fields values, etc.). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **403** – Forbidden (access denied to a report or a dashboard used in the report). - **404** – Not found (such report does not exist). - **500** – Unexpected error or server misconfiguration. Refer to server logs for more details. @@ -392,7 +392,7 @@ Content-Length: 28 #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | -------------- | --------------------------------------------------------- | @@ -423,7 +423,7 @@ Content-Length: 39 - **200** – OK - **400** – Bad request (invalid report ID). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **404** - Not found (report with this ID does not exist). - **500** - Unexpected error or server misconfiguration. Refer to server logs for more details @@ -435,7 +435,7 @@ Generate and send a report. This API waits for the report to be generated before #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ------------ | ----- | @@ -477,7 +477,7 @@ Content-Length: 29 - **200** – Report was sent. - **400** – Bad request (invalid json, missing content-type, missing or invalid fields, etc.). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **403** - Forbidden (access denied to a report or a dashboard used in the report). - **404** - Report not found. - **500** - Unexpected error or server misconfiguration. Refer to server logs for more details. @@ -490,7 +490,7 @@ Returns reports branding settings that are global and used across all the report #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | --------------------- | ----- | @@ -529,7 +529,7 @@ Content-Length: 181 ### Status Codes - **200** – OK -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **500** - Unexpected error or server misconfiguration. Refer to server logs for more detail ## Save reports branding settings @@ -540,7 +540,7 @@ Creates settings if they don't exist, otherwise updates them. These settings are #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ---------------------- | ----- | @@ -591,7 +591,7 @@ Content-Length: 35 - **200** – OK - **400** – Bad request (invalid json, missing or invalid fields values, etc.). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **500** - Unexpected error or server misconfiguration. Refer to server logs for more detail ## Send a test email @@ -602,7 +602,7 @@ Sends a test email with a report without persisting it in the database. #### Required permissions -See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. +See note in the [introduction](#reporting-api) for an explanation. | Action | Scope | | ------------ | ----- | @@ -610,7 +610,7 @@ See note in the [introduction]({{< ref "#reporting-api" >}}) for an explanation. ### Example request -See [JSON body schema]({{< ref "#config-json-body-schema" >}}) for fields description. +See [JSON body schema](#config-json-body-schema) for fields description. ```http POST /api/reports/test-email HTTP/1.1 @@ -674,6 +674,6 @@ Content-Length: 29 - **200** – OK - **400** – Bad request (invalid json, missing or invalid fields values, etc.). -- **401** - Authentication failed, refer to [Authentication API]({{< relref "/docs/grafana/latest/developers/http_api/auth" >}}). +- **401** - Authentication failed, refer to [Authentication API](/docs/grafana/latest/developers/http_api/auth/). - **403** - Forbidden (access denied to a report or a dashboard used in the report). - **500** - Unexpected error or server misconfiguration. Refer to server logs for more details diff --git a/docs/sources/developers/http_api/serviceaccount.md b/docs/sources/developers/http_api/serviceaccount.md index 680c3472647..559ecc05b3a 100644 --- a/docs/sources/developers/http_api/serviceaccount.md +++ b/docs/sources/developers/http_api/serviceaccount.md @@ -18,7 +18,7 @@ title: Service account HTTP API # Service account API -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. > For Grafana Cloud instances, please use a Bearer token to authenticate. The examples within this section reference Basic authentication which is for On-Prem Grafana instances. ## Search service accounts with Paging @@ -27,7 +27,7 @@ title: Service account HTTP API **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | -------------------- | ----- | @@ -94,7 +94,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | ---------------------- | ----- | @@ -141,7 +141,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | -------------------- | --------------------- | @@ -182,7 +182,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | --------------------- | @@ -228,7 +228,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | ---------------------- | --------------------- | @@ -262,7 +262,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | ------------------ | @@ -294,7 +294,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | ------------------ | @@ -326,7 +326,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | -------------------- | ------------------ | @@ -358,7 +358,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | ------------------ | @@ -390,7 +390,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | -------------------- | --------------------- | @@ -430,7 +430,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | --------------------- | @@ -471,7 +471,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | --------------------- | --------------------- | @@ -505,7 +505,7 @@ This operation will delete the service account and create a legacy API Key for t **Required permissions** -See note in the [introduction]({{< ref "#service-account-api" >}}) for an explanation. +See note in the [introduction](#service-account-api) for an explanation. | Action | Scope | | ---------------------- | --------------------- | diff --git a/docs/sources/developers/http_api/short_url.md b/docs/sources/developers/http_api/short_url.md index 03390a5f655..84c754a42a5 100644 --- a/docs/sources/developers/http_api/short_url.md +++ b/docs/sources/developers/http_api/short_url.md @@ -41,7 +41,7 @@ Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk JSON body schema: -- **path** – The path to shorten, relative to the Grafana [root_url]({{< relref "/docs/grafana/latest/setup-grafana/configure-grafana#root_url" >}}). +- **path** – The path to shorten, relative to the Grafana [root_url](/docs/grafana/latest/setup-grafana/configure-grafana/#root_url). **Example response:** diff --git a/docs/sources/developers/http_api/sso-settings.md b/docs/sources/developers/http_api/sso-settings.md index cb426373485..dfb10ebf71e 100644 --- a/docs/sources/developers/http_api/sso-settings.md +++ b/docs/sources/developers/http_api/sso-settings.md @@ -20,7 +20,7 @@ title: SSO Settings API # SSO Settings API -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. {{% admonition type="note" %}} Available since Grafana 11. SAML support is in public preview behind the `ssoSettingsSAML` feature flag. @@ -29,7 +29,7 @@ Available since Grafana 11. SAML support is in public preview behind the `ssoSet The API can be used to create, update, delete, get, and list SSO Settings for OAuth2 and SAML. The settings managed by this API are stored in the database and override -[settings from other sources]({{< relref "../../setup-grafana/configure-security/configure-authentication" >}}) +[settings from other sources](../../../setup-grafana/configure-security/configure-authentication/) (arguments, environment variables, settings file, etc). Therefore, every time settings for a specific provider are removed or reset to the default settings at runtime, the settings are inherited from the other sources in the reverse order of precedence @@ -45,7 +45,7 @@ The providers or SSO keys that are not managed by this API are retrieved from th **Required permissions** -See note in the [introduction]({{< ref "#sso-settings" >}}) for an explanation. +See note in the [introduction](#sso-settings) for an explanation. | Action | Scope | | --------------- | ---------------------------- | @@ -112,7 +112,7 @@ The SSO keys that are not managed by this API are retrieved from the other sourc **Required permissions** -See note in the [introduction]({{< ref "#sso-settings" >}}) for an explanation. +See note in the [introduction](#sso-settings) for an explanation. | Action | Scope | | --------------- | ---------------------------- | @@ -175,7 +175,7 @@ to wait a few minutes for the configuration to propagate to all Grafana instance **Required permissions** -See note in the [introduction]({{< ref "#sso-settings" >}}) for an explanation. +See note in the [introduction](#sso-settings) for an explanation. | Action | Scope | | ---------------- | ---------------------------- | @@ -222,7 +222,7 @@ Deletes an existing SSO Settings entry for a provider. **Required permissions** -See note in the [introduction]({{< ref "#sso-settings" >}}) for an explanation. +See note in the [introduction](#sso-settings) for an explanation. | Action | Scope | | ---------------- | ---------------------------- | diff --git a/docs/sources/developers/http_api/team.md b/docs/sources/developers/http_api/team.md index f7eec3d6260..db73f9d11f1 100644 --- a/docs/sources/developers/http_api/team.md +++ b/docs/sources/developers/http_api/team.md @@ -26,10 +26,8 @@ Access to these API endpoints is restricted as follows: - All authenticated users are able to view details of teams they are a member of. - Organization Admins are able to manage all teams and team members. -- If you enable `editors_can_admin` configuration flag, then Organization Editors can create teams and manage teams where they are Admin. - - If you enable `editors_can_admin` configuration flag, Editors can find out whether a team that they are not members of exists by trying to create a team with the same name. -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Team Search With Paging @@ -41,7 +39,7 @@ or **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ---------- | -------- | @@ -107,7 +105,7 @@ The `name` parameter returns a single team if the parameter matches the `name` f **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ---------- | -------- | @@ -153,7 +151,7 @@ The Team `name` needs to be unique. `name` is required and `email` is optional. **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ------------ | ----- | @@ -179,7 +177,7 @@ Authorization: Bearer glsa_kcVxDhZtu5ISOZIEt HTTP/1.1 200 Content-Type: application/json -{"message":"Team created","teamId":2} +{"message":"Team created","teamId":2,"uid":"ceaulqadfoav4e"} ``` Status Codes: @@ -197,7 +195,7 @@ There are two fields that can be updated for a team: `name` and `email`. **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ----------- | -------- | @@ -240,7 +238,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ------------ | -------- | @@ -277,7 +275,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ---------------------- | -------- | @@ -330,7 +328,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ----------------------- | -------- | @@ -372,7 +370,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ----------------------- | -------- | @@ -412,7 +410,7 @@ Will override all current members and administrators for the specified team. **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ----------------------- | -------- | @@ -455,7 +453,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ---------- | -------- | @@ -489,7 +487,7 @@ Content-Type: application/json **Required permissions** -See note in the [introduction]({{< ref "#team-api" >}}) for an explanation. +See note in the [introduction](#team-api) for an explanation. | Action | Scope | | ----------- | -------- | diff --git a/docs/sources/developers/http_api/team_sync.md b/docs/sources/developers/http_api/team_sync.md index 84a5b15679f..c4c0e607a2d 100644 --- a/docs/sources/developers/http_api/team_sync.md +++ b/docs/sources/developers/http_api/team_sync.md @@ -23,9 +23,9 @@ title: Team Sync HTTP API # Team Sync API -> Team Sync is only available in Grafana Enterprise. Read more about [Grafana Enterprise]({{< relref "/docs/grafana/latest/introduction/grafana-enterprise" >}}). +> Team Sync is only available in Grafana Enterprise. Read more about [Grafana Enterprise](/docs/grafana/latest/introduction/grafana-enterprise/). -> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions]({{< relref "/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes" >}}) for more information. +> If you are running Grafana Enterprise, for some endpoints you'll need to have specific permissions. Refer to [Role-based access control permissions](/docs/grafana/latest/administration/roles-and-permissions/access-control/custom-role-actions-scopes/) for more information. ## Get External Groups @@ -33,7 +33,7 @@ title: Team Sync HTTP API **Required permissions** -See note in the [introduction]({{< ref "#external-group-synchronization-api" >}}) for an explanation. +See note in the [introduction](#external-group-synchronization-api) for an explanation. | Action | Scope | | ---------------------- | -------- | @@ -75,7 +75,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#external-group-synchronization-api" >}}) for an explanation. +See note in the [introduction](#external-group-synchronization-api) for an explanation. | Action | Scope | | ----------------------- | -------- | @@ -117,7 +117,7 @@ Status Codes: **Required permissions** -See note in the [introduction]({{< ref "#external-group-synchronization-api" >}}) for an explanation. +See note in the [introduction](#external-group-synchronization-api) for an explanation. | Action | Scope | | ----------------------- | -------- | diff --git a/docs/sources/explore/correlations-editor-in-explore.md b/docs/sources/explore/correlations-editor-in-explore.md index 50053226158..dd0a0ce1936 100644 --- a/docs/sources/explore/correlations-editor-in-explore.md +++ b/docs/sources/explore/correlations-editor-in-explore.md @@ -3,6 +3,7 @@ labels: products: - enterprise - oss + - cloud title: Correlations Editor in Explore weight: 20 --- @@ -13,22 +14,22 @@ weight: 20 The Explore editor is available in 10.1 and later versions. In the editor, transformations is available in Grafana 10.3 and later versions. {{% /admonition %}} -Correlations allow users to build a link between any two data sources. For more information about correlations in general, please see the [correlations]({{< relref "../administration/correlations" >}}) topic in the administration page. +Correlations allow users to build a link between any two data sources. For more information about correlations in general, please see the [correlations](/docs/grafana//administration/correlations/) topic in the administration page. ## Create a correlation 1. In Grafana, navigate to the Explore page. -1. Select a data source that you would like to be [the source data source]({{< relref "../administration/correlations/correlation-configuration#source-data-source-and-result-field" >}}) for a new correlation. -1. Run a query producing data in [a supported visualization]({{< relref "../administration/correlations#correlations" >}}). -1. Click **+ Add** in the top toolbar and select **Add correlation** (you can also select **Correlations Editor** from the [Command Palette]({{< relref "../search#command-palette" >}})). +1. Select a data source that you would like to be [the source data source](/docs/grafana//administration/correlations/correlation-configuration/#source-data-source-and-result-field) for a new correlation. +1. Run a query producing data in [a supported visualization](/docs/grafana//administration/correlations/#correlations). +1. Click **+ Add** in the top toolbar and select **Add correlation** (you can also select **Correlations Editor** from the [Command Palette](/docs/grafana//search/#command-palette)). 1. Explore is now in Correlations Editor mode indicated by a blue border and top bar. You can exit Correlations Editor by clicking **Exit** in the top bar. 1. You can now create the following new correlations for the visualization with links that are attached to the data that you can use to build a new query: - Logs: links are displayed next to field values inside log details for each log row - Table: every table cell is a link 1. Click on a link to add a new correlation. - Links are associated with a field that is used as a [result field of a correlation]({{< relref "../administration/correlations/correlation-configuration" >}}). -1. In the split view that opens, use the right pane to set up [the target query source of the correlation]({{< relref "../administration/correlations/correlation-configuration#target-query" >}}). -1. Build a target query using [variables syntax]({{< relref "../dashboards/variables/variable-syntax" >}}) with variables from the list provided at the top of the pane. The list contains sample values from the selected data row. + Links are associated with a field that is used as a [result field of a correlation](/docs/grafana//administration/correlations/correlation-configuration/). +1. In the split view that opens, use the right pane to set up [the target query source of the correlation](/docs/grafana//administration/correlations/correlation-configuration/#target-query). +1. Build a target query using [variables syntax](/docs/grafana//dashboards/variables/variable-syntax/) with variables from the list provided at the top of the pane. The list contains sample values from the selected data row. 1. Provide a label and description (optional). A label will be used as the name of the link inside the visualization and can contain variables. 1. Provide transformations (optional; see below for details). @@ -37,7 +38,7 @@ Correlations allow users to build a link between any two data sources. For more ## Transformations -Transformations allow you to extract values that exist in a field with other data. For example, using a transformation, you can extract one portion of a log line to use in a correlation. For more details on transformations in correlations, see [Correlations]({{< relref "../administration/correlations/correlation-configuration/#correlation-transformations" >}}). +Transformations allow you to extract values that exist in a field with other data. For example, using a transformation, you can extract one portion of a log line to use in a correlation. For more details on transformations in correlations, see [Correlations](/docs/grafana//explore/correlations-editor-in-explore/#transformations). After clicking one of the generated links in the editor mode, you can add transformations by clicking **Add transformation** in the Transformations dropdown menu. @@ -47,7 +48,7 @@ You can use a transformation in your correlation with the following steps: Select the portion of the field that you want to use for the transformation. For example, a log line. Once selected, the value of this field will be used to assist you in building the transformation. 1. Select the type of the transformation. - See [correlations]({{< relref "../administration/correlations/correlation-configuration/#correlation-transformations" >}}) for the options and relevant settings. + See [correlations](/docs/grafana//explore/correlations-editor-in-explore/#transformations) for the options and relevant settings. 1. Based on your selection, you might see one or more variables populate, or you might need to provide more specifications in options that are displayed. 1. Select **Add transformation to correlation** to add the specified variables to the list of available variables. @@ -57,7 +58,7 @@ For regular expressions in this dialog box, the `mapValue` referred to in other ## Correlations examples -The following examples show how to create correlations using the Correlations Editor in Explore. If you'd like to follow these examples, make sure to set up a [test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). +The following examples show how to create correlations using the Correlations Editor in Explore. If you'd like to follow these examples, make sure to set up a [test data source](/docs/grafana//datasources/testdata/#testdata-data-source). ### Create a text to graph correlation @@ -65,7 +66,7 @@ This example shows how to create a correlation using Correlations Editor in Expl Correlations allow you to use results of one query to run a new query in any data source. In this example, you will run a query that renders tabular data. The data will be used to run a different query that yields a graph result. -To follow this example, make sure you have set up [a test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). +To follow this example, make sure you have set up [a test data source](/docs/grafana//datasources/testdata/#testdata-data-source). 1. In Grafana, navigate to **Explore**. 1. Select the **test data source** from the dropdown menu at the top left of the page. @@ -100,7 +101,7 @@ You can apply the same steps to any data source. Correlations allow you to creat In this example, you will create a correlation to demonstrate how to use transformations to extract values from the log line and another field. -To follow this example, make sure you have set up [a test data source]({{< relref "../datasources/testdata#testdata-data-source" >}}). +To follow this example, make sure you have set up [a test data source](/docs/grafana//datasources/testdata/#testdata-data-source). 1. In Grafana, navigate to **Explore**. 1. Select the **test data source** from the dropdown menu at the top left of the page. diff --git a/docs/sources/explore/get-started-with-explore.md b/docs/sources/explore/get-started-with-explore.md index 7e78e4e80c3..b25f855bac9 100644 --- a/docs/sources/explore/get-started-with-explore.md +++ b/docs/sources/explore/get-started-with-explore.md @@ -38,14 +38,10 @@ Watch the following video to get started using Explore: ## Before you begin -In order to access Explore, you must have either the `editor` or `administrator` role, unless the [`viewers_can_edit` option](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/#viewers_can_edit) is enabled. Refer to [Role and permissions](https://grafana.com/docs/grafana//administration/roles-and-permissions/) for more information on what each role can access. +In order to access Explore, you must have either the `editor` or `administrator` basic role or the `data sources explore` role. Refer to [Role and permissions](https://grafana.com/docs/grafana//administration/roles-and-permissions/) for more information on what each role can access. Refer to [Role-based access control (RBAC)](https://grafana.com/docs/grafana//administration/roles-and-permissions/access-control/) in Grafana Enterprise to understand how you can manage Explore with role-based permissions. -{{< admonition type="note" >}} -If you are using Grafana Cloud, open a [support ticket in the Cloud Portal](https://grafana.com/auth/sign-in) to enable the `viewers_can_edit` option. -{{< /admonition >}} - ## Explore elements Explore consists of a toolbar, outline, query editor, the ability to add multiple queries, a query history and a query inspector. diff --git a/docs/sources/explore/simplified-exploration/_index.md b/docs/sources/explore/simplified-exploration/_index.md index 60612ae02ba..360b37aee5a 100644 --- a/docs/sources/explore/simplified-exploration/_index.md +++ b/docs/sources/explore/simplified-exploration/_index.md @@ -8,27 +8,27 @@ title: Simplified exploration menuTitle: Simplified exploration weight: 100 hero: - title: Simplified exploration with the Explore apps + title: Simplified exploration with the Drilldown apps level: 1 width: 100 height: 100 - description: Use Explore Profiles to investigate and identify issues using profiling data. + description: Use the Grafana Drilldown apps to investigate and identify issues using telemetry data. cards: title_class: pt-0 lh-1 items: - - title: Explore Metrics + - title: Grafana Metrics Drilldown href: ./metrics/ description: Quickly find related metrics with a few clicks, without needing to write PromQL queries to retrieve metrics. height: 24 - - title: Explore Logs + - title: Grafana Logs Drilldown href: ./logs/ description: Visualize log volumes to easily detect anomalies or significant changes over time, without needing to compose LogQL queries. height: 24 - - title: Explore Traces + - title: Grafana Traces Drilldown href: ./traces/ description: Use Rate, Errors, and Duration (RED) metrics derived from traces to investigate and understand errors and latency issues within complex distributed systems. height: 24 - - title: Explore Profiles + - title: Grafana Profiles Drilldown href: ./profiles/ description: View and analyze high-level service performance, identify problem processes for optimization, and diagnose issues to determine root causes. height: 24 @@ -36,14 +36,16 @@ cards: # Simplified exploration -The Grafana Explore apps are designed for effortless data exploration through intuitive, queryless interactions. +The Grafana Drilldown apps are designed for effortless data exploration through intuitive, queryless interactions. Easily explore telemetry signals with these specialized tools, tailored specifically for the Grafana databases to provide quick and accurate insights. +{{< docs/shared source="grafana" lookup="plugins/rename-note.md" version="" >}} + To learn more, read: - [From multi-line queries to no-code investigations: meeting Grafana users where they are](https://grafana.com/blog/2024/10/22/from-multi-line-queries-to-no-code-investigations-meeting-grafana-users-where-they-are/) -- [A queryless experience for exploring metrics, logs, traces, and profiles: Introducing the Explore apps suite for Grafana](https://grafana.com/blog/2024/09/24/queryless-metrics-logs-traces-profiles/). +- [A queryless experience for exploring metrics, logs, traces, and profiles: Introducing the Drilldown apps suite for Grafana](https://grafana.com/blog/2024/09/24/queryless-metrics-logs-traces-profiles/). {{< youtube id="MSHeWWsHaIA" >}} diff --git a/docs/sources/explore/simplified-exploration/metrics/index.md b/docs/sources/explore/simplified-exploration/metrics/index.md index 127dd6cb265..eb6d23509e5 100644 --- a/docs/sources/explore/simplified-exploration/metrics/index.md +++ b/docs/sources/explore/simplified-exploration/metrics/index.md @@ -4,19 +4,21 @@ labels: - cloud - enterprise - oss -title: Explore Metrics +title: Metrics Drilldown aliases: - ../explore-metrics/ # /docs/grafana/latest/explore/explore-metrics/ canonical: https://grafana.com/docs/grafana/latest/explore/simplified-exploration/metrics/ -description: Explore Metrics lets you browse Prometheus-compatible metrics using an intuitive, queryless experience. +description: Grafana Metrics Drilldown lets you browse Prometheus-compatible metrics using an intuitive, queryless experience. weight: 200 --- -# Grafana Explore Metrics +# Grafana Metrics Drilldown -Grafana Explore Metrics is a query-less experience for browsing **Prometheus-compatible** metrics. Quickly find related metrics with just a few simple clicks, without needing to write PromQL queries to retrieve metrics. +Grafana Metrics Drilldown is a query-less experience for browsing **Prometheus-compatible** metrics. Quickly find related metrics with just a few simple clicks, without needing to write PromQL queries to retrieve metrics. -With Explore Metrics, you can: +{{< docs/shared source="grafana" lookup="plugins/rename-note.md" version="" >}} + +With Metrics Drilldown, you can: - Easily segment metrics based on their labels, so you can immediately spot anomalies and identify issues. - Automatically display the optimal visualization for each metric type (gauge vs. counter, for example) without manual setup. @@ -25,26 +27,25 @@ With Explore Metrics, you can: - View a history of user steps when navigating through metrics and their filters. - Seamlessly pivot to related telemetry, including log data. -{{< docs/play title="Explore Metrics" url="https://play.grafana.org/explore/metrics/trail?from=now-1h&to=now&var-ds=grafanacloud-demoinfra-prom&var-filters=&refresh=&metricPrefix=all" >}} +{{< docs/play title="Metrics Drilldown" url="https://play.grafana.org/explore/metrics/trail?from=now-1h&to=now&var-ds=grafanacloud-demoinfra-prom&var-filters=&refresh=&metricPrefix=all" >}} -You can access Explore Metrics either as a standalone experience or as part of Grafana dashboards. +You can access Metrics Drilldown either as a standalone experience or as part of Grafana dashboards. ## Standalone experience -To access Explore Metrics as a standalone experience: +To access Metrics Drilldown as a standalone experience: -1. Click the arrow next to **Explore** in the Grafana left-side menu and click **Metrics**. You are taken to an overview page that shows recent metrics, bookmarks, and the option to select a new metric exploration. -1. To get started with a new exploration, click **+ New metric exploration**. +1. Click the arrow next to **Drilldown** in the Grafana left-side menu and click **Metrics**. You are taken to an overview page that shows recent metrics, bookmarks, and the option to select a new metric exploration. +1. To get started with a new exploration, click **Let's start!**. 1. Select **Prometheus** or any Prometheus-compatible data source available in the drop-down menu under **Data source**. -1. Click **+ Add label** to select a label-value pair from the drop-down menu. You can add multiple label-value pairs. A label type will appear above the selected label with a drop-down list of options from which to choose. For example, if you select the label `container` a drop-down list of available containers appears. +1. Click **+ Add label** to select a label-value pair from the drop-down menu. You can add multiple label-value pairs. A label type appears above the selected label with a drop-down list of options from which to choose. For example, if you select the label `container` a drop-down list of available containers appears. 1. You can also search for metrics using keywords under **Search metrics** in the search bar. 1. Use the time picker to select a date and time range from the drop-down menu or use an absolute time range. 1. Click the down arrow next to the **Refresh** icon to set a refresh rate from the drop-down menu. The default is `Off`. -1. Click the **Settings** icon and toggle **Always keep selected metric graph in-view** to keep your main graph always in view on the Breakdown drill-down tab. The **History** button in the upper left corner tracks every step navigating through metric exploration. -![show metrics explore overview](/media/metrics-explore/metrics-explore-overview.png) +![show metrics explore overview](/media/metrics-explore/metrics-drilldown-overview.png) ### Metrics exploration @@ -54,19 +55,19 @@ To further explore a metric, click **Select** in the upper right corner of the m - The **Overview** tab provides a description for each metric, as well as the metric `type` and `unit` associated with the metric. It also provides a list of labels associated with the metric. Click on any label to view drill-down visualizations. - The **Breakdown** tab depicts time series visualizations for each of the label-value pairs for the selected metric. You can further drill down on each label and click **Add to filter** to add the label/value pair into your filters. You can also change the **View** from grid to rows. -- The **Related metrics** tab depicts related metrics with relevant key words. You can repeat the drill down process for any related metric. Toggle **SHow previews** to preview visualizations. +- The **Related metrics** tab depicts related metrics with relevant key words. You can repeat the drill down process for any related metric. Toggle **Show previews** to preview visualizations. -Once you have gathered your metrics exploration data you can: +After you have gathered your metrics exploration data you can: -- Click the **Explore** icon on the right side to open the graph in Explore, where you can modify the query or add the graph to a dashboard or incident. -- Click the **Share** icon on the right side to copy the metric drill down URL to the clipboard so it can be shared. +- Click the **Open in Explore** icon on the right side to open the graph in Explore, where you can modify the query or add the graph to a dashboard or incident. +- Click the **Copy URL** icon on the right side to copy the metric drill down URL to the clipboard so it can be shared. - Click the **Star** icon on the right side to bookmark and save the metrics exploration. ## Dashboard experience -To access Explore Metrics via a dashboard: +To access Metrics Drilldown via a dashboard: 1. Navigate to your dashboard. 1. Select a time series panel. -1. Click the panel menu in the upper right and select **Explore Metrics**. If there are multiple metrics, click on the one you want to explore. -1. You will see a slide out drawer with the Metrics Experience, starting with the drill down. You can access the standalone experience by clicking **Open** in the upper right. +1. Click the panel menu in the upper right and select **Metrics Drilldown**. If there are multiple metrics, click on the one you want to explore. +1. You see a slide out drawer with the Metrics Experience, starting with the drill down. You can access the standalone experience by clicking **Open** in the upper right. diff --git a/docs/sources/explore/trace-integration.md b/docs/sources/explore/trace-integration.md index f9b0779b12d..532bb3ca8f2 100644 --- a/docs/sources/explore/trace-integration.md +++ b/docs/sources/explore/trace-integration.md @@ -157,7 +157,8 @@ The node graph requires data to be returned from the data source in a specific f ## Service graph -A service graph visualizes span metrics, including rates, error rates, and durations (RED), along with service relationships. Once the requirements are configured, this pre-configured view is immediately available. +A service graph visualizes rates, error rates, and durations (RED), along with service relationships. +After the requirements are configured, this pre-configured view is immediately available. For additional information refer to the following documentation: diff --git a/docs/sources/fundamentals/exemplars/index.md b/docs/sources/fundamentals/exemplars/index.md index 363bc122b47..4181c50cac5 100644 --- a/docs/sources/fundamentals/exemplars/index.md +++ b/docs/sources/fundamentals/exemplars/index.md @@ -20,21 +20,31 @@ weight: 800 # Introduction to exemplars -An exemplar is a specific trace representative of measurement taken in a given time interval. While metrics excel at giving you an aggregated view of your system, traces give you a fine grained view of a single request; exemplars are a way to link the two. +An exemplar is a specific trace representative of measurement taken in a given time interval. +While metrics excel at giving you an aggregated view of your system, traces give you a fine grained view of a single request; exemplars are a way to link the two. -Suppose your company website is experiencing a surge in traffic volumes. While more than eighty percent of the users are able to access the website in under two seconds, some users are experiencing a higher than normal response time resulting in bad user experience. +Suppose your company website is experiencing a surge in traffic volumes. +While more than eighty percent of the users are able to access the website in under two seconds, some users are experiencing a higher than normal response time resulting in bad user experience. -To identify the factors that are contributing to the latency, you must compare a trace for a fast response against a trace for a slow response. Given the vast amount of data in a typical production environment, it will be extremely laborious and time-consuming effort. +To identify the factors that are contributing to the latency, you must compare a trace for a fast response against a trace for a slow response. +Given the vast amount of data in a typical production environment, it's an extremely laborious and time-consuming effort. -Use exemplars to help isolate problems within your data distribution by pinpointing query traces exhibiting high latency within a time interval. Once you localize the latency problem to a few exemplar traces, you can combine it with additional system based information or location properties to perform a root cause analysis faster, leading to quick resolutions to performance issues. +Use exemplars to help isolate problems within your data distribution by pinpointing query traces exhibiting high latency within a time interval. +After you localize the latency problem to a few exemplar traces, you can combine it with additional system based information or location properties to perform a root cause analysis faster, leading to quick resolutions to performance issues. -Support for exemplars is available for the Prometheus data source only. Once you enable the functionality, exemplar data is available by default. For more information on exemplar configuration and how to enable exemplars, refer to [configuring exemplars in the Prometheus data source]({{< relref "../../datasources/prometheus/configure-prometheus-data-source#exemplars" >}}). +Support for exemplars is available for the Prometheus data source only. +After you enable the functionality, exemplar data is available by default. +For more information on exemplar configuration and how to enable exemplars, refer to [configuring exemplars in the Prometheus data source](../../datasources/prometheus/configure-prometheus-data-source/#exemplars). -Grafana shows exemplars alongside a metric in the Explore view and in dashboards. Each exemplar displays as a highlighted star. You can hover your cursor over an exemplar to view the unique trace ID, which is a combination of a key value pair. To investigate further, click the blue button next to the `traceID` property. +Grafana shows exemplars alongside a metric in the Explore view and in dashboards. +Each exemplar displays as a highlighted star. +You can hover your cursor over an exemplar to view the unique trace ID, which is a combination of a key value pair. +To investigate further, click the blue button next to the `traceID` property. {{< figure src="/media/docs/grafana/exemplars/screenshot-exemplars.png" class="docs-image--no-shadow" max-width= "750px" caption="Screenshot showing the detail window of an exemplar" >}} -Refer to [View exemplar data]({{< relref "#view-exemplar-data" >}}) for instructions on how to drill down and view exemplar trace details from metrics and logs. To know more about exemplars, refer to the blogpost [Intro to exemplars, which enable Grafana Tempo’s distributed tracing at massive scale](/blog/2021/03/31/intro-to-exemplars-which-enable-grafana-tempos-distributed-tracing-at-massive-scale/). +Refer to [View exemplar data](#view-exemplar-data) for instructions on how to drill down and view exemplar trace details from metrics and logs. +To know more about exemplars, refer to the blog post [Intro to exemplars, which enable Grafana Tempo’s distributed tracing at massive scale](/blog/2021/03/31/intro-to-exemplars-which-enable-grafana-tempos-distributed-tracing-at-massive-scale/). ## View exemplar data @@ -42,15 +52,19 @@ When support for exemplar support is enabled for a Prometheus data source, you c ### In Explore -Explore visualizes exemplar traces as highlighted stars alongside metrics data. For more information on how Explore visualizes trace data, refer to [Tracing in Explore]({{< relref "../../explore/trace-integration" >}}). +Explore visualizes exemplar traces as highlighted stars alongside metrics data. +For more information on how Explore visualizes trace data, refer to [Tracing in Explore](../../explore/trace-integration/). To examine the details of an exemplar trace: -1. Place your cursor over an exemplar (highlighted star). Depending on the trace data source you are using, you will see a blue button with the label `Query with `. In the following example, the tracing data source is Tempo. +1. Place your cursor over an exemplar (highlighted star). + Depending on the trace data source you are using, you may see a blue button with the label `Query with `. + In the following example, the tracing data source is Tempo. {{< figure src="/media/docs/grafana/exemplars/screenshot-exemplar-details.png" class="docs-image--no-shadow" max-width= "350px" caption="Screenshot showing exemplar details" >}} -1. Click the **Query with Tempo** option next to the `traceID` property. The trace details, including the spans within the trace are listed in a separate panel on the right. +1. Click the **Query with Tempo** option next to the `traceID` property. + The trace details, including the spans within the trace are listed in a separate panel on the right. {{< figure src="/media/docs/grafana/exemplars/screenshot-exemplar-explore-view.png" class="docs-image--no-shadow" max-width= "900px" caption="Explorer view with panel showing trace details" >}} @@ -58,13 +72,20 @@ For more information on how to drill down and analyze the trace and span details ### In logs -You can also view exemplar trace details from the Loki logs in Explore. Use regex within the Derived fields links for Loki to extract the `traceID` information. Now when you expand Loki logs, you can see a `traceID` property under the **Detected fields** section. To learn more about how to extract a part of a log message into an internal or external link, refer to [using derived fields in Loki]({{< relref "../../explore/logs-integration" >}}). +You can also view exemplar trace details from the Loki logs in Explore. +Use regular expressions within the Derived fields links for Loki to extract the `traceID` information. +Now when you expand Loki logs, you can see a `traceID` property under the **Detected fields** section. +To learn more about how to extract a part of a log message into an internal or external link, refer to [using derived fields in Loki](../../explore/logs-integration/). To view the details of an exemplar trace: -1. Expand a log line and scroll down to the `Fields` section. Depending on your backend trace data source, you will see a blue button with the label ``. +1. Expand a log line and scroll down to the `Fields` section. + Depending on your backend trace data source, you may see a blue button with the label ``. -1. Click the blue button next to the `traceID` property. Typically, it will have the name of the backend data source. In the following example, the tracing data source is Tempo. The trace details, including the spans within the trace are listed in a separate panel on the right. +1. Click the blue button next to the `traceID` property. + Typically, it has the name of the backend data source. + In the following example, the tracing data source is Tempo. + The trace details, including the spans within the trace are listed in a separate panel on the right. {{< figure src="/media/docs/grafana/exemplars/screenshot-exemplar-loki-logs.png" class="docs-image--no-shadow" max-width= "750px" caption="Explorer view with panel showing trace details" >}} @@ -78,16 +99,20 @@ This panel shows the details of the trace in different segments. You can add more traces to the results using the `Add query` button. -- The next segment shows the entire span for the specific trace as a narrow strip. All levels of the trace from the client all the way down to database query is displayed, which provides a bird's eye view of the time distribution across all layers over which the HTTP request was processed. +- The next segment shows the entire span for the specific trace as a narrow strip. + All levels of the trace from the client all the way down to database query is displayed, which provides a bird's eye view of the time distribution across all layers over which the HTTP request was processed. 1. You can click within this strip view to display a magnified view of a smaller time segment within the span. This magnified view shows up in the bottom segment of the panel. 1. In the magnified view, you can expand or collapse the various levels of the trace to drill down to the specific span of interest. - For example, if the strip view shows that most of the latency was within the app layer, you can expand the trace down the app layer to investigate the problem further. To expand a particular layer of span, click the left icon. The same button can collapse an expanded span. + For example, if the strip view shows that most of the latency was within the app layer, you can expand the trace down the app layer to investigate the problem further. + To expand a particular layer of span, click the left icon. + The same button can collapse an expanded span. - To see the details of the span at any level, click the span itself. - This displays additional metadata associated with the span. The metadata itself is initially shown in a narrow strip but you can see more details by clicking the metadata strip. + This displays additional metadata associated with the span. + The metadata itself is initially shown in a narrow strip but you can see more details by clicking the metadata strip. {{< figure src="/media/docs/grafana/exemplars/screenshot-exemplar-span-details.png" class="docs-image--no-shadow" max-width= "600px" caption="Span details" >}} diff --git a/docs/sources/getting-started/_index.md b/docs/sources/getting-started/_index.md index 6252d05cd40..752757401dd 100644 --- a/docs/sources/getting-started/_index.md +++ b/docs/sources/getting-started/_index.md @@ -14,6 +14,6 @@ weight: 9 Grafana helps you collect, correlate, and visualize data with beautiful dashboards — the open source data visualization and monitoring solution that drives informed decisions, enhances system performance, and streamlines troubleshooting. -This section provides guidance to our open source community about how to build your first dashboard after you have installed Grafana. It also provides step-by-step instructions on how to add a Prometheus, InfluxDB, or an MS SQL Server data source. If you are connecting a different data source, please refer to our complete list of supported [Data sources]({{< relref "../datasources" >}}). If you would like to learn how to get started with Grafana Cloud, our fully managed observability stack, visit the [Grafana Cloud documentation](https://grafana.com/docs/grafana-cloud/quickstart/) for more information. +This section provides guidance to our open source community about how to build your first dashboard after you have installed Grafana. It also provides step-by-step instructions on how to add a Prometheus, InfluxDB, or an MS SQL Server data source. If you are connecting a different data source, please refer to our complete list of supported [Data sources](../datasources/). If you would like to learn how to get started with Grafana Cloud, our fully managed observability stack, visit the [Grafana Cloud documentation](https://grafana.com/docs/grafana-cloud/quickstart/) for more information. {{< section >}} diff --git a/docs/sources/getting-started/get-started-grafana-influxdb.md b/docs/sources/getting-started/get-started-grafana-influxdb.md index d6a163a1219..fed06324346 100644 --- a/docs/sources/getting-started/get-started-grafana-influxdb.md +++ b/docs/sources/getting-started/get-started-grafana-influxdb.md @@ -38,11 +38,11 @@ Windows users might need to make additional adjustments. Look for special instru You can have more than one InfluxDB data source defined in Grafana. -1. Follow the general instructions to [add a data source]({{< relref "../datasources#add-a-data-source" >}}). +1. Follow the general instructions to [add a data source](../../datasources/#add-a-data-source). 1. Decide if you will use InfluxQL or Flux as your query language. - - [Configure the data source]({{< relref "../datasources/influxdb#configure-the-data-source" >}}) for your chosen query language. + - [Configure the data source](../../datasources/influxdb/#configure-the-data-source) for your chosen query language. Each query language has its own unique data source settings. - - For querying features specific to each language, see the data source's [query editor documentation]({{< relref "../datasources/influxdb/query-editor" >}}). + - For querying features specific to each language, see the data source's [query editor documentation](../../datasources/influxdb/query-editor/). ##### InfluxDB guides @@ -75,8 +75,8 @@ Grafana displays a list of possible series. Click one to select it, and Grafana Create a simple Flux query. -1. [Add a panel]({{< relref "../dashboards/build-dashboards/create-dashboard" >}}). -1. In the query editor, select your InfluxDB-Flux data source. For more information, refer to [Queries]({{< relref "../panels-visualizations/query-transform-data" >}}). +1. [Add a panel](../../dashboards/build-dashboards/create-dashboard/). +1. In the query editor, select your InfluxDB-Flux data source. For more information, refer to [Queries](../../panels-visualizations/query-transform-data/). 1. Select the **Table** visualization. 1. In the query editor text field, enter `buckets()` and then click outside of the query editor. @@ -96,12 +96,12 @@ You can also create Flux queries in the InfluxDB Explore view. ![InfluxDB Explore Script Editor](/static/img/docs/influxdb/explore-query-text-7-5.png) -1. In Grafana, [add a panel]({{< relref "../dashboards/build-dashboards/create-dashboard" >}}) and then paste your Flux code into the query editor. +1. In Grafana, [add a panel](../../dashboards/build-dashboards/create-dashboard/) and then paste your Flux code into the query editor. 1. Click **Apply**. Your new panel should be visible with data from your Flux query. #### Check InfluxDB metrics in Grafana Explore -In your Grafana instance, go to the [Explore]({{< relref "../explore" >}}) view and build queries to experiment with the metrics you want to monitor. Here you can also debug issues related to collecting metrics. +In your Grafana instance, go to the [Explore](../../explore/) view and build queries to experiment with the metrics you want to monitor. Here you can also debug issues related to collecting metrics. #### Start building dashboards @@ -109,5 +109,5 @@ There you go! Use Explore and Data Explorer to experiment with your data, and ad Here are some resources to learn more: -- Grafana documentation: [InfluxDB data source]({{< relref "../datasources/influxdb" >}}) +- Grafana documentation: [InfluxDB data source](../../datasources/influxdb/) - InfluxDB documentation: [Comparison of Flux vs InfluxQL](https://docs.influxdata.com/influxdb/v1.8/flux/flux-vs-influxql/) diff --git a/docs/sources/getting-started/get-started-grafana-ms-sql-server.md b/docs/sources/getting-started/get-started-grafana-ms-sql-server.md index 2ca4dcac2b4..9b714940d4b 100644 --- a/docs/sources/getting-started/get-started-grafana-ms-sql-server.md +++ b/docs/sources/getting-started/get-started-grafana-ms-sql-server.md @@ -24,7 +24,7 @@ MS SQL Server can be installed on Windows or Linux operating systems and also on You can install MS SQL Server on the host running Grafana or on a remote server. To install the software from the [downloads page](https://www.microsoft.com/en-us/sql-server/sql-server-downloads), follow their setup prompts. -If you are on a Windows host but want to use Grafana and MS SQL data source on a Linux environment, refer to the [WSL to set up your Grafana development environment](/blog/2021/03/03/.how-to-set-up-a-grafana-development-environment-on-a-windows-pc-using-wsl). This will allow you to leverage the resources available in [grafana/grafana](https://github.com/grafana/grafana) GitHub repository. Here you will find a collection of supported data sources, including MS SQL Server, along with test data and pre-configured dashboards for use. +If you are on a Windows host but want to use Grafana and MS SQL data source on a Linux environment, refer to the [WSL to set up your Grafana development environment](/blog/2021/03/03/how-to-set-up-a-grafana-development-environment-on-a-windows-pc-using-wsl) blog post. This will allow you to leverage the resources available in [grafana/grafana](https://github.com/grafana/grafana) GitHub repository. Here you will find a collection of supported data sources, including MS SQL Server, along with test data and pre-configured dashboards for use. #### Add the MS SQL data source @@ -99,6 +99,6 @@ Optionally, play around this dashboard and customize it to: Now that you have gained some idea of using the pre-packaged MS SQL data source and some test data, the next step is to setup your own instance of MS SQL Server database and data your development or sandbox area. -To fetch data from your own instance of MS SQL Server, add the data source using instructions in Step 4 of this topic. In Grafana [Explore]({{< relref "../explore" >}}) build queries to experiment with the metrics you want to monitor. +To fetch data from your own instance of MS SQL Server, add the data source using instructions in Step 4 of this topic. In Grafana [Explore](../../explore/) build queries to experiment with the metrics you want to monitor. -Once you have a curated list of queries, create [dashboards]({{< relref "../dashboards" >}}) to render metrics from the SQL Server database. For troubleshooting, user permissions, known issues, and query examples, refer to [Using Microsoft SQL Server in Grafana]({{< relref "../datasources/mssql" >}}). +Once you have a curated list of queries, create [dashboards](../../dashboards/) to render metrics from the SQL Server database. For troubleshooting, user permissions, known issues, and query examples, refer to [Using Microsoft SQL Server in Grafana](../../datasources/mssql/). diff --git a/docs/sources/getting-started/get-started-grafana-prometheus.md b/docs/sources/getting-started/get-started-grafana-prometheus.md index 1ed833b034a..188460d7896 100644 --- a/docs/sources/getting-started/get-started-grafana-prometheus.md +++ b/docs/sources/getting-started/get-started-grafana-prometheus.md @@ -114,11 +114,11 @@ To configure your Prometheus instance to work with Grafana locally instead of Gr #### Check Prometheus metrics in Grafana Explore view -In your Grafana instance, go to the [Explore]({{< relref "../explore" >}}) view and build queries to experiment with the metrics you want to monitor. Here you can also debug issues related to collecting metrics from Prometheus. +In your Grafana instance, go to the [Explore](../../explore/) view and build queries to experiment with the metrics you want to monitor. Here you can also debug issues related to collecting metrics from Prometheus. #### Start building dashboards -Now that you have a curated list of queries, create [dashboards]({{< relref "../dashboards" >}}) to render system metrics monitored by Prometheus. When you install Prometheus and node_exporter or windows_exporter, you will find recommended dashboards for use. +Now that you have a curated list of queries, create [dashboards](../../dashboards/) to render system metrics monitored by Prometheus. When you install Prometheus and node_exporter or windows_exporter, you will find recommended dashboards for use. The following image shows a dashboard with three panels showing some system metrics. @@ -126,5 +126,5 @@ The following image shows a dashboard with three panels showing some system metr To learn more: -- Grafana documentation: [Prometheus data source]({{< relref "../datasources/prometheus" >}}) +- Grafana documentation: [Prometheus data source](../../datasources/prometheus/) - Prometheus documentation: [What is Prometheus?](https://prometheus.io/docs/introduction/overview/) diff --git a/docs/sources/introduction/_index.md b/docs/sources/introduction/_index.md index 0c64bc5f355..9aba0f1cd48 100644 --- a/docs/sources/introduction/_index.md +++ b/docs/sources/introduction/_index.md @@ -16,35 +16,35 @@ weight: 5 [Grafana open source software](/oss/) enables you to query, visualize, alert on, and explore your metrics, logs, and traces wherever they are stored. Grafana OSS provides you with tools to turn your time-series database (TSDB) data into insightful graphs and visualizations. The Grafana OSS plugin framework also enables you to connect other data sources like NoSQL/SQL databases, ticketing tools like Jira or ServiceNow, and CI/CD tooling like GitLab. -After you have [installed Grafana]({{< relref "../setup-grafana/installation" >}}) and set up your first dashboard using instructions in [Getting started with Grafana]({{< relref "../getting-started/build-first-dashboard" >}}), you will have many options to choose from depending on your requirements. For example, if you want to view weather data and statistics about your smart home, then you can create a [playlist]({{< relref "../dashboards/create-manage-playlists" >}}). If you are the administrator for an enterprise and are managing Grafana for multiple teams, then you can set up [provisioning]({{< relref "../administration/provisioning" >}}) and [authentication]({{< relref "../setup-grafana/configure-security/configure-authentication" >}}). +After you have [installed Grafana](../setup-grafana/installation/) and set up your first dashboard using instructions in [Getting started with Grafana](../getting-started/build-first-dashboard/), you will have many options to choose from depending on your requirements. For example, if you want to view weather data and statistics about your smart home, then you can create a [playlist](../dashboards/create-manage-playlists/). If you are the administrator for an enterprise and are managing Grafana for multiple teams, then you can set up [provisioning](../administration/provisioning/) and [authentication](../setup-grafana/configure-security/configure-authentication/). The following sections provide an overview of Grafana features and links to product documentation to help you learn more. For more guidance and ideas, check out our [Grafana Community forums](https://community.grafana.com/). ## Explore metrics, logs, and traces -Explore your data through ad-hoc queries and dynamic drilldown. Split view and compare different time ranges, queries and data sources side by side. Refer to [Explore]({{< relref "../explore" >}}) for more information. +Explore your data through ad-hoc queries and dynamic drilldown. Split view and compare different time ranges, queries and data sources side by side. Refer to [Explore](../explore/) for more information. ## Alerts If you're using Grafana Alerting, then you can have alerts sent through a number of different alert notifiers, including PagerDuty, SMS, email, VictorOps, OpsGenie, or Slack. -Alert hooks allow you to create different notifiers with a bit of code if you prefer some other channels of communication. Visually define [alert rules]({{< relref "../alerting/alerting-rules" >}}) for your most important metrics. +Alert hooks allow you to create different notifiers with a bit of code if you prefer some other channels of communication. Visually define [alert rules](../alerting/alerting-rules/) for your most important metrics. ## Annotations Annotate graphs with rich events from different data sources. Hover over events to see the full event metadata and tags. -This feature, which shows up as a graph marker in Grafana, is useful for correlating data in case something goes wrong. You can create the annotations manually—just control-click on a graph and input some text—or you can fetch data from any data source. Refer to [Annotations]({{< relref "../dashboards/build-dashboards/annotate-visualizations" >}}) for more information. +This feature, which shows up as a graph marker in Grafana, is useful for correlating data in case something goes wrong. You can create the annotations manually—just control-click on a graph and input some text—or you can fetch data from any data source. Refer to [Annotations](../dashboards/build-dashboards/annotate-visualizations/) for more information. ## Dashboard variables -[Template variables]({{< relref "../dashboards/variables" >}}) allow you to create dashboards that can be reused for lots of different use cases. Values aren't hard-coded with these templates, so for instance, if you have a production server and a test server, you can use the same dashboard for both. +[Template variables](../dashboards/variables/) allow you to create dashboards that can be reused for lots of different use cases. Values aren't hard-coded with these templates, so for instance, if you have a production server and a test server, you can use the same dashboard for both. Templating allows you to drill down into your data, say, from all data to North America data, down to Texas data, and beyond. You can also share these dashboards across teams within your organization—or if you create a great dashboard template for a popular data source, you can contribute it to the whole community to customize and use. ## Configure Grafana -If you're a Grafana administrator, then you'll want to thoroughly familiarize yourself with [Grafana configuration options]({{< relref "../setup-grafana/configure-grafana" >}}) and the [Grafana CLI]({{< relref "../cli" >}}). +If you're a Grafana administrator, then you'll want to thoroughly familiarize yourself with [Grafana configuration options](../setup-grafana/configure-grafana/) and the [Grafana CLI](../cli/). Configuration covers both config files and environment variables. You can set up default ports, logging levels, email IP addresses, security, and more. @@ -54,19 +54,19 @@ Discover hundreds of [dashboards](/grafana/dashboards) and [plugins](/grafana/pl ## Authentication -Grafana supports different authentication methods, such as LDAP and OAuth, and allows you to map users to organizations. Refer to the [User authentication overview]({{< relref "../setup-grafana/configure-security/configure-authentication" >}}) for more information. +Grafana supports different authentication methods, such as LDAP and OAuth, and allows you to map users to organizations. Refer to the [User authentication overview](../setup-grafana/configure-security/configure-authentication/) for more information. -In Grafana Enterprise, you can also map users to teams: If your company has its own authentication system, Grafana allows you to map the teams in your internal systems to teams in Grafana. That way, you can automatically give people access to the dashboards designated for their teams. Refer to [Grafana Enterprise]({{< relref "./grafana-enterprise" >}}) for more information. +In Grafana Enterprise, you can also map users to teams: If your company has its own authentication system, Grafana allows you to map the teams in your internal systems to teams in Grafana. That way, you can automatically give people access to the dashboards designated for their teams. Refer to [Grafana Enterprise](grafana-enterprise/) for more information. ## Provisioning While it's easy to click, drag, and drop to create a single dashboard, power users in need of many dashboards will want to automate the setup with a script. You can script anything in Grafana. -For example, if you're spinning up a new Kubernetes cluster, you can also spin up a Grafana automatically with a script that would have the right server, IP address, and data sources preset and locked in so users cannot change them. It's also a way of getting control over a lot of dashboards. Refer to [Provisioning]({{< relref "../administration/provisioning" >}}) for more information. +For example, if you're spinning up a new Kubernetes cluster, you can also spin up a Grafana automatically with a script that would have the right server, IP address, and data sources preset and locked in so users cannot change them. It's also a way of getting control over a lot of dashboards. Refer to [Provisioning](../administration/provisioning/) for more information. ## Permissions -When organizations have one Grafana and multiple teams, they often want the ability to both keep things separate and share dashboards. You can create a team of users and then set permissions on [folders and dashboards]({{< relref "../administration/user-management/manage-dashboard-permissions" >}}), and down to the [data source level]({{< relref "../administration/data-source-management#data-source-permissions" >}}) if you're using [Grafana Enterprise]({{< relref "./grafana-enterprise" >}}). +When organizations have one Grafana and multiple teams, they often want the ability to both keep things separate and share dashboards. You can create a team of users and then set permissions on [folders and dashboards](../administration/user-management/manage-dashboard-permissions/), and down to the [data source level](../administration/data-source-management/#data-source-permissions) if you're using [Grafana Enterprise](grafana-enterprise/). ## Other Grafana Labs OSS Projects diff --git a/docs/sources/introduction/grafana-enterprise.md b/docs/sources/introduction/grafana-enterprise.md index 7de85993dc6..15db695b9bc 100644 --- a/docs/sources/introduction/grafana-enterprise.md +++ b/docs/sources/introduction/grafana-enterprise.md @@ -13,7 +13,7 @@ weight: 200 Grafana Enterprise is a commercial edition of Grafana that includes additional features not found in the open source version. -Building on everything you already know and love about Grafana open source, Grafana Enterprise includes [exclusive datasource plugins]({{< relref "#enterprise-data-sources" >}}) and [additional features]({{< relref "#enterprise-features" >}}). You also get 24x7x365 support and training from the core Grafana team. +Building on everything you already know and love about Grafana open source, Grafana Enterprise includes [exclusive data source plugins](#enterprise-data-sources) and [additional features](#enterprise-features). You also get 24x7x365 support and training from the core Grafana team. To learn more about Grafana Enterprise, refer to [our product page](/enterprise). @@ -21,7 +21,7 @@ To learn more about Grafana Enterprise, refer to [our product page](/enterprise) Many Grafana Enterprise features are also available in [Grafana Cloud](/docs/grafana-cloud) Free, Pro, and Advanced accounts. For details, refer to [Grafana Cloud pricing](/pricing/#featuresTable). -To migrate to Grafana Cloud, refer to [Migrate from Grafana Enterprise to Grafana Cloud](/docs/grafana-cloud/account-management/e2c-guide/). +To migrate to Grafana Cloud, refer to [Migrate from Grafana Enterprise to Grafana Cloud](/docs/grafana//administration/migration-guide/) ## Authentication @@ -29,48 +29,48 @@ Grafana Enterprise includes integrations with more ways to authenticate your use ### Team sync -[Team sync]({{< relref "../setup-grafana/configure-security/configure-team-sync" >}}) allows you to set up synchronization between teams in Grafana and teams in your auth provider so that your users automatically end up in the right team. +[Team sync](/docs/grafana//setup-grafana/configure-security/configure-team-sync/) allows you to set up synchronization between teams in Grafana and teams in your auth provider so that your users automatically end up in the right team. Supported auth providers: -- [Auth Proxy]({{< relref "../setup-grafana/configure-security/configure-authentication/auth-proxy#team-sync-enterprise-only" >}}) -- [Azure AD](https://grafana.com/docs/grafana//configure-security/configure-authentication/azuread#group-sync-enterprise-only) -- [Generic OAuth integration](https://grafana.com/docs/grafana//configure-security/configure-authentication/generic-oauth#configure-group-synchronization" >}}) -- [GitHub OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/github#configure-group-synchronization) -- [GitLab OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/gitlab#configure-group-synchronization) -- [Google OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/google#configure-group-synchronization) -- [LDAP](https://grafana.com/docs/grafana//configure-security/configure-authentication/enhanced-ldap#ldap-group-synchronization) -- [Okta](https://grafana.com/docs/grafana//configure-security/configure-authentication/okta#configure-group-synchronization-enterprise-only) -- [SAML](https://grafana.com/docs/grafana//configure-security/configure-authentication/saml#configure-group-synchronization) +- [Auth Proxy](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/auth-proxy#team-sync-enterprise-only) +- [Azure AD](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/azuread#group-sync-enterprise-only) +- [Generic OAuth integration](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/generic-oauth#configure-group-synchronization) +- [GitHub OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/github#configure-group-synchronization) +- [GitLab OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/gitlab#configure-group-synchronization) +- [Google OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/google#configure-group-synchronization) +- [LDAP](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/enhanced-ldap#ldap-group-synchronization) +- [Okta](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/okta#configure-group-synchronization-enterprise-only) +- [SAML](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/saml#configure-group-synchronization) ### Enhanced LDAP integration -With [enhanced LDAP integration]({{< relref "../setup-grafana/configure-security/configure-authentication/enhanced-ldap" >}}), you can set up active LDAP synchronization. +With [enhanced LDAP integration](/docs/grafana//setup-grafana/configure-security/configure-authentication/enhanced-ldap/), you can set up active LDAP synchronization. ### SAML authentication -[SAML authentication]({{< relref "../setup-grafana/configure-security/configure-authentication/saml" >}}) enables users to authenticate with single sign-on services that use Security Assertion Markup Language (SAML). +[SAML authentication](/docs/grafana//setup-grafana/configure-security/configure-authentication/saml/) enables users to authenticate with single sign-on services that use Security Assertion Markup Language (SAML). ### Protected roles -With [protected roles]({{< relref "../setup-grafana/configure-security/configure-authentication#protected-roles" >}}), you can define user roles that are exempt from being converted from one authentication type to another when changing auth providers. +With [protected roles](/docs/grafana//setup-grafana/configure-security/configure-authentication/#protected-roles), you can define user roles that are exempt from being converted from one authentication type to another when changing auth providers. ## Enterprise features Grafana Enterprise adds the following features: -- [Role-based access control]({{< relref "../administration/roles-and-permissions/access-control" >}}) to control access with role-based permissions. -- [Data source permissions]({{< relref "../administration/data-source-management#data-source-permissions" >}}) to restrict query access to specific teams and users. -- [Data source query and resource caching]({{< relref "../administration/data-source-management#query-and-resource-caching" >}}) to temporarily store query results in Grafana to reduce data source load and rate limiting. -- [Reporting]({{< relref "../dashboards/create-reports" >}}) to generate a PDF report from any dashboard and set up a schedule to have it emailed to whomever you choose. -- [Export dashboard as PDF]({{< relref "../dashboards/share-dashboards-panels#export-a-dashboard-as-pdf" >}}) -- [Custom branding]({{< relref "../setup-grafana/configure-grafana/configure-custom-branding" >}}) to customize Grafana from the brand and logo to the footer links. -- [Usage insights]({{< relref "../dashboards/assess-dashboard-usage" >}}) to understand how your Grafana instance is used. -- [Recorded queries]({{< relref "../administration/recorded-queries" >}}) to see trends over time for your data sources. -- [Vault integration]({{< relref "../setup-grafana/configure-security/configure-database-encryption#encrypting-your-database-with-a-key-from-a-key-management-service-kms" >}}) to manage your configuration or provisioning secrets with Vault. -- [Auditing]({{< relref "../setup-grafana/configure-security/audit-grafana" >}}) tracks important changes to your Grafana instance to help you manage and mitigate suspicious activity and meet compliance requirements. -- [Request security]({{< relref "../setup-grafana/configure-security/configure-request-security" >}}) makes it possible to restrict outgoing requests from the Grafana server. -- [Settings updates at runtime]({{< relref "../setup-grafana/configure-grafana/settings-updates-at-runtime" >}}) allows you to update Grafana settings at runtime without requiring a restart. +- [Role-based access control](https://grafana.com/docs/grafana//administration/roles-and-permissions/access-control/) to control access with role-based permissions. +- [Data source permissions](https://grafana.com/docs/grafana//administration/data-source-management/#data-source-permissions) to restrict query access to specific teams and users. +- [Data source query and resource caching](https://grafana.com/docs/grafana//administration/data-source-management/#query-and-resource-caching) to temporarily store query results in Grafana to reduce data source load and rate limiting. +- [Reporting](https://grafana.com/docs/grafana//dashboards/create-reports/) to generate a PDF report from any dashboard and set up a schedule to have it emailed to whomever you choose. +- [Export dashboard as PDF](https://grafana.com/docs/grafana//dashboards/share-dashboards-panels/#export-a-dashboard-as-pdf) +- [Custom branding](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/configure-custom-branding/) to customize Grafana from the brand and logo to the footer links. +- [Usage insights](https://grafana.com/docs/grafana//dashboards/assess-dashboard-usage/) to understand how your Grafana instance is used. +- [Recorded queries](https://grafana.com/docs/grafana//administration/recorded-queries/) to see trends over time for your data sources. +- [Vault integration](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-database-encryption/#encrypting-your-database-with-a-key-from-a-key-management-service-kms) to manage your configuration or provisioning secrets with Vault. +- [Auditing](https://grafana.com/docs/grafana//setup-grafana/configure-security/audit-grafana/) tracks important changes to your Grafana instance to help you manage and mitigate suspicious activity and meet compliance requirements. +- [Request security](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-request-security/) makes it possible to restrict outgoing requests from the Grafana server. +- [Settings updates at runtime](https://grafana.com/docs/grafana//setup-grafana/configure-grafana/settings-updates-at-runtime/) allows you to update Grafana settings at runtime without requiring a restart. ## Enterprise data sources diff --git a/docs/sources/panels-visualizations/configure-data-links/index.md b/docs/sources/panels-visualizations/configure-data-links/index.md index 31bf6df9b67..2b057694e6c 100644 --- a/docs/sources/panels-visualizations/configure-data-links/index.md +++ b/docs/sources/panels-visualizations/configure-data-links/index.md @@ -18,16 +18,21 @@ labels: - cloud - enterprise - oss -menuTitle: Configure data links -title: Configure data links +menuTitle: Configure data links and actions +title: Configure data links and actions description: Configure data links to create links between dashboards and link to external resources weight: 80 refs: + api-settings: + - pattern: /docs/grafana/ + destination: /docs/grafana//panels-visualizations/visualizations/canvas/#button-api-options + - pattern: /docs/grafana-cloud/ + destination: /docs/grafana/latest/panels-visualizations/visualizations/canvas/#button-api-options global-variables: - pattern: /docs/grafana/ - destination: /docs/grafana//dashboards/variables/add-template-variables/#**from-and-**to + destination: /docs/grafana//dashboards/variables/add-template-variables/#__from-and-__to - pattern: /docs/grafana-cloud/ - destination: /docs/grafana-cloud/visualizations/dashboards/variables/add-template-variables/#**from-and-**to + destination: /docs/grafana-cloud/visualizations/dashboards/variables/add-template-variables/#__from-and-__to heatmap: - pattern: /docs/grafana/ destination: /docs/grafana//panels-visualizations/visualizations/heatmap/ @@ -125,9 +130,14 @@ refs: destination: /docs/grafana-cloud/visualizations/panels-visualizations/visualizations/bar-chart/ --- -# Configure data links +# Configure data links and actions -Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. 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. +_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls. +In both cases, you can carry out these tasks while maintaining the context of the source panel. + +## Data links + +With data 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. 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: @@ -139,7 +149,7 @@ For visualizations like stat, gauge, or bar gauge you can click anywhere on the 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 +### Supported visualizations You can configure data links for the following visualizations: @@ -164,11 +174,32 @@ You can configure data links for the following visualizations: {{< /column-list >}} -## Data link variables +## Actions -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. +Using actions, you can trigger processes like starting or shutting down a server, directly from a dashboard panel. [API settings](ref:api-settings) are configured in the **Add action** dialog box. You can also pass variables in the API editor. -To see a list of available variables, enter `$` in the data link **URL** field. +### Supported visualizations + +You can configure actions for the following visualizations: + +{{< column-list >}} + +- [Bar chart](ref:bar-chart) +- [Candlestick](ref:candlestick) +- [State timeline](ref:state-timeline) +- [Status history](ref:status-history) +- [Table](ref:table) +- [Time series](ref:time-series) +- [Trend](ref:trend) +- [XY chart](ref:xy-chart) + +{{< /column-list >}} + +## Data link and action variables {#data-link-variables} + +Variables in data links and actions let you send people to a detailed dashboard or trigger an API call 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, enter `$` in the data link or action **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. @@ -176,11 +207,11 @@ These variables changed in 6.4 so if you have an older version of Grafana, then Azure Monitor, [CloudWatch](ref:cloudwatch), and [Google Cloud Monitoring](ref:google-cloud-monitoring) have pre-configured data links called _deep links_. -You can also use template variables in your data links URLs. For more information, refer to [Templates and variables](ref:templates-and-variables). +You can also use template variables in your data links or actions URLs. For more information, refer to [Templates and variables](ref:templates-and-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 or action URL: | Variable | Description | | ------------------ | ------------------------------------------------------------------------ | @@ -188,7 +219,7 @@ These variables allow you to include the current time range in the data link URL | `__from` | For more information, refer to [Global variables](ref:global-variables). | | `__to` | For more information, refer to [Global variables](ref:global-variables). | -When you create data links using time range variables like `__url_time_range` in the URL, you have to form the query parameter syntax yourself; that is, you must format the URL by appending query parameters using the question mark (`?`) and ampersand (`&`) syntax. These characters aren't automatically generated. +When you create data links and actions using time range variables like `__url_time_range` in the URL, you have to form the query parameter syntax yourself; that is, you must format the URL by appending query parameters using the question mark (`?`) and ampersand (`&`) syntax. These characters aren't automatically generated. ### Series variables @@ -219,9 +250,9 @@ Value-specific variables are available under `__value` namespace: | `__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. +Using value-specific variables in data links and actions can show different results depending on the set option of Tooltip mode. -When you create data links using time range variables like `__value.time` in the URL, you have to form the query parameter syntax yourself; that is, you must add the question mark (`?`) and ampersand (`&`). These characters aren't automatically generated. +When you create data links and actions using time range variables like `__value.time` in the URL, you have to form the query parameter syntax yourself; that is, you must add the question mark (`?`) and ampersand (`&`). These characters aren't automatically generated. ### Data variables @@ -247,21 +278,67 @@ 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}`. -## Add a data link +## Add data links or actions {#add-a-data-link} + +The following tasks describe how to configure data links and actions. + +{{< tabs >}} +{{< tab-content name="Add data links" >}} +To add a data link, follow these steps: 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. 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. +1. Scroll down to the **Data links and actions** section and expand it. +1. Click **+ Add link**. +1. In the dialog box that opens, enter a **Title**. - 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. + This is a human-readable label for the link displayed in the UI. This is a required field. + +1. Enter the **URL** to which you want to link. + + 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. This is a required field. 1. If you want the link to open in a new tab, toggle the **Open in a new tab** switch. +1. If you want the data link to open with a single click on the visualization, toggle the **One click** switch. + + Only one data link can have **One click** enabled at a time. **One click** is only supported for some visualizations. + 1. Click **Save** to save changes and close the dialog box. 1. Click **Save dashboard**. 1. Click **Back to dashboard** and then **Exit edit**. -If you add multiple data links, you can control the order in which they appear in the visualization. To do this, click and drag the data link to the desired position. + {{< /tab-content >}} + {{< tab-content name="Add actions" >}} + + {{< admonition type="note">}} + Actions are not supported for all visualizations. For the list of supported visualizations, refer to [Supported visualizations](#supported-visualizations-1). + {{< /admonition >}} + + To add an action, by follow these steps: + +1. Navigate to the panel to which you want to add the action. +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. Scroll down to the **Data links and actions** section and expand it. +1. Click **+ Add action**. +1. In the dialog box that opens, define the API call settings: + + | Option | Description | + | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | + | Title | A human-readable label for the action that's displayed in the UI. | + | Confirmation message | A descriptive prompt to confirm or cancel the action. | + | Method | Select from **POST**, **PUT**, or **GET**. | + | URL | The request URL.

To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. | + | Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. | + | Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.

Click the **+** icon to add as many key/value pairs as you need. | + | Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. | + | Body | The body of the request. | + +1. Click **Save** to save changes and close the dialog box. +1. Click **Save dashboard**. +1. Click **Back to dashboard** and then **Exit edit**. + {{< /tab-content >}} + {{< /tabs >}} + +If you add multiple data links or actions, you can control the order in which they appear in the visualization. To do this, click and drag the data link or action to the desired position. diff --git a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md index 9fef087e422..cfc5a5e29e5 100644 --- a/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md +++ b/docs/sources/panels-visualizations/query-transform-data/transform-data/index.md @@ -104,6 +104,16 @@ When there are multiple transformations, Grafana applies them in the order they The order in which Grafana applies transformations directly impacts the results. For example, if you use a Reduce transformation to condense all the results of one column into a single value, then you can only apply transformations to that single value. +## Dashboard variables in transformations + +All text input fields in transformations accept [variable syntax](ref:dashboard-variable): + +{{< figure src="/media/docs/grafana/panels-visualizations/screenshot-transformation-variables-v11.6.png" alt="Transformation with a mock variable in a text field" >}} + +When you use dashboard variables in transformations, the variables are automatically interpolated before the transformations are applied to the data. + +For an example, refer to [Use a dashboard variable](#use-a-dashboard-variable) in the **Filter fields by name** transformation. + ## Add a transformation function to data The following steps guide you in adding a transformation to data. This documentation does not include steps for each type of transformation. For a complete list of transformations, refer to [Transformation functions](#transformation-functions). diff --git a/docs/sources/panels-visualizations/visualizations/bar-chart/index.md b/docs/sources/panels-visualizations/visualizations/bar-chart/index.md index 3d7f982d554..6de1af95513 100644 --- a/docs/sources/panels-visualizations/visualizations/bar-chart/index.md +++ b/docs/sources/panels-visualizations/visualizations/bar-chart/index.md @@ -199,9 +199,9 @@ You can set standard min/max options to define hard limits of the Y-axis. For mo {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md b/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md index f4059970634..3fd9b5c24ea 100644 --- a/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md +++ b/docs/sources/panels-visualizations/visualizations/bar-gauge/index.md @@ -211,9 +211,9 @@ This option only applies when bar size is set to manual. {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -## Data links +## Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="" >}} ## Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/candlestick/index.md b/docs/sources/panels-visualizations/visualizations/candlestick/index.md index ee51937afc9..bbaccb65254 100644 --- a/docs/sources/panels-visualizations/visualizations/candlestick/index.md +++ b/docs/sources/panels-visualizations/visualizations/candlestick/index.md @@ -136,9 +136,9 @@ The candlestick visualization is based on the time series visualization. It can {{< docs/shared lookup="visualizations/tooltip-options-2.md" source="grafana" version="" >}} -## Data links +## Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ## Thresholds diff --git a/docs/sources/panels-visualizations/visualizations/canvas/index.md b/docs/sources/panels-visualizations/visualizations/canvas/index.md index ebd7162047e..3313fb3b225 100644 --- a/docs/sources/panels-visualizations/visualizations/canvas/index.md +++ b/docs/sources/panels-visualizations/visualizations/canvas/index.md @@ -258,6 +258,13 @@ You can enable panning and zooming in a canvas. This allows you to both create a {{< docs/public-preview product="Canvas pan and zoom" featureFlag="`canvasPanelPanZoom`" >}} +Use the following pointer and keyboard strokes: + +- **Zoom in** - Scroll up +- **Zoom out** - Scroll down +- **Pan** - Middle mouse/wheel + drag OR Control + right-click + drag +- **Reset** - Double-click + {{< video-embed src="/media/docs/grafana/2024-01-05-Canvas-Pan-&-Zoom-Enablement-Video.mp4" max-width="750px" alt="Canvas pan and zoom enablement video" >}} ##### Infinite panning @@ -323,14 +330,14 @@ Use the following options to control the border of the canvas: The following options allow you to control the appearance of the element you've selected. To access an element so that you can edit it, expand the **Layer** section and select the desired element. -| Option | Description | -| ------------------------------------------- | ----------------------------------------------------------------------------------------------- | -| [Element type](#element-type) | Change the selected element type. | -| [Element](#element) | Control the appearance of text on the element. This section is named based on the element type. | -| [Layout](#layout) | Control the placement of elements on the canvas. | -| [Background (element)](#background-element) | Set the background of the element. | -| [Border (element)](#border-element) | Set the border of the element. | -| [Data links](#data-links) | Configure data links for elements. | +| Option | Description | +| ------------------------------------------------- | ----------------------------------------------------------------------------------------------- | +| [Element type](#element-type) | Change the selected element type. | +| [Element](#element) | Control the appearance of text on the element. This section is named based on the element type. | +| [Layout](#layout) | Control the placement of elements on the canvas. | +| [Background (element)](#background-element) | Set the background of the element. | +| [Border (element)](#border-element) | Set the border of the element. | +| [Data links and actions](#data-links-and-actions) | Configure data links and actions for elements. | #### Element type @@ -398,40 +405,66 @@ Use the following options to set the border of the element: - **Color** - Set the border color. This option is only displayed when the border width is greater than zero. - **Radius** - Add rounded corners to the element border and control the degree of curve. -#### Data links +#### Data links and actions -Canvases support [data links](ref:data-links) for all elements except drone and button elements. You can add a data link by following these steps: +Canvases support [data links](ref:data-links) and actions for all elements. -1. Enable inline editing. -1. Click the element you to which you want to add the data link. -1. In either the inline editor or panel editor, expand the **Selected element** editor. -1. Scroll down to the **Data links** section and expand it. -1. Click **Add link**. -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. +If you add multiple data links or actions to an element, you can control the order in which they appear in the element tooltip. +To do this, click and drag the link or action to the desired position. - 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. +The following tasks describe how to configure data links and actions. -1. If you want the link to open in a new tab, toggle the **Open in a new tab** switch. -1. Click **Save** to save changes and close the dialog box. -1. Disable inline editing. - -If you add multiple data links, you can control the order in which they appear in the visualization. To do this, click and drag the data link to the desired position. - -##### One-click data link - -You can configure a canvas data link to open with a single click on the element. To enable this feature, follow these steps: +{{< tabs >}} +{{< tab-content name="Add data links" >}} +To add a data link, follow these steps: 1. Enable inline editing. 1. Click the element to which you want to add the data link. 1. In either the inline editor or panel editor, expand the **Selected element** editor. -1. Scroll down to the **Data links** section and expand it. -1. In the **One-click** section, choose **Link**. +1. Scroll down to the **Data links and actions** section and expand it. +1. Click **+ Add link**. +1. In the dialog box that opens, enter a **Title**. + + This is a human-readable label for the link displayed in the UI. This is a required field. + +1. Enter the **URL** or variable to which you want to link. + + 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. This is a required field. + +1. If you want the link to open in a new tab, toggle the **Open in a new tab** switch. +1. If you want the data link to open with a single click on the element, toggle the **One click** switch. + + Only one data link or action can have **One click** enabled at a time. + +1. Click **Save** to save changes and close the dialog box. 1. Disable inline editing. + {{< /tab-content >}} + {{< tab-content name="Add actions" >}} + To add an action, by follow these steps: -The first data link in the list will be configured as your one-click data link. If you want to change the one-click data link, simply drag the desired data link to the top of the list. +1. Enable inline editing. +1. Click the element to which you want to add the data link. +1. In either the inline editor or panel editor, expand the **Selected element** editor. +1. Scroll down to the **Data links and actions** section and expand it. +1. Click **+ Add action**. +1. In the dialog box that opens, set the action options: -{{< video-embed src="/media/docs/grafana/panels-visualizations/canvas-one-click-datalink-.mp4" >}} + | Option | Description | + | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | Title | A human-readable label for the action that's displayed in the UI. | + | Confirmation message | A descriptive prompt to confirm or cancel the action. | + | One click | If you want the action to be triggered by a single click on the element, toggle the switch.

Only one data link or action can have **One click** enabled at a time. | + | Method | Select from **POST**, **PUT**, or **GET**. | + | URL | The request URL or variable to which you want to link.

To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. | + | Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. | + | Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.

Click the **+** icon to add as many key/value pairs as you need. | + | Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. | + | Body | The body of the request. | + +1. Click **Save** to save changes and close the dialog box. +1. Disable inline editing. + {{< /tab-content >}} + {{< /tabs >}} ### Selected connection options diff --git a/docs/sources/panels-visualizations/visualizations/flame-graph/index.md b/docs/sources/panels-visualizations/visualizations/flame-graph/index.md index beb660f660f..b4096fa4d09 100644 --- a/docs/sources/panels-visualizations/visualizations/flame-graph/index.md +++ b/docs/sources/panels-visualizations/visualizations/flame-graph/index.md @@ -19,7 +19,7 @@ weight: 100 # Flame graph -Flame graphs let you visualize [profiling](https://grafana.com/docs/pyroscope/latest/introduction/profiling/) data. Using this visualization, a [profile](https://grafana.com/docs/pyroscope/latest/view-and-analyze-profile-data/profiling-types/) can be represented as a [flame graph](#flame-graph-mode), [top table](#top-table-mode), or both. +Flame graphs let you visualize [profiling](https://grafana.com/docs/pyroscope/latest/introduction/what-is-profiling/) data. Using this visualization, a [profile](https://grafana.com/docs/pyroscope/latest/view-and-analyze-profile-data/profiling-types/) can be represented as a [flame graph](#flame-graph-mode), [top table](#top-table-mode), or both. For example, if you want to understand which parts of a program consume the most resources, such as CPU time, memory, or I/O operations, you can use a flame graph to visualize and analyze where potential performance issues are: diff --git a/docs/sources/panels-visualizations/visualizations/gauge/index.md b/docs/sources/panels-visualizations/visualizations/gauge/index.md index bfcd1c89549..fbb1cb922ae 100644 --- a/docs/sources/panels-visualizations/visualizations/gauge/index.md +++ b/docs/sources/panels-visualizations/visualizations/gauge/index.md @@ -171,9 +171,9 @@ Adjust the sizes of the gauge text. {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/geomap/index.md b/docs/sources/panels-visualizations/visualizations/geomap/index.md index b42d1f78a6c..64b20d33dd7 100644 --- a/docs/sources/panels-visualizations/visualizations/geomap/index.md +++ b/docs/sources/panels-visualizations/visualizations/geomap/index.md @@ -711,7 +711,7 @@ Displays debug information in the upper right corner. This can be useful for deb {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions {{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} diff --git a/docs/sources/panels-visualizations/visualizations/heatmap/index.md b/docs/sources/panels-visualizations/visualizations/heatmap/index.md index 99bd1f53e68..a51479e4e7a 100644 --- a/docs/sources/panels-visualizations/visualizations/heatmap/index.md +++ b/docs/sources/panels-visualizations/visualizations/heatmap/index.md @@ -208,7 +208,7 @@ Choose whether you want to display the heatmap legend on the visualization by to Set the color used to show exemplar data. -### Data links +### Data links and actions {{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} diff --git a/docs/sources/panels-visualizations/visualizations/histogram/index.md b/docs/sources/panels-visualizations/visualizations/histogram/index.md index 70fcc675d02..f005c8ad7cb 100644 --- a/docs/sources/panels-visualizations/visualizations/histogram/index.md +++ b/docs/sources/panels-visualizations/visualizations/histogram/index.md @@ -157,7 +157,7 @@ Choose from the following: {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -## Data links +## Data links and actions {{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} diff --git a/docs/sources/panels-visualizations/visualizations/pie-chart/index.md b/docs/sources/panels-visualizations/visualizations/pie-chart/index.md index bb1d2cd02aa..679f4e61f3b 100644 --- a/docs/sources/panels-visualizations/visualizations/pie-chart/index.md +++ b/docs/sources/panels-visualizations/visualizations/pie-chart/index.md @@ -174,9 +174,9 @@ Use these settings to define how the legend appears in your visualization. For m {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/stat/index.md b/docs/sources/panels-visualizations/visualizations/stat/index.md index eb989ae6d4e..e1ad7fada4a 100644 --- a/docs/sources/panels-visualizations/visualizations/stat/index.md +++ b/docs/sources/panels-visualizations/visualizations/stat/index.md @@ -172,9 +172,9 @@ Adjust the sizes of the gauge text. {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-1.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md index 1ef99435336..192bcb8fdb1 100644 --- a/docs/sources/panels-visualizations/visualizations/state-timeline/index.md +++ b/docs/sources/panels-visualizations/visualizations/state-timeline/index.md @@ -149,13 +149,17 @@ The **Page size** option lets you paginate the state timeline visualization to l {{< docs/shared lookup="visualizations/tooltip-options-1.md" source="grafana" version="" leveloffset="+1" >}} +### Axis options + +{{< docs/shared lookup="visualizations/axis-options-state-status.md" source="grafana" version="" leveloffset="+1" >}} + ### Standard options {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/status-history/index.md b/docs/sources/panels-visualizations/visualizations/status-history/index.md index b7825b94b82..0382deffd77 100644 --- a/docs/sources/panels-visualizations/visualizations/status-history/index.md +++ b/docs/sources/panels-visualizations/visualizations/status-history/index.md @@ -111,6 +111,10 @@ Controls whether values are rendered inside the value boxes. Auto will render va Controls the height of boxes. 1 = maximum space and 0 = minimum space. +### Page size (enable pagination) + +The **Page size** option lets you paginate the status history visualization to limit how many series are visible at once. This is useful when you have many series. + ### Column width Controls the width of boxes. 1 = maximum space and 0 = minimum space. @@ -131,13 +135,17 @@ Controls the opacity of state regions. {{< docs/shared lookup="visualizations/tooltip-options-1.md" source="grafana" version="" >}} +## Axis options + +{{< docs/shared lookup="visualizations/axis-options-state-status.md" source="grafana" version="" leveloffset="+1" >}} + ## Standard options {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -## Data links +## Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ## Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/table/index.md b/docs/sources/panels-visualizations/visualizations/table/index.md index 42635aa733f..e99622019d8 100644 --- a/docs/sources/panels-visualizations/visualizations/table/index.md +++ b/docs/sources/panels-visualizations/visualizations/table/index.md @@ -246,6 +246,7 @@ If you want to apply a cell type to only some fields instead of all fields, you | Data links | If you've configured data links, when the cell type is **Auto**, the cell text becomes clickable. If you change the cell type to **Data links**, the cell text reflects the titles of the configured data links. To control the application of data link text more granularly, use a **Cell option > Cell type > Data links** field override. | | [JSON View](#json-view) | Shows values formatted as code. | | [Image](#image) | If the field value is an image URL or a base64 encoded image, the table displays the image. | +| [Actions](#actions) | The cell displays a button that triggers a basic, unauthenticated API call when clicked. | ##### Sparkline @@ -333,6 +334,23 @@ Set the following options: - **Alt text** - Set the alternative text of an image. The text will be available for screen readers and in cases when images can't be loaded. - **Title text** - Set the text that's displayed when the image is hovered over with a cursor. +##### Actions + +The cell displays a button that triggers a basic, unauthenticated API call when clicked. +Configure the API call with the following options: + + +| Option | Description | +| ------- | ------------ | +| Endpoint | Enter the endpoint URL. | +| Method | Choose from **GET**, **POST**, and **PUT**. | +| Content-Type | Select an option in the drop-down list. Choose from: JSON, Text, JavaScript, HTML, XML, and x-www-form-urlencoded. | +| Query parameters | Enter as many **Key**, **Value** pairs as you need. | +| Header parameters | Enter as many **Key**, **Value** pairs as you need. | +| Payload | Enter the body of the API call. | + + + #### Wrap text {{< admonition type="note" >}} @@ -362,9 +380,9 @@ If you want to apply this setting to only some fields instead of all fields, you {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-3.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/time-series/index.md b/docs/sources/panels-visualizations/visualizations/time-series/index.md index e7f21000554..7b3dec5e5bf 100644 --- a/docs/sources/panels-visualizations/visualizations/time-series/index.md +++ b/docs/sources/panels-visualizations/visualizations/time-series/index.md @@ -209,21 +209,7 @@ The following example shows three series: Min, Max, and Value. The Min and Max s ### Axis options -Options under the **Axis** section control how the x- and y-axes are rendered. Some options don't take effect until you click outside of the field option box you're editing. You can also press `Enter`. - -| Option | Description | -| ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| Time zone | Set the desired time zones to display along the x-axis. | -| [Placement](#placement) | Select the placement of the y-axis. | -| Label | Set a y-axis text label. If you have more than one y-axis, then you can assign different labels using an override. | -| Width | Set a fixed width of the axis. By default, Grafana dynamically calculates the width of an axis. By setting the width of the axis, data with different axes types can share the same display proportions. This setting makes it easier for you to compare more than one graph’s worth of data because the axes aren't shifted or stretched within visual proximity to each other. | -| Show grid lines | Set the axis grid line visibility.
| -| Color | Set the color of the axis. | -| Show border | Set the axis border visibility. | -| Scale | Set the y-axis values scale.
| -| Centered zero | Set the y-axis so it's centered on zero. | -| [Soft min](#soft-min-and-soft-max) | Set a soft min to better control the y-axis limits. zero. | -| [Soft max](#soft-min-and-soft-max) | Set a soft max to better control the y-axis limits. zero. | +{{< docs/shared lookup="visualizations/axis-options-all.md" source="grafana" version="" leveloffset="+1" >}} #### Placement @@ -376,9 +362,9 @@ Set the position of the bar relative to a data point. In the examples below, **S {{< docs/shared lookup="visualizations/standard-options.md" source="grafana" version="" >}} -### Data links +### Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ### Value mappings diff --git a/docs/sources/panels-visualizations/visualizations/traces/index.md b/docs/sources/panels-visualizations/visualizations/traces/index.md index ac99c3a07bd..d89ea25b559 100644 --- a/docs/sources/panels-visualizations/visualizations/traces/index.md +++ b/docs/sources/panels-visualizations/visualizations/traces/index.md @@ -59,7 +59,7 @@ For more information about traces and how to use them, refer to the following do - [Tempo data source](ref:tempo-data-source) - [Getting started with Tempo](/docs/tempo/latest/getting-started) -{{< figure src="/static/img/docs/explore/trace-view-9-4.png" class="docs-image--no-shadow" max-width= "900px" caption="Screenshot of the trace view" >}} +{{< figure src="/media/docs/grafana/panels-visualizations/screenshot-traces-visualization-11.5.png" max-width= "700px" alt="Screenshot of the trace view" >}} {{< docs/play title="Traces Panel" url="https://play.grafana.org/d/edodkfmj0tce8f/" >}} @@ -77,7 +77,7 @@ To use this procedure, you need: - A Grafana instance - A [Tempo data source](ref:tempo-data-source) connected to your Grafana instance -### Add the traces visualization query {#add-the-traces-panel-query} +### Steps {#add-the-traces-panel-query} To view and analyze traces data in a dashboard, you need to add the traces visualization to your dashboard and define a query using the panel editor. The query determines the data that is displayed in the visualization. @@ -100,19 +100,19 @@ This procedure uses dashboard variables and templates to allow you to enter trac 1. In the query editor, click the **TraceQL** query type tab. 1. Enter `${traceId}` in the TraceQL query field to create a dashboard variable. This variable is used as the template query. - {{< figure src="/static/img/docs/panels/traces/screenshot-traces-template-query.png" caption="Add a template query" >}} + {{< figure src="/static/img/docs/panels/traces/screenshot-traces-template-query.png" alt="Add a template query" >}} 1. Click **Back to dashboard**. 1. Click **Settings** and go to the **Variables** tab. 1. Add a new variable called `traceId`, of variable type **Custom**, giving it a label if required. - {{< figure src="/media/docs/grafana/dashboards/screenshot-traces-custom-variable-11.2.png" max-width="50%" caption="Add a Custom variable" >}} + {{< figure src="/media/docs/grafana/panels-visualizations/screenshot-traces-custom-variable-v11.5.png" max-width="400px" alt="Add a template query" >}} 1. Click **Save dashboard**. 1. Click **Back to dashboard** and **Exit edit**. 1. Verify that the panel works by using a valid trace ID for the data source used for the trace panel and editing the ID in the dashboard variable. - {{< figure src="/static/img/docs/panels/traces/screenshot-traces-traceid-panel.png" caption="Results of query in trace panel" >}} + {{< figure src="/static/img/docs/panels/traces/screenshot-traces-traceid-panel.png" alt="Results of query in trace panel" >}} ## Add TraceQL with table visualizations @@ -127,14 +127,14 @@ It’s more useful to instead be able to use TraceQL queries to search for speci 1. Under the **Panel options**, enter a **Title** for your trace panel or have Grafana create one using [generative AI features](ref:generative-ai-features). 1. Add an appropriate TraceQL query to search for traces that you would like to visualize in the dashboard. This example uses a simple, static query. You can write the TraceQL query as a template query to take advantage of other dashboard variables, if they exist. This lets you create dynamic queries based on these variables. - {{< figure src="/static/img/docs/panels/traces/screenshot-traces-dynamic-query.png" caption="Create a dynamic query" >}} + {{< figure src="/static/img/docs/panels/traces/screenshot-traces-dynamic-query.png" alt="Create a dynamic query" >}} 1. Click **Save dashboard**. 1. Click **Back to dashboard** and **Exit edit**. When results are returned from a query, the results are rendered in the panel’s table. -{{< figure src="/static/img/docs/panels/traces/screenshot-traces-returned-query.png" caption="Results of a returned query in the panel table" >}} +{{< figure src="/static/img/docs/panels/traces/screenshot-traces-returned-query.png" alt="Results of a returned query in the panel table" >}} ### Use a variable to add other links to traces @@ -146,12 +146,12 @@ To create a set of data links in the panel, use the following steps: 1. Add a **Title** for the data link. 1. Find the UUID of the dashboard by looking in your browser’s address bar when the full dashboard is being rendered. Because this is a link to a dashboard in the same Grafana stack, only the path of the dashboard is required. - {{< figure src="/static/img/docs/panels/traces/screensnot-traces-uuid-url.png" caption="Unique identifier for the dashboard" >}} + {{< figure src="/static/img/docs/panels/traces/screensnot-traces-uuid-url.png" alt="Unique identifier for the dashboard" >}} 1. In the **URL** field, make a self-reference to the dashboard that contains both of the panels. This self-reference uses the value of the selected trace in the table to fill in the dashboard variable. Use the path for the dashboard from the previous step and then fill in the value of `traceId` using the selected results from the TraceQL table. The trace ID is exposed using the `traceID` data field in the returned results, so use that as the value for the dashboard variable. - {{< figure src="/static/img/docs/panels/traces/screenshot-traces-edit-link.png" caption="Edit link and add the Trace link" >}} + {{< figure src="/static/img/docs/panels/traces/screenshot-traces-edit-link.png" alt="Edit link and add the Trace link" >}} 1. Select **Save** to save the data link. 1. Click **Save dashboard**. @@ -159,24 +159,35 @@ To create a set of data links in the panel, use the following steps: You should now see a list of matching traces in the table visualization. While selecting the **TraceID** or **SpanID** fields will give you the option to either open the **Explore** page to visualize the trace or following the data link, selecting any other field (such as **Start time**, **Name** or **Duration**) automatically follows the data link, filling in the `traceId` dashboard variable, and then shows the relevant trace in the trace panel. -{{< figure src="/static/img/docs/panels/traces/screenshot-traces-trace-link.png" caption="Selecting the trace link" >}} +{{< figure src="/static/img/docs/panels/traces/screenshot-traces-trace-link.png" alt="Selecting the trace link" >}} {{< figure src="/static/img/docs/panels/traces/screenshot-traces-trace-link-follow.png" caption="Follow the trace link populates the trace ID and displays the traces view" >}} -## Panel options +## Configuration options + +{{< docs/shared lookup="visualizations/config-options-intro.md" source="grafana" version="" >}} + +### Panel options {{< docs/shared lookup="visualizations/panel-options.md" source="grafana" version="" >}} -## Span filters +### Span filters options The **Span filters** options control the initial state of the span filters when the visualization loads, allowing you to customize your trace analysis view. -- **Find in trace** - Set the initial value to focus on spans relevant to your query. -- **Show matches only** - Toggle the switch on to display only spans that match the defined filter criteria. This helps simplify trace interpretation. -- **Show critical path only** - Toggle the switch on to highlight only the spans in the critical path, which helps identify performance bottlenecks and their impact on overall latency. -- **Service name** and **Service name operator** - Define a specific service or pattern to narrow analysis to spans related to particular services. -- **Span name** and **Span name operator** - Filter spans by name or pattern to focus on specific span types or processes. -- **Min duration** and **Max duration** - Set duration thresholds to exclude spans outside the desired time range. -- **Tags** - Add one or more tags to further refine the filtering criteria so only relevant spans are displayed. +The following options support variable interpolation, where you can set the service name to a variable `$var` and the visualization will replace it with the value for the variable named `$var` in the span filters: **Service name**, **Span name**, **Min duration**, **Max duration**, and **Tags**. -The options support variable interpolation, where you can set the service name to a variable `$var` and the visualization will replace it with the value for the variable named `$var` in the span filters. This applies to the service name, span name, duration fields, and tags. + + +| Option | Description | +| ------ | ----------- | +| Find in trace | Set the initial value to focus on spans relevant to your query. | +| Show matches only | Toggle the switch on to display only spans that match the defined filter criteria. This helps simplify trace interpretation. | +| Show critical path only | Toggle the switch on to highlight only the spans in the critical path, which helps identify performance bottlenecks and their impact on overall latency. | +| Service name | Along with the **Service name operator**, define a specific service or pattern to narrow analysis to spans related to particular services. | +| Span name | Along with the **Span name operator**, filter spans by name or pattern to focus on specific span types or processes. | +| Min duration | Set the minimum duration threshold to exclude spans outside the desired time range. | +| Max duration | Set the maximum duration threshold to exclude spans outside the desired time range. | +| Tags | Add one or more tags to further refine the filtering criteria so only relevant spans are displayed. | + + diff --git a/docs/sources/panels-visualizations/visualizations/trend/index.md b/docs/sources/panels-visualizations/visualizations/trend/index.md index 7c8900b0f4f..e8cc7fa8d30 100644 --- a/docs/sources/panels-visualizations/visualizations/trend/index.md +++ b/docs/sources/panels-visualizations/visualizations/trend/index.md @@ -60,9 +60,9 @@ For example, you could represent engine power and torque versus speed where spee {{< docs/shared lookup="visualizations/tooltip-options-2.md" source="grafana" version="" >}} -## Data links +## Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ## Thresholds diff --git a/docs/sources/panels-visualizations/visualizations/xy-chart/index.md b/docs/sources/panels-visualizations/visualizations/xy-chart/index.md index 1e3f4d341dd..83becc1b7df 100644 --- a/docs/sources/panels-visualizations/visualizations/xy-chart/index.md +++ b/docs/sources/panels-visualizations/visualizations/xy-chart/index.md @@ -308,9 +308,9 @@ You can customize the following standard options: To learn more, refer to [Configure standard options](ref:configure-standard-options). -## Data links +## Data links and actions -{{< docs/shared lookup="visualizations/datalink-options.md" source="grafana" version="" >}} +{{< docs/shared lookup="visualizations/datalink-options-2.md" source="grafana" version="" >}} ## Field overrides diff --git a/docs/sources/release-notes/_index.md b/docs/sources/release-notes/_index.md index bdc839a1df3..8409c58c6a7 100644 --- a/docs/sources/release-notes/_index.md +++ b/docs/sources/release-notes/_index.md @@ -16,127 +16,127 @@ as well as notices about deprecations, breaking changes, and changes related to {{% admonition type="note" %}} As of Grafana v9.2 we no longer publish release notes, which are redundant with other release lists that we publish: -- For details about new features, deprecations, and breaking changes in new Grafana releases, see [What's New in Grafana]({{< relref "../whatsnew/" >}}). +- For details about new features, deprecations, and breaking changes in new Grafana releases, see [What's New in Grafana](../whatsnew/). - For lists of changes to Grafana, with links to pull requests and related issues when available, see the [Changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). {{% /admonition %}} -- [Release notes for 9.1.7]({{< relref "release-notes-9-1-7" >}}) -- [Release notes for 9.1.6]({{< relref "release-notes-9-1-6" >}}) -- [Release notes for 9.1.5]({{< relref "release-notes-9-1-5" >}}) -- [Release notes for 9.1.4]({{< relref "release-notes-9-1-4" >}}) -- [Release notes for 9.1.3]({{< relref "release-notes-9-1-3" >}}) -- [Release notes for 9.1.2]({{< relref "release-notes-9-1-2" >}}) -- [Release notes for 9.1.1]({{< relref "release-notes-9-1-1" >}}) -- [Release notes for 9.1.0]({{< relref "release-notes-9-1-0" >}}) -- [Release notes for 9.1.0-beta1]({{< relref "release-notes-9-1-0-beta1" >}}) -- [Release notes for 9.0.9]({{< relref "release-notes-9-0-9" >}}) -- [Release notes for 9.0.8]({{< relref "release-notes-9-0-8" >}}) -- [Release notes for 9.0.7]({{< relref "release-notes-9-0-7" >}}) -- [Release notes for 9.0.6]({{< relref "release-notes-9-0-6" >}}) -- [Release notes for 9.0.5]({{< relref "release-notes-9-0-5" >}}) -- [Release notes for 9.0.4]({{< relref "release-notes-9-0-4" >}}) -- [Release notes for 9.0.3]({{< relref "release-notes-9-0-3" >}}) -- [Release notes for 9.0.2]({{< relref "release-notes-9-0-2" >}}) -- [Release notes for 9.0.1]({{< relref "release-notes-9-0-1" >}}) -- [Release notes for 9.0.0]({{< relref "release-notes-9-0-0/" >}}) -- [Release notes for 9.0.0-beta3]({{< relref "release-notes-9-0-0-beta3/" >}}) -- [Release notes for 9.0.0-beta2]({{< relref "release-notes-9-0-0-beta2/" >}}) -- [Release notes for 9.0.0-beta1]({{< relref "release-notes-9-0-0-beta1/" >}}) -- [Release notes for 8.5.13]({{< relref "release-notes-8-5-13" >}}) -- [Release notes for 8.5.11]({{< relref "release-notes-8-5-11" >}}) -- [Release notes for 8.5.10]({{< relref "release-notes-8-5-10" >}}) -- [Release notes for 8.5.9]({{< relref "release-notes-8-5-9" >}}) -- [Release notes for 8.5.6]({{< relref "release-notes-8-5-6/" >}}) -- [Release notes for 8.5.5]({{< relref "release-notes-8-5-5/" >}}) -- [Release notes for 8.5.4]({{< relref "release-notes-8-5-4/" >}}) -- [Release notes for 8.5.3]({{< relref "release-notes-8-5-3/" >}}) -- [Release notes for 8.5.2]({{< relref "release-notes-8-5-2/" >}}) -- [Release notes for 8.5.1]({{< relref "release-notes-8-5-1/" >}}) -- [Release notes for 8.5.0]({{< relref "release-notes-8-5-0/" >}}) -- [Release notes for 8.5.0-beta1]({{< relref "release-notes-8-5-0-beta1/" >}}) -- [Release notes for 8.4.11]({{< relref "release-notes-8-4-11" >}}) -- [Release notes for 8.4.10]({{< relref "release-notes-8-4-10" >}}) -- [Release notes for 8.4.7]({{< relref "release-notes-8-4-7/" >}}) -- [Release notes for 8.4.6]({{< relref "release-notes-8-4-6/" >}}) -- [Release notes for 8.4.5]({{< relref "release-notes-8-4-5/" >}}) -- [Release notes for 8.4.4]({{< relref "release-notes-8-4-4/" >}}) -- [Release notes for 8.4.3]({{< relref "release-notes-8-4-3/" >}}) -- [Release notes for 8.4.2]({{< relref "release-notes-8-4-2/" >}}) -- [Release notes for 8.4.1]({{< relref "release-notes-8-4-1/" >}}) -- [Release notes for 8.4.0-beta1]({{< relref "release-notes-8-4-0-beta1/" >}}) -- [Release notes for 8.3.11]({{< relref "release-notes-8-3-11/" >}}) -- [Release notes for 8.3.7]({{< relref "release-notes-8-3-7/" >}}) -- [Release notes for 8.3.6]({{< relref "release-notes-8-3-6/" >}}) -- [Release notes for 8.3.5]({{< relref "release-notes-8-3-5/" >}}) -- [Release notes for 8.3.4]({{< relref "release-notes-8-3-4/" >}}) -- [Release notes for 8.3.3]({{< relref "release-notes-8-3-3/" >}}) -- [Release notes for 8.3.2]({{< relref "release-notes-8-3-2/" >}}) -- [Release notes for 8.3.1]({{< relref "release-notes-8-3-1/" >}}) -- [Release notes for 8.3.0]({{< relref "release-notes-8-3-0/" >}}) -- [Release notes for 8.3.0-beta2]({{< relref "release-notes-8-3-0-beta2/" >}}) -- [Release notes for 8.3.0-beta1]({{< relref "release-notes-8-3-0-beta1/" >}}) -- [Release notes for 8.2.7]({{< relref "release-notes-8-2-7/" >}}) -- [Release notes for 8.2.6]({{< relref "release-notes-8-2-6/" >}}) -- [Release notes for 8.2.5]({{< relref "release-notes-8-2-5/" >}}) -- [Release notes for 8.2.4]({{< relref "release-notes-8-2-4/" >}}) -- [Release notes for 8.2.3]({{< relref "release-notes-8-2-3/" >}}) -- [Release notes for 8.2.2]({{< relref "release-notes-8-2-2/" >}}) -- [Release notes for 8.2.1]({{< relref "release-notes-8-2-1/" >}}) -- [Release notes for 8.2.0]({{< relref "release-notes-8-2-0/" >}}) -- [Release notes for 8.2.0-beta2]({{< relref "release-notes-8-2-0-beta2/" >}}) -- [Release notes for 8.2.0-beta1]({{< relref "release-notes-8-2-0-beta1/" >}}) -- [Release notes for 8.1.8]({{< relref "release-notes-8-1-8/" >}}) -- [Release notes for 8.1.7]({{< relref "release-notes-8-1-7/" >}}) -- [Release notes for 8.1.6]({{< relref "release-notes-8-1-6/" >}}) -- [Release notes for 8.1.5]({{< relref "release-notes-8-1-5/" >}}) -- [Release notes for 8.1.4]({{< relref "release-notes-8-1-4/" >}}) -- [Release notes for 8.1.3]({{< relref "release-notes-8-1-3/" >}}) -- [Release notes for 8.1.2]({{< relref "release-notes-8-1-2/" >}}) -- [Release notes for 8.1.1]({{< relref "release-notes-8-1-1/" >}}) -- [Release notes for 8.1.0]({{< relref "release-notes-8-1-0/" >}}) -- [Release notes for 8.1.0-beta3]({{< relref "release-notes-8-1-0-beta3/" >}}) -- [Release notes for 8.1.0-beta2]({{< relref "release-notes-8-1-0-beta2/" >}}) -- [Release notes for 8.1.0-beta1]({{< relref "release-notes-8-1-0-beta1/" >}}) -- [Release notes for 8.0.7]({{< relref "release-notes-8-0-7/" >}}) -- [Release notes for 8.0.6]({{< relref "release-notes-8-0-6/" >}}) -- [Release notes for 8.0.5]({{< relref "release-notes-8-0-5/" >}}) -- [Release notes for 8.0.4]({{< relref "release-notes-8-0-4/" >}}) -- [Release notes for 8.0.3]({{< relref "release-notes-8-0-3/" >}}) -- [Release notes for 8.0.2]({{< relref "release-notes-8-0-2/" >}}) -- [Release notes for 8.0.1]({{< relref "release-notes-8-0-1/" >}}) -- [Release notes for 8.0.0]({{< relref "release-notes-8-0-0/" >}}) -- [Release notes for 8.0.0-beta3]({{< relref "release-notes-8-0-0-beta3/" >}}) -- [Release notes for 8.0.0-beta2]({{< relref "release-notes-8-0-0-beta2/" >}}) -- [Release notes for 8.0.0-beta1]({{< relref "release-notes-8-0-0-beta1/" >}}) -- [Release notes for 7.5.15]({{< relref "release-notes-7-5-15/" >}}) -- [Release notes for 7.5.13]({{< relref "release-notes-7-5-13/" >}}) -- [Release notes for 7.5.12]({{< relref "release-notes-7-5-12/" >}}) -- [Release notes for 7.5.11]({{< relref "release-notes-7-5-11/" >}}) -- [Release notes for 7.5.10]({{< relref "release-notes-7-5-10/" >}}) -- [Release notes for 7.5.9]({{< relref "release-notes-7-5-9/" >}}) -- [Release notes for 7.5.8]({{< relref "release-notes-7-5-8/" >}}) -- [Release notes for 7.5.7]({{< relref "release-notes-7-5-7/" >}}) -- [Release notes for 7.5.6]({{< relref "release-notes-7-5-6/" >}}) -- [Release notes for 7.5.5]({{< relref "release-notes-7-5-5/" >}}) -- [Release notes for 7.5.4]({{< relref "release-notes-7-5-4/" >}}) -- [Release notes for 7.5.3]({{< relref "release-notes-7-5-3/" >}}) -- [Release notes for 7.5.2]({{< relref "release-notes-7-5-2/" >}}) -- [Release notes for 7.5.1]({{< relref "release-notes-7-5-1/" >}}) -- [Release notes for 7.5.0]({{< relref "release-notes-7-5-0/" >}}) -- [Release notes for 7.5.0-beta2]({{< relref "release-notes-7-5-0-beta2/" >}}) -- [Release notes for 7.5.0-beta1]({{< relref "release-notes-7-5-0-beta1/" >}}) -- [Release notes for 7.4.5]({{< relref "release-notes-7-4-5/" >}}) -- [Release notes for 7.4.3]({{< relref "release-notes-7-4-3/" >}}) -- [Release notes for 7.4.2]({{< relref "release-notes-7-4-2/" >}}) -- [Release notes for 7.4.1]({{< relref "release-notes-7-4-1/" >}}) -- [Release notes for 7.4.0]({{< relref "release-notes-7-4-0/" >}}) -- [Release notes for 7.3.10]({{< relref "release-notes-7-3-10/" >}}) -- [Release notes for 7.3.7]({{< relref "release-notes-7-3-7/" >}}) -- [Release notes for 7.3.6]({{< relref "release-notes-7-3-6/" >}}) -- [Release notes for 7.3.5]({{< relref "release-notes-7-3-5/" >}}) -- [Release notes for 7.3.4]({{< relref "release-notes-7-3-4/" >}}) -- [Release notes for 7.3.3]({{< relref "release-notes-7-3-3/" >}}) -- [Release notes for 7.3.2]({{< relref "release-notes-7-3-2/" >}}) -- [Release notes for 7.3.1]({{< relref "release-notes-7-3-1/" >}}) -- [Release notes for 7.3.0]({{< relref "release-notes-7-3-0/" >}}) +- [Release notes for 9.1.7](release-notes-9-1-7/) +- [Release notes for 9.1.6](release-notes-9-1-6/) +- [Release notes for 9.1.5](release-notes-9-1-5/) +- [Release notes for 9.1.4](release-notes-9-1-4/) +- [Release notes for 9.1.3](release-notes-9-1-3/) +- [Release notes for 9.1.2](release-notes-9-1-2/) +- [Release notes for 9.1.1](release-notes-9-1-1/) +- [Release notes for 9.1.0](release-notes-9-1-0/) +- [Release notes for 9.1.0-beta1](release-notes-9-1-0-beta1/) +- [Release notes for 9.0.9](release-notes-9-0-9/) +- [Release notes for 9.0.8](release-notes-9-0-8/) +- [Release notes for 9.0.7](release-notes-9-0-7/) +- [Release notes for 9.0.6](release-notes-9-0-6/) +- [Release notes for 9.0.5](release-notes-9-0-5/) +- [Release notes for 9.0.4](release-notes-9-0-4/) +- [Release notes for 9.0.3](release-notes-9-0-3/) +- [Release notes for 9.0.2](release-notes-9-0-2/) +- [Release notes for 9.0.1](release-notes-9-0-1/) +- [Release notes for 9.0.0](release-notes-9-0-0/) +- [Release notes for 9.0.0-beta3](release-notes-9-0-0-beta3/) +- [Release notes for 9.0.0-beta2](release-notes-9-0-0-beta2/) +- [Release notes for 9.0.0-beta1](release-notes-9-0-0-beta1/) +- [Release notes for 8.5.13](release-notes-8-5-13/) +- [Release notes for 8.5.11](release-notes-8-5-11/) +- [Release notes for 8.5.10](release-notes-8-5-10/) +- [Release notes for 8.5.9](release-notes-8-5-9/) +- [Release notes for 8.5.6](release-notes-8-5-6/) +- [Release notes for 8.5.5](release-notes-8-5-5/) +- [Release notes for 8.5.4](release-notes-8-5-4/) +- [Release notes for 8.5.3](release-notes-8-5-3/) +- [Release notes for 8.5.2](release-notes-8-5-2/) +- [Release notes for 8.5.1](release-notes-8-5-1/) +- [Release notes for 8.5.0](release-notes-8-5-0/) +- [Release notes for 8.5.0-beta1](release-notes-8-5-0-beta1/) +- [Release notes for 8.4.11](release-notes-8-4-11/) +- [Release notes for 8.4.10](release-notes-8-4-10/) +- [Release notes for 8.4.7](release-notes-8-4-7/) +- [Release notes for 8.4.6](release-notes-8-4-6/) +- [Release notes for 8.4.5](release-notes-8-4-5/) +- [Release notes for 8.4.4](release-notes-8-4-4/) +- [Release notes for 8.4.3](release-notes-8-4-3/) +- [Release notes for 8.4.2](release-notes-8-4-2/) +- [Release notes for 8.4.1](release-notes-8-4-1/) +- [Release notes for 8.4.0-beta1](release-notes-8-4-0-beta1/) +- [Release notes for 8.3.11](release-notes-8-3-11/) +- [Release notes for 8.3.7](release-notes-8-3-7/) +- [Release notes for 8.3.6](release-notes-8-3-6/) +- [Release notes for 8.3.5](release-notes-8-3-5/) +- [Release notes for 8.3.4](release-notes-8-3-4/) +- [Release notes for 8.3.3](release-notes-8-3-3/) +- [Release notes for 8.3.2](release-notes-8-3-2/) +- [Release notes for 8.3.1](release-notes-8-3-1/) +- [Release notes for 8.3.0](release-notes-8-3-0/) +- [Release notes for 8.3.0-beta2](release-notes-8-3-0-beta2/) +- [Release notes for 8.3.0-beta1](release-notes-8-3-0-beta1/) +- [Release notes for 8.2.7](release-notes-8-2-7/) +- [Release notes for 8.2.6](release-notes-8-2-6/) +- [Release notes for 8.2.5](release-notes-8-2-5/) +- [Release notes for 8.2.4](release-notes-8-2-4/) +- [Release notes for 8.2.3](release-notes-8-2-3/) +- [Release notes for 8.2.2](release-notes-8-2-2/) +- [Release notes for 8.2.1](release-notes-8-2-1/) +- [Release notes for 8.2.0](release-notes-8-2-0/) +- [Release notes for 8.2.0-beta2](release-notes-8-2-0-beta2/) +- [Release notes for 8.2.0-beta1](release-notes-8-2-0-beta1/) +- [Release notes for 8.1.8](release-notes-8-1-8/) +- [Release notes for 8.1.7](release-notes-8-1-7/) +- [Release notes for 8.1.6](release-notes-8-1-6/) +- [Release notes for 8.1.5](release-notes-8-1-5/) +- [Release notes for 8.1.4](release-notes-8-1-4/) +- [Release notes for 8.1.3](release-notes-8-1-3/) +- [Release notes for 8.1.2](release-notes-8-1-2/) +- [Release notes for 8.1.1](release-notes-8-1-1/) +- [Release notes for 8.1.0](release-notes-8-1-0/) +- [Release notes for 8.1.0-beta3](release-notes-8-1-0-beta3/) +- [Release notes for 8.1.0-beta2](release-notes-8-1-0-beta2/) +- [Release notes for 8.1.0-beta1](release-notes-8-1-0-beta1/) +- [Release notes for 8.0.7](release-notes-8-0-7/) +- [Release notes for 8.0.6](release-notes-8-0-6/) +- [Release notes for 8.0.5](release-notes-8-0-5/) +- [Release notes for 8.0.4](release-notes-8-0-4/) +- [Release notes for 8.0.3](release-notes-8-0-3/) +- [Release notes for 8.0.2](release-notes-8-0-2/) +- [Release notes for 8.0.1](release-notes-8-0-1/) +- [Release notes for 8.0.0](release-notes-8-0-0/) +- [Release notes for 8.0.0-beta3](release-notes-8-0-0-beta3/) +- [Release notes for 8.0.0-beta2](release-notes-8-0-0-beta2/) +- [Release notes for 8.0.0-beta1](release-notes-8-0-0-beta1/) +- [Release notes for 7.5.15](release-notes-7-5-15/) +- [Release notes for 7.5.13](release-notes-7-5-13/) +- [Release notes for 7.5.12](release-notes-7-5-12/) +- [Release notes for 7.5.11](release-notes-7-5-11/) +- [Release notes for 7.5.10](release-notes-7-5-10/) +- [Release notes for 7.5.9](release-notes-7-5-9/) +- [Release notes for 7.5.8](release-notes-7-5-8/) +- [Release notes for 7.5.7](release-notes-7-5-7/) +- [Release notes for 7.5.6](release-notes-7-5-6/) +- [Release notes for 7.5.5](release-notes-7-5-5/) +- [Release notes for 7.5.4](release-notes-7-5-4/) +- [Release notes for 7.5.3](release-notes-7-5-3/) +- [Release notes for 7.5.2](release-notes-7-5-2/) +- [Release notes for 7.5.1](release-notes-7-5-1/) +- [Release notes for 7.5.0](release-notes-7-5-0/) +- [Release notes for 7.5.0-beta2](release-notes-7-5-0-beta2/) +- [Release notes for 7.5.0-beta1](release-notes-7-5-0-beta1/) +- [Release notes for 7.4.5](release-notes-7-4-5/) +- [Release notes for 7.4.3](release-notes-7-4-3/) +- [Release notes for 7.4.2](release-notes-7-4-2/) +- [Release notes for 7.4.1](release-notes-7-4-1/) +- [Release notes for 7.4.0](release-notes-7-4-0/) +- [Release notes for 7.3.10](release-notes-7-3-10/) +- [Release notes for 7.3.7](release-notes-7-3-7/) +- [Release notes for 7.3.6](release-notes-7-3-6/) +- [Release notes for 7.3.5](release-notes-7-3-5/) +- [Release notes for 7.3.4](release-notes-7-3-4/) +- [Release notes for 7.3.3](release-notes-7-3-3/) +- [Release notes for 7.3.2](release-notes-7-3-2/) +- [Release notes for 7.3.1](release-notes-7-3-1/) +- [Release notes for 7.3.0](release-notes-7-3-0/) diff --git a/docs/sources/setup-grafana/configure-docker.md b/docs/sources/setup-grafana/configure-docker.md index 0ad1aecabbd..f5c706f1845 100644 --- a/docs/sources/setup-grafana/configure-docker.md +++ b/docs/sources/setup-grafana/configure-docker.md @@ -84,9 +84,9 @@ For a list of available tags, refer to [grafana/grafana-oss](https://hub.docker. ## Default paths -Grafana comes with default configuration parameters that remain the same among versions regardless of the operating system or the environment (for example, virtual machine, Docker, Kubernetes, etc.). You can refer to the [Configure Grafana]({{< relref "./configure-grafana" >}}) documentation to view all the default configuration settings. +Grafana comes with default configuration parameters that remain the same among versions regardless of the operating system or the environment (for example, virtual machine, Docker, Kubernetes, etc.). You can refer to the [Configure Grafana](../configure-grafana/) documentation to view all the default configuration settings. -The following configurations are set by default when you start the Grafana Docker container. When running in Docker you cannot change the configurations by editing the `conf/grafana.ini` file. Instead, you can modify the configuration using [environment variables]({{< relref "./configure-grafana#override-configuration-with-environment-variables" >}}). +The following configurations are set by default when you start the Grafana Docker container. When running in Docker you cannot change the configurations by editing the `conf/grafana.ini` file. Instead, you can modify the configuration using [environment variables](../configure-grafana/#override-configuration-with-environment-variables). | Setting | Default value | | --------------------- | ------------------------- | @@ -99,7 +99,7 @@ The following configurations are set by default when you start the Grafana Docke ## Install plugins in the Docker container -You can install publicly available plugins and plugins that are private or used internally in an organization. For plugin installation instructions, refer to [Install plugins in the Docker container]({{< relref "./installation/docker#install-plugins-in-the-docker-container" >}}). +You can install publicly available plugins and plugins that are private or used internally in an organization. For plugin installation instructions, refer to [Install plugins in the Docker container](../installation/docker/#install-plugins-in-the-docker-container). ### Install plugins from other sources @@ -209,7 +209,7 @@ docker run -d -p 3000:3000 --name=grafana grafana-custom ## Logging -By default, Docker container logs are directed to `STDOUT`, a common practice in the Docker community. You can change this by setting a different [log mode]({{< relref "./configure-grafana#mode" >}}) such as `console`, `file`, or `syslog`. You can use one or more modes by separating them with spaces, for example, `console file`. By default, both `console` and `file` modes are enabled. +By default, Docker container logs are directed to `STDOUT`, a common practice in the Docker community. You can change this by setting a different [log mode](../configure-grafana/#mode) such as `console`, `file`, or `syslog`. You can use one or more modes by separating them with spaces, for example, `console file`. By default, both `console` and `file` modes are enabled. Example: @@ -235,7 +235,7 @@ The following example demonstrates how to set the admin password: ### Configure Docker secrets credentials for AWS CloudWatch -Grafana ships with built-in support for the [Amazon CloudWatch datasource]({{< relref "../datasources/aws-cloudwatch" >}}). To configure the data source, you must provide information such as the AWS ID-Key, secret access key, region, and so on. You can use Docker secrets as a way to provide this information. +Grafana ships with built-in support for the [Amazon CloudWatch datasource](../../datasources/aws-cloudwatch/). To configure the data source, you must provide information such as the AWS ID-Key, secret access key, region, and so on. You can use Docker secrets as a way to provide this information. Example: @@ -309,7 +309,7 @@ The following list includes the supported environment variables: By default, the Grafana log level is set to `INFO`, but you can increase the log level to `DEBUG` mode when you want to reproduce a problem. -For more information about logging, refer to [logs]({{< relref "./configure-grafana#log" >}}). +For more information about logging, refer to [logs](../configure-grafana/#log). ### Increase log level using the Docker run (CLI) command diff --git a/docs/sources/setup-grafana/configure-grafana/_index.md b/docs/sources/setup-grafana/configure-grafana/_index.md index 6469a11891b..5c7b92515ec 100644 --- a/docs/sources/setup-grafana/configure-grafana/_index.md +++ b/docs/sources/setup-grafana/configure-grafana/_index.md @@ -203,13 +203,13 @@ Override log path using the command line argument `cfg:default.paths.logs`: #### `plugins` -Directory where Grafana automatically scans and looks for plugins. For information about manually or automatically installing plugins, refer to [Install Grafana plugins]({{< relref "../../administration/plugin-management#install-grafana-plugins" >}}). +Directory where Grafana automatically scans and looks for plugins. For information about manually or automatically installing plugins, refer to [Install Grafana plugins](../../administration/plugin-management/#install-grafana-plugins). **macOS:** By default, the Mac plugin location is: `/usr/local/var/lib/grafana/plugins`. #### `provisioning` -Directory that contains [provisioning]({{< relref "../../administration/provisioning" >}}) configuration files that Grafana applies on startup. +Directory that contains [provisioning](../../administration/provisioning/) configuration files that Grafana applies on startup. Dashboards are reloaded when the JSON files change.


@@ -301,6 +301,10 @@ Path to the certificate file (if `protocol` is set to `https` or `h2`). Path to the certificate key file (if `protocol` is set to `https` or `h2`). +#### `cert_pass` + +Optional. Password to decrypt encrypted certificates. + #### `certs_watch_interval` Controls whether `cert_key` and `cert_file` are periodically watched for changes. @@ -471,7 +475,7 @@ Set to `true` to add metrics and tracing for database queries. The default value ### `[remote_cache]` -Caches authentication details and session information in the configured database, Redis or Memcached. This setting does not configure [Query Caching in Grafana Enterprise]({{< relref "../../administration/data-source-management#query-and-resource-caching" >}}). +Caches authentication details and session information in the configured database, Redis or Memcached. This setting does not configure [Query Caching in Grafana Enterprise](../../administration/data-source-management/#query-and-resource-caching). #### `type` @@ -696,6 +700,10 @@ An existing user's account is unable to login for five minutes if all login atte Configure how many login attempts a user can have within a five minute window before their account is locked. Default is `5`. +#### `disable_ip_address_login_protection` + +Set to `true` to disable [brute force login protection by IP address](https://cheatsheetseries.owasp.org/cheatsheets/Authentication_Cheat_Sheet.html#account-lockout). Default is `true`. Anyone from the IP address will be unable to login for 5 minutes if all login attempts are spent within a 5 minute window. + #### `cookie_secure` Set to `true` if you host Grafana behind HTTPS. Default is `false`. @@ -775,7 +783,7 @@ The following example limits access to the backend of a single plugin: #### `angular_support_enabled` This is set to false by default, meaning that the angular framework and support components aren't be loaded. -This means that all [plugins]({{< relref "../../developers/angular_deprecation/angular-plugins" >}}) and core features that depend on angular support won't work. +This means that all [plugins](../../developers/angular_deprecation/angular-plugins/) and core features that depend on angular support won't work. The core features that depend on angular are: @@ -876,7 +884,7 @@ For SQL data sources (MySql, Postgres, MSSQL) you can override the default maxim Set to `false` to prohibit users from being able to sign up or create user accounts. Default is `false`. A Grafana Admin can still create users. -For more information about creating a user, refer to [Add a user]({{< relref "../../administration/user-management/server-user-management#add-a-user" >}}). +For more information about creating a user, refer to [Add a user](../../administration/user-management/server-user-management/#add-a-user). #### `allow_org_create` @@ -942,10 +950,18 @@ If you manage users externally you can replace the user invite button for organi #### `viewers_can_edit` -Viewers can access and use [Explore]({{< relref "../../explore" >}}) and perform temporary edits on panels in dashboards they have access to. They cannot save their changes. Default is `false`. +{{< admonition type="note" >}} +This option is deprecated - assign your viewers as editors, if you are using RBAC assign the data sources explorer role to your users. +{{< /admonition >}} + +Viewers can access and use [Explore](../../explore/) and perform temporary edits on panels in dashboards they have access to. They cannot save their changes. Default is `false`. #### `editors_can_admin` +{{< admonition type="note" >}} +This option is deprecated - assign your editors as admins, if you are using RBAC assign the team creator role to your users. +{{< /admonition >}} + Editors can administrate dashboards, folders and teams they create. Default is `false`. @@ -975,7 +991,7 @@ This is a comma-separated list of usernames. Users specified here are hidden in ### `[auth]` -Grafana provides many ways to authenticate users. Refer to the Grafana [Authentication overview]({{< relref "../configure-security/configure-authentication" >}}) and other authentication documentation for detailed instructions on how to set up and configure authentication. +Grafana provides many ways to authenticate users. Refer to the Grafana [Authentication overview](../configure-security/configure-authentication/) and other authentication documentation for detailed instructions on how to set up and configure authentication. #### `login_cookie_name` @@ -1180,25 +1196,25 @@ This means the plugin can only access data and resources within that specific or ### `[auth.anonymous]` -Refer to [Anonymous authentication]({{< relref "../configure-security/configure-authentication/grafana#anonymous-authentication" >}}) for detailed instructions. +Refer to [Anonymous authentication](../configure-security/configure-authentication/grafana/#anonymous-authentication) for detailed instructions.
### `[auth.github]` -Refer to [GitHub OAuth2 authentication]({{< relref "../configure-security/configure-authentication/github" >}}) for detailed instructions. +Refer to [GitHub OAuth2 authentication](../configure-security/configure-authentication/github/) for detailed instructions.
### `[auth.gitlab]` -Refer to [GitLab OAuth 2.0 authentication]({{< relref "../configure-security/configure-authentication/gitlab" >}}) for detailed instructions. +Refer to [GitLab OAuth 2.0 authentication](../configure-security/configure-authentication/gitlab/) for detailed instructions.
### `[auth.google]` -Refer to [Google OAuth2 authentication]({{< relref "../configure-security/configure-authentication/google" >}}) for detailed instructions. +Refer to [Google OAuth2 authentication](../configure-security/configure-authentication/google/) for detailed instructions.
@@ -1216,37 +1232,37 @@ Legacy key names, still in the configuration file so they work in environment va ### `[auth.azuread]` -Refer to [Azure AD OAuth2 authentication]({{< relref "../configure-security/configure-authentication/azuread" >}}) for detailed instructions. +Refer to [Azure AD OAuth2 authentication](../configure-security/configure-authentication/azuread/) for detailed instructions.
### `[auth.okta]` -Refer to [Okta OAuth2 authentication]({{< relref "../configure-security/configure-authentication/okta" >}}) for detailed instructions. +Refer to [Okta OAuth2 authentication](../configure-security/configure-authentication/okta/) for detailed instructions.
### `[auth.generic_oauth]` -Refer to [Generic OAuth authentication]({{< relref "../configure-security/configure-authentication/generic-oauth" >}}) for detailed instructions. +Refer to [Generic OAuth authentication](../configure-security/configure-authentication/generic-oauth/) for detailed instructions.
### `[auth.basic]` -Refer to [Basic authentication]({{< relref "../configure-security/configure-authentication#basic-authentication" >}}) for detailed instructions. +Refer to [Basic authentication](../configure-security/configure-authentication/#basic-authentication) for detailed instructions.
### `[auth.proxy]` -Refer to [Auth proxy authentication]({{< relref "../configure-security/configure-authentication/auth-proxy" >}}) for detailed instructions. +Refer to [Auth proxy authentication](../configure-security/configure-authentication/auth-proxy/) for detailed instructions.
### `[auth.ldap]` -Refer to [LDAP authentication]({{< relref "../configure-security/configure-authentication/ldap" >}}) for detailed instructions. +Refer to [LDAP authentication](../configure-security/configure-authentication/ldap/) for detailed instructions. ### `[aws]` @@ -1361,7 +1377,13 @@ Override token URL for Azure Active Directory. By default is the same as token URL configured for AAD authentication settings. -#### `user_identity_client_id` +### `user_identity_client_authentication` + +Override client authentication method for Azure Active Directory. Currently supported values are `client_secret_post` and `managed_identity`. + +By default is the same as client authentication method configured for AAD authentication settings. + +### `user_identity_client_id` Override ADD application ID which would be used to exchange users token to an access token for the data source. @@ -1373,7 +1395,19 @@ Override the AAD application client secret. By default is the same as used in AAD authentication or can be set to another application (for OBO flow). -#### `forward_settings_to_plugins` +### `user_identity_managed_identity_client_id` + +Override the AAD application managed identity client ID of the federated credential configured as a user-assigned managed identity. + +By default is the same as used in AAD authentication or can be set to another managed identity (for OBO flow). + +### `user_identity_federated_credential_audience` + +Override the AAD federated credential audience of the federated credential configured as a user-assigned managed identity. + +By default is the same as used in AAD authentication or can be set to another audience (for OBO flow). + +### `forward_settings_to_plugins` Set plugins to receive Azure settings via plugin context. @@ -1387,7 +1421,7 @@ Disabled by default, needs to be explicitly enabled. ### `[auth.jwt]` -Refer to [JWT authentication]({{< relref "../configure-security/configure-authentication/jwt" >}}) for more information. +Refer to [JWT authentication](../configure-security/configure-authentication/jwt/) for more information.
@@ -1489,6 +1523,16 @@ Options are `debug`, `info`, `warn`, `error`, and `critical`. Default is `info`. Optional settings to set different levels for specific loggers. For example: `filters = sqlstore:debug` +You can use multiple filters with a comma-seperated list: +For example: `filters = sqlstore:debug,plugins:info` + +The equivalent for a `docker-compose.yaml` looks like this: + +``` +GF_LOG_FILTERS: sqlstore:debug,plugins:info +GF_LOG_LEVEL: error +``` + #### `user_facing_default_error` Use this configuration option to set the default error message shown to users. This message is displayed instead of sensitive backend errors, which should be obfuscated. The default message is `Please inspect the Grafana server log for details.`. @@ -1682,7 +1726,7 @@ Limit the number of query evaluation results per alert rule. If the condition qu ### `[unified_alerting]` -For more information about the Grafana alerts, refer to [Grafana Alerting]({{< relref "../../alerting" >}}). +For more information about the Grafana alerts, refer to [Grafana Alerting](../../alerting/). #### `enabled` @@ -1795,7 +1839,7 @@ The timeout string is a possibly signed sequence of decimal numbers, followed by #### `max_attempts` -Sets a maximum number of times Grafana attempts to evaluate an alert rule before giving up on that evaluation. The default value is `1`. +Sets a maximum number of times Grafana attempts to evaluate an alert rule before giving up on that evaluation. The default value is `3`. #### `min_interval` @@ -1814,7 +1858,7 @@ If a rule frequency is lower than this value, then this value is enforced. ### `[unified_alerting.screenshots]` -For more information about screenshots, refer to [Images in notifications]({{< relref "../../alerting/configure-notifications/template-notifications/images-in-notifications" >}}). +For more information about screenshots, refer to [Images in notifications](../../alerting/configure-notifications/template-notifications/images-in-notifications/). #### `capture` @@ -1905,7 +1949,7 @@ Configures max number of API annotations that Grafana keeps. Default value is 0, ### `[explore]` -For more information about this feature, refer to [Explore]({{< relref "../../explore" >}}). +For more information about this feature, refer to [Explore](../../explore/). #### `enabled` @@ -1916,6 +1960,10 @@ Enable or disable the Explore section. Default is `enabled`. Set a default time offset from now on the time picker. Default is 1 hour. This setting should be expressed as a duration. Examples: 1h (hour), 1d (day), 1w (week), 1M (month). +#### `hide_logs_download` + +Show or hide the button to download logs in Explore. Default is `false`, so that the button will be visible. + ### `[help]` Configures the help section. @@ -1978,7 +2026,7 @@ Short links without an expiration increase the size of the database and can't be ### `[metrics]` -For detailed instructions, refer to [Internal Grafana metrics]({{< relref "../set-up-grafana-monitoring" >}}). +For detailed instructions, refer to [Internal Grafana metrics](../set-up-grafana-monitoring/). #### `enabled` @@ -2330,6 +2378,8 @@ URL to a remote HTTP image renderer service, for example, `http://localhost:8081 If the remote HTTP image renderer service runs on a different server than the Grafana server you may have to configure this to a URL where Grafana is reachable, for example, http://grafana.domain/. +The `callback_url` can also be configured to support usage of the image renderer running as a plugin with support for SSL / HTTPS. For example https://localhost:3000/. + #### `concurrent_render_request_limit` Concurrent render request limit affects when the /render HTTP endpoint is used. Rendering many images at the same time can overload the server, @@ -2373,7 +2423,7 @@ Set to `true` if you want to test alpha plugins that are not yet ready for gener Enter a comma-separated list of plugin identifiers to identify plugins to load even if they are unsigned. Plugins with modified signatures are never loaded. -We do _not_ recommend using this option. For more information, refer to [Plugin signatures]({{< relref "../../administration/plugin-management#plugin-signatures" >}}). +We do _not_ recommend using this option. For more information, refer to [Plugin signatures](../../administration/plugin-management/#plugin-signatures). #### `plugin_admin_enabled` @@ -2381,7 +2431,7 @@ Available to Grafana administrators only, enables installing, uninstalling, and Set to `true` by default. Setting it to `false` hides the controls. -For more information, refer to [Plugin catalog]({{< relref "../../administration/plugin-management#plugin-catalog" >}}). +For more information, refer to [Plugin catalog](../../administration/plugin-management/#plugin-catalog). #### `plugin_admin_external_manage_enabled` @@ -2443,7 +2493,7 @@ This option disables all preinstalled plugins. The default is `false`. To disabl The `max_connections` option specifies the maximum number of connections to the Grafana Live WebSocket endpoint per Grafana server instance. Default is `100`. -Refer to [Grafana Live configuration documentation]({{< relref "../set-up-grafana-live" >}}) if you specify a number higher than default since this can require some operating system and infrastructure tuning. +Refer to [Grafana Live configuration documentation](../set-up-grafana-live/) if you specify a number higher than default since this can require some operating system and infrastructure tuning. 0 disables Grafana Live, -1 means unlimited connections. @@ -2451,7 +2501,7 @@ Refer to [Grafana Live configuration documentation]({{< relref "../set-up-grafan The `allowed_origins` option is a comma-separated list of additional origins (`Origin` header of HTTP Upgrade request during WebSocket connection establishment) that is accepted by Grafana Live. -If not set (default), then the origin is matched over [root_url]({{< relref "#root_url" >}}) which should be sufficient for most scenarios. +If not set (default), then the origin is matched over [root_url](#root_url) which should be sufficient for most scenarios. Origin patterns support wildcard symbol "\*". @@ -2468,7 +2518,7 @@ allowed_origins = "https://*.example.com" The high availability (HA) engine name for Grafana Live. By default, it's not set. The only possible value is `redis`. -For more information, refer to the [Configure Grafana Live HA setup]({{< relref "../set-up-grafana-live#configure-grafana-live-ha-setup" >}}). +For more information, refer to the [Configure Grafana Live HA setup](../set-up-grafana-live/#configure-grafana-live-ha-setup). #### `ha_engine_address` @@ -2508,7 +2558,7 @@ Experimental. Requires the feature toggle `externalCorePlugins` to be enabled. ### `[plugin.grafana-image-renderer]` -For more information, refer to [Image rendering]({{< relref "../image-rendering" >}}). +For more information, refer to [Image rendering](../image-rendering/). #### `rendering_timezone` @@ -2615,7 +2665,7 @@ Change the listening port of the gRPC server. Default port is `0` and uses a por ### `[enterprise]` -For more information about Grafana Enterprise, refer to [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}). +For more information about Grafana Enterprise, refer to [Grafana Enterprise](../../introduction/grafana-enterprise/).
@@ -2635,7 +2685,7 @@ Some feature toggles for stable features are on by default. Use this setting to The options in this section configure the experimental Feature Toggle Admin Page feature, which is enabled using the `featureToggleAdminPage` feature toggle. Grafana Labs offers support on a best-effort basis, and breaking changes might occur prior to the feature being made generally available. -For more information, refer to [Configure feature toggles]({{< relref "./feature-toggles" >}}). +For more information, refer to [Configure feature toggles](feature-toggles/). #### `allow_editing` @@ -2728,7 +2778,7 @@ Set this to `false` to disable loading other custom base maps and hide them in t ### `[rbac]` -Refer to [Role-based access control]({{< relref "../../administration/roles-and-permissions/access-control" >}}) for more information. +Refer to [Role-based access control](../../administration/roles-and-permissions/access-control/) for more information. ### `[navigation.app_sections]` diff --git a/docs/sources/setup-grafana/configure-grafana/configure-custom-branding/index.md b/docs/sources/setup-grafana/configure-grafana/configure-custom-branding/index.md index 8a16c6e293d..a0a33ea3229 100644 --- a/docs/sources/setup-grafana/configure-grafana/configure-custom-branding/index.md +++ b/docs/sources/setup-grafana/configure-grafana/configure-custom-branding/index.md @@ -15,7 +15,7 @@ weight: 300 Custom branding enables you to replace the Grafana Labs brand and logo with your corporate brand and logo. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). For Cloud Advanced and Enterprise customers, please provide custom elements and logos to our Support team. We will help you host your images and update your custom branding. +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). For Cloud Advanced and Enterprise customers, please provide custom elements and logos to our Support team. We will help you host your images and update your custom branding. This feature is not available for Grafana Free and Pro tiers. For more information on feature availability across plans, refer to our [feature comparison page](/docs/grafana-cloud/cost-management-and-billing/understand-grafana-cloud-features/) @@ -39,7 +39,7 @@ With custom branding, you have the ability to modify the following elements: > You will have to host your logo and other images used by the custom branding feature separately. Make sure Grafana can access the URL where the assets are stored. -The configuration file in Grafana Enterprise contains the following options. For more information about configuring Grafana, refer to [Configure Grafana]({{< relref "../../configure-grafana" >}}). +The configuration file in Grafana Enterprise contains the following options. For more information about configuring Grafana, refer to [Configure Grafana](../). ```ini # Enterprise only diff --git a/docs/sources/setup-grafana/configure-grafana/enterprise-configuration/index.md b/docs/sources/setup-grafana/configure-grafana/enterprise-configuration/index.md index c75522253e2..bf4b6fc65c6 100644 --- a/docs/sources/setup-grafana/configure-grafana/enterprise-configuration/index.md +++ b/docs/sources/setup-grafana/configure-grafana/enterprise-configuration/index.md @@ -12,7 +12,7 @@ weight: 100 # Configure Grafana Enterprise -This page describes Grafana Enterprise-specific configuration options that you can specify in a `.ini` configuration file or using environment variables. Refer to [Configuration]({{< relref "../../configure-grafana" >}}) for more information about available configuration options. +This page describes Grafana Enterprise-specific configuration options that you can specify in a `.ini` configuration file or using environment variables. Refer to [Configuration](../) for more information about available configuration options. ## [enterprise] @@ -41,7 +41,7 @@ The license only automatically updates once per day. To immediately update the t ### license_validation_type -When set to `aws`, Grafana will validate its license status with Amazon Web Services (AWS) instead of with Grafana Labs. Only use this setting if you purchased an Enterprise license from AWS Marketplace. Defaults to empty, which means that by default Grafana Enterprise will validate using a license issued by Grafana Labs. For details about licenses issued by AWS, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace]({{< relref "../../../administration/enterprise-licensing/activate-aws-marketplace-license" >}}). +When set to `aws`, Grafana will validate its license status with Amazon Web Services (AWS) instead of with Grafana Labs. Only use this setting if you purchased an Enterprise license from AWS Marketplace. Defaults to empty, which means that by default Grafana Enterprise will validate using a license issued by Grafana Labs. For details about licenses issued by AWS, refer to [Activate a Grafana Enterprise license purchased through AWS Marketplace](../../../administration/enterprise-licensing/activate-aws-marketplace-license/). ## [white_labeling] @@ -84,7 +84,7 @@ List the link IDs to use here. Grafana will look for matching link configuration ## [usage_insights.export] -By [exporting usage logs]({{< relref "../../configure-security/export-logs" >}}), you can directly query them and create dashboards of the information that matters to you most, such as dashboard errors, most active organizations, or your top-10 most-used queries. +By [exporting usage logs](../../configure-security/export-logs/), you can directly query them and create dashboards of the information that matters to you most, such as dashboard errors, most active organizations, or your top-10 most-used queries. ### enabled @@ -144,7 +144,7 @@ Enable or disable the reporting feature. When disabled, no reports are generated ### rendering_timeout -Timeout for the following reporting rendering requests: generating PDFs, generating embedded dashboard images for report emails, and generating attached CSV files. Default is 10 seconds. +Timeout for the following reporting rendering requests: generating PDFs, generating embedded dashboard images for report emails, and generating attached CSV files. Default is 10 seconds (`10s`). ### concurrent_render_limit @@ -184,7 +184,7 @@ Allowed domains to receive reports. Use an asterisk (`*`) to allow all domains. ## [auditing] -[Auditing]({{< relref "../../configure-security/audit-grafana" >}}) allows you to track important changes to your Grafana instance. By default, audit logs are logged to file but the auditing feature also supports sending logs directly to Loki. +[Auditing](../../configure-security/audit-grafana/) allows you to track important changes to your Grafana instance. By default, audit logs are logged to file but the auditing feature also supports sending logs directly to Loki. ### enabled @@ -409,7 +409,7 @@ Setting 'enabled' to `true` allows users to configure query caching for data sou This value is `true` by default. {{% admonition type="note" %}} -This setting enables the caching feature, but it does not turn on query caching for any data source. To turn on query caching for a data source, update the setting on the data source configuration page. For more information, refer to the [query caching docs]({{< relref "../../../administration/data-source-management#enable-and-configure-query-caching" >}}). +This setting enables the caching feature, but it does not turn on query caching for any data source. To turn on query caching for a data source, update the setting on the data source configuration page. For more information, refer to the [query caching docs](../../../administration/data-source-management/#enable-and-configure-query-caching). {{% /admonition %}} ### ttl diff --git a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md index 2bd6d4eef14..c401c8dd581 100644 --- a/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md +++ b/docs/sources/setup-grafana/configure-grafana/feature-toggles/index.md @@ -13,7 +13,7 @@ weight: 150 You use feature toggles, also known as feature flags, to enable or disable features in Grafana. You can turn on feature toggles to try out new functionality in development or test environments. -This page contains a list of available feature toggles. To learn how to turn on feature toggles, refer to our [Configure Grafana documentation]({{< relref "../_index.md#feature_toggles" >}}). Feature toggles are also available to Grafana Cloud Advanced customers. If you use Grafana Cloud Advanced, you can open a support ticket and specify the feature toggles and stack for which you want them enabled. +This page contains a list of available feature toggles. To learn how to turn on feature toggles, refer to our [Configure Grafana documentation](../#feature_toggles). Feature toggles are also available to Grafana Cloud Advanced customers. If you use Grafana Cloud Advanced, you can open a support ticket and specify the feature toggles and stack for which you want them enabled. For more information about feature release stages, refer to [Release life cycle for Grafana Labs](https://grafana.com/docs/release-life-cycle/) and [Manage feature toggles](https://grafana.com/docs/grafana//administration/feature-toggles/#manage-feature-toggles). @@ -28,7 +28,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `featureHighlights` | Highlight Grafana Enterprise features | | | `correlations` | Correlations page | Yes | | `cloudWatchCrossAccountQuerying` | Enables cross-account querying in CloudWatch datasources | Yes | -| `accessControlOnCall` | Access control primitives for OnCall | Yes | | `nestedFolders` | Enable folder nesting | Yes | | `logsContextDatasourceUi` | Allow datasource to provide custom UI for context view | Yes | | `lokiQuerySplitting` | Split large interval queries into subqueries with smaller time intervals | Yes | @@ -46,11 +45,9 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `alertingInsights` | Show the new alerting insights landing page | Yes | | `panelMonitoring` | Enables panel monitoring through logs and measurements | Yes | | `formatString` | Enable format string transformer | Yes | -| `transformationsVariableSupport` | Allows using variables in transformations | Yes | | `kubernetesPlaylists` | Use the kubernetes API in the frontend for playlists, and route /api/playlist requests to k8s | Yes | | `recoveryThreshold` | Enables feature recovery threshold (aka hysteresis) for threshold server-side expression | Yes | | `lokiStructuredMetadata` | Enables the loki data source to request structured metadata from the Loki server | Yes | -| `managedPluginsInstall` | Install managed plugins directly from plugins catalog | Yes | | `addFieldFromCalculationStatFunctions` | Add cumulative and window functions to the add field from calculation transformation | Yes | | `annotationPermissionUpdate` | Change the way annotation permissions work by scoping them to folders and dashboards. | Yes | | `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | Yes | @@ -58,21 +55,20 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `dashboardScene` | Enables dashboard rendering using scenes for all roles | Yes | | `ssoSettingsApi` | Enables the SSO settings API and the OAuth configuration UIs in Grafana | Yes | | `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | Yes | -| `exploreMetrics` | Enables the new Explore Metrics core app | Yes | +| `exploreMetrics` | Enables the new Grafana Metrics Drilldown core app | Yes | | `alertingSimplifiedRouting` | Enables users to easily configure alert notifications by specifying a contact point directly when editing or creating an alert rule | Yes | | `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes | | `lokiQueryHints` | Enables query hints for Loki | Yes | | `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | | -| `promQLScope` | In-development feature that will allow injection of labels into prometheus queries. | Yes | | `groupToNestedTableTransformation` | Enables the group to nested table transformation | Yes | | `newPDFRendering` | New implementation for the dashboard-to-PDF rendering | Yes | | `tlsMemcached` | Use TLS-enabled memcached in the enterprise caching feature | Yes | +| `ssoSettingsSAML` | Use the new SSO Settings API to configure the SAML connector | Yes | | `cloudWatchNewLabelParsing` | Updates CloudWatch label parsing to be more accurate | Yes | | `accessActionSets` | Introduces action sets for resource permissions. Also ensures that all folder editors and admins can create subfolders without needing any additional permissions. | Yes | | `newDashboardSharingComponent` | Enables the new sharing drawer design | Yes | | `pluginProxyPreserveTrailingSlash` | Preserve plugin proxy trailing slash. | | | `pinNavItems` | Enables pinning of nav items | Yes | -| `openSearchBackendFlowEnabled` | Enables the backend query flow for Open Search datasource plugin | Yes | | `alertingApiServer` | Register Alerting APIs with the K8s API server | Yes | | `cloudWatchRoundUpEndTime` | Round up end time for metric queries to the next minute to avoid missing data | Yes | | `newFiltersUI` | Enables new combobox style UI for the Ad hoc filters variable in scenes architecture | Yes | @@ -81,7 +77,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `userStorageAPI` | Enables the user storage API | Yes | | `azureMonitorDisableLogLimit` | Disables the log limit restriction for Azure Monitor when true. The limit is enabled by default. | | | `preinstallAutoUpdate` | Enables automatic updates for pre-installed plugins | Yes | -| `zipkinBackendMigration` | Enables querying Zipkin data source without the proxy | Yes | | `reportingUseRawTimeRange` | Uses the original report or dashboard time range instead of making an absolute transformation | Yes | | `alertingUIOptimizeReducer` | Enables removing the reducer from the alerting UI when creating a new alert rule and using instant query | Yes | | `azureMonitorEnableUserAuth` | Enables user auth for Azure Monitor datasource only | Yes | @@ -103,7 +98,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `autoMigrateStatPanel` | Migrate old stat panel to supported stat panel - broken out from autoMigrateOldPanels to enable granular tracking | | `disableAngular` | Dynamic flag to disable angular at runtime. The preferred method is to set `angular_support_enabled` to `false` in the [security] settings, which allows you to change the state at runtime. | | `grpcServer` | Run the GRPC server | -| `alertingNoNormalState` | Stop maintaining state of alerts that are not firing | | `renderAuthJWT` | Uses JWT-based auth for rendering instead of relying on remote cache | | `refactorVariablesTimeRange` | Refactor time range variables flow to reduce number of API calls made when query variables are chained | | `faroDatasourceSelector` | Enable the data source selector within the Frontend Apps section of the Frontend Observability | @@ -112,134 +106,132 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general- | `reportingRetries` | Enables rendering retries for the reporting feature | | `externalServiceAccounts` | Automatic service account and token setup for plugins | | `cloudWatchBatchQueries` | Runs CloudWatch metrics queries as separate batches | -| `teamHttpHeaders` | Enables LBAC for datasources to apply LogQL filtering of logs to the client requests for users in teams | | `pdfTables` | Enables generating table data as PDF in reporting | | `canvasPanelPanZoom` | Allow pan and zoom in canvas panel | | `regressionTransformation` | Enables regression analysis transformation | | `onPremToCloudMigrations` | Enable the Grafana Migration Assistant, which helps you easily migrate on-prem resources, such as dashboards, folders, and data source configurations, to your Grafana Cloud stack. | -| `ssoSettingsSAML` | Use the new SSO Settings API to configure the SAML connector | +| `alertingSaveStateCompressed` | Enables the compressed protobuf-based alert state storage | | `azureMonitorPrometheusExemplars` | Allows configuration of Azure Monitor as a data source that can provide Prometheus exemplars | | `ssoSettingsLDAP` | Use the new SSO Settings API to configure LDAP | | `improvedExternalSessionHandling` | Enables improved support for OAuth external sessions. After enabling this feature, users might need to re-authenticate themselves. | | `elasticsearchCrossClusterSearch` | Enables cross cluster search in the Elasticsearch datasource | | `improvedExternalSessionHandlingSAML` | Enables improved support for SAML external sessions. Ensure the NameID format is correctly configured in Grafana for SAML Single Logout to function properly. | +| `alertRuleRestore` | Enables the alert rule restore feature | ## Experimental feature toggles [Experimental](https://grafana.com/docs/release-life-cycle/#experimental) features are early in their development lifecycle and so are not yet supported in Grafana Cloud. Experimental features might be changed or removed without prior notice. -| Feature toggle name | Description | -| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `live-service-web-worker` | This will use a webworker thread to processes events rather than the main thread | -| `queryOverLive` | Use Grafana Live WebSocket to execute backend queries | -| `lokiExperimentalStreaming` | Support new streaming approach for loki (prototype, needs special loki build) | -| `storage` | Configurable storage for dashboards, datasources, and resources | -| `canvasPanelNesting` | Allow elements nesting | -| `vizActions` | Allow actions in visualizations | -| `disableSecretsCompatibility` | Disable duplicated secret storage in legacy tables | -| `logRequestsInstrumentedAsUnknown` | Logs the path for requests that are instrumented as unknown | -| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema | -| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query | -| `alertingBacktesting` | Rule backtesting API for alerting | -| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files | -| `lokiShardSplitting` | Use stream shards to split queries into smaller subqueries | -| `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries | -| `individualCookiePreferences` | Support overriding cookie preferences per user | -| `influxqlStreamingParser` | Enable streaming JSON parser for InfluxDB datasource InfluxQL query language | -| `lokiLogsDataplane` | Changes logs responses from Loki to be compliant with the dataplane specification. | -| `disableSSEDataplane` | Disables dataplane specific processing in server side expressions. | -| `alertStateHistoryLokiSecondary` | Enable Grafana to write alert state history to an external Loki instance in addition to Grafana annotations. | -| `alertStateHistoryLokiPrimary` | Enable a remote Loki instance as the primary source for state history reads. | -| `alertStateHistoryLokiOnly` | Disable Grafana alerts from emitting annotations when a remote Loki instance is available. | -| `extraThemes` | Enables extra themes | -| `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor | -| `frontendSandboxMonitorOnly` | Enables monitor only in the plugin frontend sandbox (if enabled) | -| `pluginsDetailsRightPanel` | Enables right panel for the plugins details page | -| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers | -| `mlExpressions` | Enable support for Machine Learning in server-side expressions | -| `metricsSummary` | Enables metrics summary queries in the Tempo data source | -| `datasourceAPIServers` | Expose some datasources as apiservers. | -| `provisioning` | Next generation provisioning... and git | -| `permissionsFilterRemoveSubquery` | Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder | -| `aiGeneratedDashboardChanges` | Enable AI powered features for dashboards to auto-summary changes when saving | -| `sseGroupByDatasource` | Send query to the same datasource in a single request when using server side expressions. The `cloudWatchBatchQueries` feature toggle should be enabled if this used with CloudWatch. | -| `libraryPanelRBAC` | Enables RBAC support for library panels | -| `wargamesTesting` | Placeholder feature flag for internal testing | -| `externalCorePlugins` | Allow core plugins to be loaded as external | -| `pluginsAPIMetrics` | Sends metrics of public grafana packages usage by plugins | -| `enableNativeHTTPHistogram` | Enables native HTTP Histograms | -| `disableClassicHTTPHistogram` | Disables classic HTTP Histogram (use with enableNativeHTTPHistogram) | -| `kubernetesSnapshots` | Routes snapshot requests from /api to the /apis endpoint | -| `kubernetesDashboards` | Use the kubernetes API in the frontend for dashboards | -| `kubernetesCliDashboards` | Use the k8s client to retrieve dashboards internally | -| `kubernetesRestore` | Allow restoring objects in k8s | -| `kubernetesFolders` | Use the kubernetes API in the frontend for folders, and route /api/folders requests to k8s | -| `kubernetesFoldersServiceV2` | Use the Folders Service V2, and route Folder Service requests to k8s | -| `grafanaAPIServerTestingWithExperimentalAPIs` | Facilitate integration testing of experimental APIs | -| `datasourceQueryTypes` | Show query type endpoints in datasource API servers (currently hardcoded for testdata, expressions, and prometheus) | -| `queryService` | Register /apis/query.grafana.app/ -- will eventually replace /api/ds/query | -| `queryServiceRewrite` | Rewrite requests targeting /ds/query to the query service | -| `queryServiceFromUI` | Routes requests to the new query service | -| `cachingOptimizeSerializationMemoryUsage` | If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses. | -| `prometheusPromQAIL` | Prometheus and AI/ML to assist users in creating a query | -| `prometheusCodeModeMetricNamesSearch` | Enables search for metric names in Code Mode, to improve performance when working with an enormous number of metric names | -| `alertmanagerRemoteSecondary` | Enable Grafana to sync configuration and state with a remote Alertmanager. | -| `alertmanagerRemotePrimary` | Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager. | -| `alertmanagerRemoteOnly` | Disable the internal Alertmanager and only use the external one defined. | -| `extractFieldsNameDeduplication` | Make sure extracted field names are unique in the dataframe | -| `dashboardNewLayouts` | Enables experimental new dashboard layouts | -| `pluginsSkipHostEnvVars` | Disables passing host environment variable to plugin processes | -| `tableSharedCrosshair` | Enables shared crosshair in table panel | -| `kubernetesFeatureToggles` | Use the kubernetes API for feature toggle management in the frontend | -| `newFolderPicker` | Enables the nested folder picker without having nested folders enabled | -| `onPremToCloudMigrationsAuthApiMig` | Enables the use of auth api instead of gcom for internal token services. Requires `onPremToCloudMigrations` to be enabled in conjunction. | -| `scopeApi` | In-development feature flag for the scope api using the app platform. | -| `sqlExpressions` | Enables using SQL and DuckDB functions as Expressions. | -| `nodeGraphDotLayout` | Changed the layout algorithm for the node graph | -| `kubernetesAggregator` | Enable grafana's embedded kube-aggregator | -| `expressionParser` | Enable new expression parser | -| `disableNumericMetricsSortingInExpressions` | In server-side expressions, disable the sorting of numeric-kind metrics by their metric name or labels. | -| `queryLibrary` | Enables Query Library feature in Explore | -| `logsExploreTableDefaultVisualization` | Sets the logs table as default visualisation in logs explore | -| `alertingListViewV2` | Enables the new alert list view design | -| `dashboardRestore` | Enables deleted dashboard restore feature | -| `alertingCentralAlertHistory` | Enables the new central alert history. | -| `sqlQuerybuilderFunctionParameters` | Enables SQL query builder function parameters | -| `failWrongDSUID` | Throws an error if a datasource has an invalid UIDs | -| `dataplaneAggregator` | Enable grafana dataplane aggregator | -| `lokiSendDashboardPanelNames` | Send dashboard and panel names to Loki when querying | -| `alertingPrometheusRulesPrimary` | Uses Prometheus rules as the primary source of truth for ruler-enabled data sources | -| `exploreLogsShardSplitting` | Used in Explore Logs to split queries into multiple queries based on the number of shards | -| `exploreLogsAggregatedMetrics` | Used in Explore Logs to query by aggregated metrics | -| `exploreLogsLimitedTimeRange` | Used in Explore Logs to limit the time range | -| `homeSetupGuide` | Used in Home for users who want to return to the onboarding flow or quickly find popular config pages | -| `appSidecar` | Enable the app sidecar feature that allows rendering 2 apps at the same time | -| `rolePickerDrawer` | Enables the new role picker drawer design | -| `pluginsSriChecks` | Enables SRI checks for plugin assets | -| `unifiedStorageBigObjectsSupport` | Enables to save big objects in blob storage | -| `timeRangeProvider` | Enables time pickers sync | -| `prometheusUsesCombobox` | Use new combobox component for Prometheus query editor | -| `playlistsReconciler` | Enables experimental reconciler for playlists | -| `prometheusSpecialCharsInLabelValues` | Adds support for quotes and special characters in label values for Prometheus queries | -| `enableExtensionsAdminPage` | Enables the extension admin page regardless of development mode | -| `enableSCIM` | Enables SCIM support for user and group management | -| `crashDetection` | Enables browser crash detection reporting to Faro. | -| `jaegerBackendMigration` | Enables querying the Jaeger data source without the proxy | -| `useV2DashboardsAPI` | Use the v2 kubernetes API in the frontend for dashboards | -| `unifiedHistory` | Displays the navigation history so the user can navigate back to previous pages | -| `investigationsBackend` | Enable the investigations backend API | -| `k8SFolderCounts` | Enable folder's api server counts | -| `k8SFolderMove` | Enable folder's api server move | -| `teamHttpHeadersMimir` | Enables LBAC for datasources for Mimir to apply LBAC filtering of metrics to the client requests for users in teams | -| `queryLibraryDashboards` | Enables Query Library feature in Dashboards | -| `grafanaAdvisor` | Enables Advisor app | -| `elasticsearchImprovedParsing` | Enables less memory intensive Elasticsearch result parsing | -| `datasourceConnectionsTab` | Shows defined connections for a data source in the plugins detail page | +| Feature toggle name | Description | +| ------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `live-service-web-worker` | This will use a webworker thread to processes events rather than the main thread | +| `queryOverLive` | Use Grafana Live WebSocket to execute backend queries | +| `lokiExperimentalStreaming` | Support new streaming approach for loki (prototype, needs special loki build) | +| `storage` | Configurable storage for dashboards, datasources, and resources | +| `canvasPanelNesting` | Allow elements nesting | +| `disableSecretsCompatibility` | Disable duplicated secret storage in legacy tables | +| `logRequestsInstrumentedAsUnknown` | Logs the path for requests that are instrumented as unknown | +| `showDashboardValidationWarnings` | Show warnings when dashboards do not validate against the schema | +| `mysqlAnsiQuotes` | Use double quotes to escape keyword in a MySQL query | +| `alertingBacktesting` | Rule backtesting API for alerting | +| `editPanelCSVDragAndDrop` | Enables drag and drop for CSV and Excel files | +| `lokiShardSplitting` | Use stream shards to split queries into smaller subqueries | +| `lokiQuerySplittingConfig` | Give users the option to configure split durations for Loki queries | +| `individualCookiePreferences` | Support overriding cookie preferences per user | +| `influxqlStreamingParser` | Enable streaming JSON parser for InfluxDB datasource InfluxQL query language | +| `lokiLogsDataplane` | Changes logs responses from Loki to be compliant with the dataplane specification. | +| `disableSSEDataplane` | Disables dataplane specific processing in server side expressions. | +| `alertStateHistoryLokiSecondary` | Enable Grafana to write alert state history to an external Loki instance in addition to Grafana annotations. | +| `alertStateHistoryLokiPrimary` | Enable a remote Loki instance as the primary source for state history reads. | +| `alertStateHistoryLokiOnly` | Disable Grafana alerts from emitting annotations when a remote Loki instance is available. | +| `extraThemes` | Enables extra themes | +| `lokiPredefinedOperations` | Adds predefined query operations to Loki query editor | +| `frontendSandboxMonitorOnly` | Enables monitor only in the plugin frontend sandbox (if enabled) | +| `pluginsDetailsRightPanel` | Enables right panel for the plugins details page | +| `awsDatasourcesTempCredentials` | Support temporary security credentials in AWS plugins for Grafana Cloud customers | +| `mlExpressions` | Enable support for Machine Learning in server-side expressions | +| `metricsSummary` | Enables metrics summary queries in the Tempo data source | +| `datasourceAPIServers` | Expose some datasources as apiservers. | +| `provisioning` | Next generation provisioning... and git | +| `permissionsFilterRemoveSubquery` | Alternative permission filter implementation that does not use subqueries for fetching the dashboard folder | +| `aiGeneratedDashboardChanges` | Enable AI powered features for dashboards to auto-summary changes when saving | +| `sseGroupByDatasource` | Send query to the same datasource in a single request when using server side expressions. The `cloudWatchBatchQueries` feature toggle should be enabled if this used with CloudWatch. | +| `libraryPanelRBAC` | Enables RBAC support for library panels | +| `wargamesTesting` | Placeholder feature flag for internal testing | +| `externalCorePlugins` | Allow core plugins to be loaded as external | +| `pluginsAPIMetrics` | Sends metrics of public grafana packages usage by plugins | +| `enableNativeHTTPHistogram` | Enables native HTTP Histograms | +| `disableClassicHTTPHistogram` | Disables classic HTTP Histogram (use with enableNativeHTTPHistogram) | +| `kubernetesSnapshots` | Routes snapshot requests from /api to the /apis endpoint | +| `kubernetesDashboards` | Use the kubernetes API in the frontend for dashboards | +| `kubernetesRestore` | Allow restoring objects in k8s | +| `kubernetesClientDashboardsFolders` | Route the folder and dashboard service requests to k8s | +| `datasourceQueryTypes` | Show query type endpoints in datasource API servers (currently hardcoded for testdata, expressions, and prometheus) | +| `queryService` | Register /apis/query.grafana.app/ -- will eventually replace /api/ds/query | +| `queryServiceRewrite` | Rewrite requests targeting /ds/query to the query service | +| `queryServiceFromUI` | Routes requests to the new query service | +| `cachingOptimizeSerializationMemoryUsage` | If enabled, the caching backend gradually serializes query responses for the cache, comparing against the configured `[caching]max_value_mb` value as it goes. This can can help prevent Grafana from running out of memory while attempting to cache very large query responses. | +| `prometheusCodeModeMetricNamesSearch` | Enables search for metric names in Code Mode, to improve performance when working with an enormous number of metric names | +| `alertmanagerRemoteSecondary` | Enable Grafana to sync configuration and state with a remote Alertmanager. | +| `alertmanagerRemotePrimary` | Enable Grafana to have a remote Alertmanager instance as the primary Alertmanager. | +| `alertmanagerRemoteOnly` | Disable the internal Alertmanager and only use the external one defined. | +| `extractFieldsNameDeduplication` | Make sure extracted field names are unique in the dataframe | +| `dashboardNewLayouts` | Enables experimental new dashboard layouts | +| `pluginsSkipHostEnvVars` | Disables passing host environment variable to plugin processes | +| `tableSharedCrosshair` | Enables shared crosshair in table panel | +| `kubernetesFeatureToggles` | Use the kubernetes API for feature toggle management in the frontend | +| `newFolderPicker` | Enables the nested folder picker without having nested folders enabled | +| `scopeApi` | In-development feature flag for the scope api using the app platform. | +| `sqlExpressions` | Enables SQL Expressions, which can execute SQL queries against data source results. | +| `nodeGraphDotLayout` | Changed the layout algorithm for the node graph | +| `kubernetesAggregator` | Enable grafana's embedded kube-aggregator | +| `expressionParser` | Enable new expression parser | +| `disableNumericMetricsSortingInExpressions` | In server-side expressions, disable the sorting of numeric-kind metrics by their metric name or labels. | +| `queryLibrary` | Enables Query Library feature in Explore | +| `logsExploreTableDefaultVisualization` | Sets the logs table as default visualisation in logs explore | +| `alertingListViewV2` | Enables the new alert list view design | +| `dashboardRestore` | Enables deleted dashboard restore feature | +| `alertingCentralAlertHistory` | Enables the new central alert history. | +| `failWrongDSUID` | Throws an error if a datasource has an invalid UIDs | +| `dataplaneAggregator` | Enable grafana dataplane aggregator | +| `lokiSendDashboardPanelNames` | Send dashboard and panel names to Loki when querying | +| `alertingPrometheusRulesPrimary` | Uses Prometheus rules as the primary source of truth for ruler-enabled data sources | +| `exploreLogsShardSplitting` | Used in Logs Drilldown to split queries into multiple queries based on the number of shards | +| `exploreLogsAggregatedMetrics` | Used in Logs Drilldown to query by aggregated metrics | +| `exploreLogsLimitedTimeRange` | Used in Logs Drilldown to limit the time range | +| `homeSetupGuide` | Used in Home for users who want to return to the onboarding flow or quickly find popular config pages | +| `appSidecar` | Enable the app sidecar feature that allows rendering 2 apps at the same time | +| `rolePickerDrawer` | Enables the new role picker drawer design | +| `pluginsSriChecks` | Enables SRI checks for plugin assets | +| `unifiedStorageBigObjectsSupport` | Enables to save big objects in blob storage | +| `timeRangeProvider` | Enables time pickers sync | +| `prometheusUsesCombobox` | Use new combobox component for Prometheus query editor | +| `playlistsReconciler` | Enables experimental reconciler for playlists | +| `exploreMetricsRelatedLogs` | Display Related Logs in Grafana Metrics Drilldown | +| `prometheusSpecialCharsInLabelValues` | Adds support for quotes and special characters in label values for Prometheus queries | +| `enableExtensionsAdminPage` | Enables the extension admin page regardless of development mode | +| `enableSCIM` | Enables SCIM support for user and group management | +| `crashDetection` | Enables browser crash detection reporting to Faro. | +| `jaegerBackendMigration` | Enables querying the Jaeger data source without the proxy | +| `useV2DashboardsAPI` | Use the v2 kubernetes API in the frontend for dashboards | +| `unifiedHistory` | Displays the navigation history so the user can navigate back to previous pages | +| `investigationsBackend` | Enable the investigations backend API | +| `k8SFolderCounts` | Enable folder's api server counts | +| `k8SFolderMove` | Enable folder's api server move | +| `teamHttpHeadersMimir` | Enables LBAC for datasources for Mimir to apply LBAC filtering of metrics to the client requests for users in teams | +| `templateVariablesUsesCombobox` | Use new combobox component for template variables | +| `grafanaAdvisor` | Enables Advisor app | +| `elasticsearchImprovedParsing` | Enables less memory intensive Elasticsearch result parsing | +| `datasourceConnectionsTab` | Shows defined connections for a data source in the plugins detail page | +| `newLogsPanel` | Enables the new logs panel in Explore | +| `pluginsCDNSyncLoader` | Load plugins from CDN synchronously | +| `assetSriChecks` | Enables SRI checks for Grafana JavaScript assets | +| `extraLanguages` | Enables additional languages | ## Development feature toggles -The following toggles require explicitly setting Grafana's [app mode]({{< relref "../_index.md#app_mode" >}}) to 'development' before you can enable this feature toggle. These features tend to be experimental. +The following toggles require explicitly setting Grafana's [app mode](../#app_mode) to 'development' before you can enable this feature toggle. These features tend to be experimental. | Feature toggle name | Description | | -------------------------------------- | ----------------------------------------------------------------------------- | diff --git a/docs/sources/setup-grafana/configure-grafana/proxy/index.md b/docs/sources/setup-grafana/configure-grafana/proxy/index.md index e38f5e5aae0..7f17909ad5d 100644 --- a/docs/sources/setup-grafana/configure-grafana/proxy/index.md +++ b/docs/sources/setup-grafana/configure-grafana/proxy/index.md @@ -44,6 +44,6 @@ To complete this task, you must first deploy a socks proxy server that supports 1. Set up a data source and configure it to send data source connections through the proxy. - To configure your data sources to send connections through the proxy, `enableSecureSocksProxy=true` must be specified in the data source json. You can do this in the [API]({{< relref "../../../developers/http_api/data_source" >}}) or use [file based provisioning]({{< relref "../../../administration/provisioning#data-sources" >}}). + To configure your data sources to send connections through the proxy, `enableSecureSocksProxy=true` must be specified in the data source json. You can do this in the [API](../../../developers/http_api/data_source/) or use [file based provisioning](../../../administration/provisioning/#data-sources). Additionally, you can set the socks5 username and password by adding `secureSocksProxyUsername` in the data source json and `secureSocksProxyPassword` in the secure data source json. diff --git a/docs/sources/setup-grafana/configure-grafana/settings-updates-at-runtime/index.md b/docs/sources/setup-grafana/configure-grafana/settings-updates-at-runtime/index.md index 046c0528c43..f755b6d0246 100644 --- a/docs/sources/setup-grafana/configure-grafana/settings-updates-at-runtime/index.md +++ b/docs/sources/setup-grafana/configure-grafana/settings-updates-at-runtime/index.md @@ -17,13 +17,13 @@ weight: 500 # Settings updates at runtime {{% admonition type="note" %}} -This functionality is deprecated and will be removed in a future release. For configuring SAML authentication, please use the new [SSO settings API]({{< relref "../../../developers/http_api/sso-settings" >}}). +This functionality is deprecated and will be removed in a future release. For configuring SAML authentication, please use the new [SSO settings API](../../../developers/http_api/sso-settings/). {{% /admonition %}} By updating settings at runtime, you can update Grafana settings without needing to restart the Grafana server. Updates that happen at runtime are stored in the database and override -[settings from other sources]({{< relref "../../configure-grafana" >}}) +[settings from other sources](../) (arguments, environment variables, settings file, etc). Therefore, every time a specific setting key is removed at runtime, the value used for that key is the inherited one from the other sources in the reverse order of precedence (`arguments > environment variables > settings file`). When no value is provided through any of these options, then the value used will be the application default @@ -32,7 +32,7 @@ Currently, **it only supports updates on the `auth.saml` section.** ## Update settings via the API -You can update settings through the [Admin API]({{< relref "../../../developers/http_api/admin#update-settings" >}}). +You can update settings through the [Admin API](../../../developers/http_api/admin/#update-settings). When you submit a settings update via API, Grafana verifies if the given settings updates are allowed and valid. If they are, then Grafana stores the settings in the database and reloads Grafana services with no need to restart the instance. @@ -99,5 +99,5 @@ HTTP API, then the other instances are synchronized through the database and the ## Control access with role-based access control -If you have [role-based access control]({{< relref "../../../administration/roles-and-permissions/access-control" >}}) enabled, you can control who can read or update settings. -Refer to the [Admin API]({{< relref "../../../developers/http_api/admin#update-settings" >}}) for more information. +If you have [role-based access control](../../../administration/roles-and-permissions/access-control/) enabled, you can control who can read or update settings. +Refer to the [Admin API](../../../developers/http_api/admin/#update-settings) for more information. diff --git a/docs/sources/setup-grafana/configure-security/_index.md b/docs/sources/setup-grafana/configure-security/_index.md index c638203fc8d..af6d0d9307b 100644 --- a/docs/sources/setup-grafana/configure-security/_index.md +++ b/docs/sources/setup-grafana/configure-security/_index.md @@ -19,11 +19,11 @@ To prevent this type of exploitation from happening, we recommend that you apply ## Limit IP addresses/hostnames for data source URL -You can configure Grafana to only allow certain IP addresses or hostnames to be used as data source URLs and proxied through the Grafana data source proxy. Refer to [data_source_proxy_whitelist]({{< relref "../configure-grafana#data_source_proxy_whitelist" >}}) for usage instructions. +You can configure Grafana to only allow certain IP addresses or hostnames to be used as data source URLs and proxied through the Grafana data source proxy. Refer to [data_source_proxy_whitelist](../configure-grafana/#data_source_proxy_whitelist) for usage instructions. ## Request security -The request security configuration option allows users to limit requests from the Grafana server. It targets requests that are generated by users. For more information, refer to [Request security]({{< relref "./configure-request-security" >}}). +The request security configuration option allows users to limit requests from the Grafana server. It targets requests that are generated by users. For more information, refer to [Request security](configure-request-security/). {{% admonition type="note" %}} Request security is available in Grafana Enterprise v7.4 and later versions. @@ -53,7 +53,7 @@ For example, in a Grafana instance with one data source, one dashboard, and one To address this vulnerability, you can restrict data source query access in the following ways: -- Create multiple data sources with some restrictions added in data source configuration that restrict access (like database name or credentials). Then use the [Data Source Permissions]({{< relref "../../administration/data-source-management#data-source-permissions" >}}) Enterprise feature to restrict user access to the data source in Grafana. +- Create multiple data sources with some restrictions added in data source configuration that restrict access (like database name or credentials). Then use the [Data Source Permissions](../../administration/data-source-management/#data-source-permissions) Enterprise feature to restrict user access to the data source in Grafana. - Create a separate Grafana organization, and in that organization, create a separate data source. Make sure the data source has some option/user/credentials setting that limits access to a subset of the data. Not all data sources have an option to limit access. ## Implications of enabling anonymous access to dashboards diff --git a/docs/sources/setup-grafana/configure-security/audit-grafana.md b/docs/sources/setup-grafana/configure-security/audit-grafana.md index 9bafd16630e..7353235d90a 100644 --- a/docs/sources/setup-grafana/configure-security/audit-grafana.md +++ b/docs/sources/setup-grafana/configure-security/audit-grafana.md @@ -26,7 +26,7 @@ To enable sending Grafana Cloud audit logs to your Grafana Cloud Logs instance, Only API requests or UI actions that trigger an API request generate an audit log. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). {{% /admonition %}} ## Audit logs @@ -145,7 +145,7 @@ to the action when the user requests a report's preview to be sent through email \* Where `AUTH-MODULE` is the name of the authentication module: `grafana`, `saml`, `ldap`, etc. \ -\*\* Includes manual log out, token expired/revoked, and [SAML Single Logout]({{< relref "./configure-authentication/saml#single-logout" >}}). +\*\* Includes manual log out, token expired/revoked, and [SAML Single Logout](../configure-authentication/saml/#single-logout). #### Service accounts @@ -359,7 +359,7 @@ The auditing feature is disabled by default. {{% /admonition %}} Audit logs can be saved into files, sent to a Loki instance or sent to the Grafana default logger. By default, only the file exporter is enabled. -You can choose which exporter to use in the [configuration file]({{< relref "../configure-grafana" >}}). +You can choose which exporter to use in the [configuration file](../../configure-grafana/). Options are `file`, `loki`, and `logger`. Use spaces to separate multiple modes, such as `file loki`. @@ -437,4 +437,4 @@ url = user:password@localhost:3000 ### Console exporter -Audit logs are sent to the Grafana default logger. The audit logs use the `auditing.console` logger and are logged on `debug`-level, learn how to enable debug logging in the [log configuration]({{< relref "../configure-grafana#log" >}}) section of the documentation. Accessing the audit logs in this way is not recommended for production use. +Audit logs are sent to the Grafana default logger. The audit logs use the `auditing.console` logger and are logged on `debug`-level, learn how to enable debug logging in the [log configuration](../../configure-grafana/#log) section of the documentation. Accessing the audit logs in this way is not recommended for production use. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md index 1c6b0ce9256..41132550368 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/_index.md @@ -17,23 +17,24 @@ weight: 200 Grafana provides many ways to authenticate users. Some authentication integrations also enable syncing user permissions and org memberships. -The following table shows all supported authentication methods and the features available for them. [Team sync]({{< relref "../configure-team-sync" >}}) and [active sync]({{< relref "./enhanced-ldap#active-ldap-synchronization" >}}) are only available in Grafana Enterprise. +The following table shows all supported authentication methods and the features available for them. [Team sync](../configure-team-sync/) and [active sync](enhanced-ldap/#active-ldap-synchronization) are only available in Grafana Enterprise. -| Authentication method | Multi Org Mapping | Enforce Sync | Role Mapping | Grafana Admin Mapping | Team Sync | Allowed groups | Active Sync | Skip OrgRole mapping | Auto Login | Single Logout | -| :---------------------------------------------------- | :---------------- | :----------- | :----------- | :-------------------- | :-------- | :------------- | :---------- | :------------------- | :--------- | :------------ | -| [Anonymous access]({{< relref "./anonymous-auth" >}}) | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | -| [Auth Proxy]({{< relref "./auth-proxy" >}}) | no | yes | yes | no | yes | no | N/A | no | N/A | N/A | -| [Azure AD OAuth]({{< relref "./azuread" >}}) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | -| [Basic auth]({{< relref "./grafana" >}}) | yes | N/A | yes | yes | N/A | N/A | N/A | N/A | N/A | N/A | -| [Generic OAuth]({{< relref "./generic-oauth" >}}) | yes | yes | yes | yes | yes | no | N/A | yes | yes | yes | -| [GitHub OAuth]({{< relref "./github" >}}) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | -| [GitLab OAuth]({{< relref "./gitlab" >}}) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | -| [Google OAuth]({{< relref "./google" >}}) | yes | no | no | no | yes | no | N/A | no | yes | yes | -| [Grafana.com OAuth]({{< relref "./grafana-cloud" >}}) | no | no | yes | no | N/A | N/A | N/A | yes | yes | yes | -| [Okta OAuth]({{< relref "./okta" >}}) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | -| [SAML]({{< relref "./saml" >}}) (Enterprise only) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | -| [LDAP]({{< relref "./ldap" >}}) | yes | yes | yes | yes | yes | yes | yes | no | N/A | N/A | -| [JWT Proxy]({{< relref "./jwt" >}}) | no | yes | yes | yes | no | no | N/A | no | N/A | N/A | +| Authentication method | Multi Org Mapping | Enforce Sync | Role Mapping | Grafana Admin Mapping | Team Sync | Allowed groups | Active Sync | Skip OrgRole mapping | Auto Login | Single Logout | +| :---------------------------------- | :---------------- | :----------- | :----------- | :-------------------- | :-------- | :------------- | :---------- | :------------------- | :--------- | :------------ | +| [Anonymous access](anonymous-auth/) | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | N/A | +| [Auth Proxy](auth-proxy/) | no | yes | yes | no | yes | no | N/A | no | N/A | N/A | +| [Azure AD OAuth](azuread/) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | +| [Basic auth](grafana/) | yes | N/A | yes | yes | N/A | N/A | N/A | N/A | N/A | N/A | +| [Passwordless auth](passwordless/) | yes | N/A | yes | yes | N/A | N/A | N/A | N/A | N/A | N/A | +| [Generic OAuth](generic-oauth/) | yes | yes | yes | yes | yes | no | N/A | yes | yes | yes | +| [GitHub OAuth](github/) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | +| [GitLab OAuth](gitlab/) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | +| [Google OAuth](google/) | yes | no | no | no | yes | no | N/A | no | yes | yes | +| [Grafana.com OAuth](grafana-cloud/) | no | no | yes | no | N/A | N/A | N/A | yes | yes | yes | +| [Okta OAuth](okta/) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | +| [SAML](saml/) (Enterprise only) | yes | yes | yes | yes | yes | yes | N/A | yes | yes | yes | +| [LDAP](ldap/) | yes | yes | yes | yes | yes | yes | yes | no | N/A | N/A | +| [JWT Proxy](jwt/) | no | yes | yes | yes | no | no | N/A | no | N/A | N/A | Fields explanation: @@ -60,7 +61,7 @@ Fields explanation: ## Configuring multiple identity providers Grafana allows you to configure more than one authentication provider, however it is not possible to configure the same type of authentication provider twice. -For example, you can have [SAML]({{< relref "./saml" >}}) (Enterprise only) and [Generic OAuth]({{< relref "./generic-oauth" >}}) configured, but you can not have two different [Generic OAuth]({{< relref "./generic-oauth" >}}) configurations. +For example, you can have [SAML](saml/) (Enterprise only) and [Generic OAuth](generic-oauth/) configured, but you can not have two different [Generic OAuth](generic-oauth/) configurations. > Note: Grafana does not support multiple identity providers resolving the same user. Ensure there are no user account overlaps between the different providers @@ -68,7 +69,7 @@ In scenarios where you have multiple identity providers of the same type, there - Use different Grafana instances each configured with a given identity provider. - Check if the identity provider supports account federation. In such cases, you can configure it once and let your identity provider federate the accounts from different providers. -- If SAML is supported by the identity provider, you can configure one [Generic OAuth]({{< relref "./generic-oauth" >}}) and one [SAML]({{< relref "./saml" >}}) (Enterprise only). +- If SAML is supported by the identity provider, you can configure one [Generic OAuth](generic-oauth/) and one [SAML](saml/) (Enterprise only). ## Using the same email address to login with different identity providers @@ -141,7 +142,7 @@ oauth_allow_insecure_email_lookup = true You can also enable email lookup using the API: {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud]({{< relref "../../../introduction/grafana-cloud" >}}) since Grafana v10.4. +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud](../../../introduction/grafana-cloud/) since Grafana v10.4. {{% /admonition %}} ``` @@ -207,7 +208,7 @@ a Grafana admin user, you can also do the same for any user from the Server Admi ### Protected roles {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud]({{< relref "../../../introduction/grafana-cloud" >}}). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud](../../../introduction/grafana-cloud/). {{% /admonition %}} By default, after you configure an authorization provider, Grafana will adopt existing users into the new authentication scheme. For example, if you have created a user with basic authentication having the login `jsmith@example.com`, then set up SAML authentication where `jsmith@example.com` is an account, the user's authentication type will be changed to SAML if they perform a SAML sign-in. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/auth-proxy/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/auth-proxy/index.md index 5ed036bb6ed..357cd103714 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/auth-proxy/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/auth-proxy/index.md @@ -251,7 +251,7 @@ headers = "Groups:X-WEBAUTH-GROUPS" You use the `X-WEBAUTH-GROUPS` header to send the team information for each user. Specifically, the set of Grafana's group IDs that the user belongs to. -First, we need to set up the mapping between your authentication provider and Grafana. Follow [these instructions]({{< relref "../../configure-team-sync#synchronize-a-grafana-team-with-an-external-group" >}}) to add groups to a team within Grafana. +First, we need to set up the mapping between your authentication provider and Grafana. Follow [these instructions](../../configure-team-sync/#synchronize-a-grafana-team-with-an-external-group) to add groups to a team within Grafana. Once that's done. You can verify your mappings by querying the API. @@ -313,7 +313,7 @@ With this, the user `leonard` will be automatically placed into the Loki team as An empty `X-WEBAUTH-GROUPS` or the absence of a groups header will remove the user from all teams. {{% /admonition %}} -[Learn more about Team Sync]({{< relref "../../configure-team-sync" >}}) +[Learn more about Team Sync](../../configure-team-sync/) ## Login token and session cookie diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md index 8ac7d9bd79f..fd1b2773749 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/azuread/index.md @@ -22,7 +22,7 @@ weight: 800 The Azure AD authentication allows you to use a Microsoft Entra ID (formerly known as Azure Active Directory) tenant as an identity provider for Grafana. You can use Entra ID application roles to assign users and groups to Grafana roles from the Azure Portal. {{% admonition type="note" %}} -If Users use the same email address in Microsoft Entra ID that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) for more information. +If Users use the same email address in Microsoft Entra ID that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) for more information. {{% /admonition %}} ## Create the Microsoft Entra ID application @@ -253,11 +253,11 @@ Refer to [Terraform Registry](https://registry.terraform.io/providers/grafana/gr ## Configure Azure AD authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Enable Azure AD OAuth in Grafana -Add the following to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}): +Add the following to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location): ``` [auth.azuread] @@ -293,7 +293,7 @@ GF_AUTH_AZUREAD_FEDERATED_CREDENTIAL_AUDIENCE ``` {{% admonition type="note" %}} -Verify that the Grafana [root_url]({{< relref "../../../configure-grafana#root_url" >}}) is set in your Azure Application Redirect URLs. +Verify that the Grafana [root_url](../../../configure-grafana/#root_url) is set in your Azure Application Redirect URLs. {{% /admonition %}} ### Configure refresh token @@ -417,7 +417,7 @@ Entra ID does not emit the groups claim in the token and emits a group overage c If Grafana receives a token with a group overage claim instead of a groups claim, Grafana attempts to retrieve the user's group membership by calling the included endpoint. -To ensure this functionality works correctly, you must enable [`force_use_graph_api`]({{< relref "./#force-fetching-groups-from-microsoft-graph-api" >}}) in your configuration. +To ensure this functionality works correctly, you must enable [`force_use_graph_api`](./#force-fetching-groups-from-microsoft-graph-api) in your configuration. {{% admonition type="note" %}} The 'App registration' must include the `GroupMember.Read.All` API permission for group overage claim calls to succeed. @@ -451,7 +451,7 @@ force_use_graph_api = true By default, Azure AD authentication will map users to organization roles based on the most privileged application role assigned to the user in Entra ID. If no application role is found, the user is assigned the role specified by -[the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +[the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned and the `org_mapping` expression evaluates to an empty mapping. You can use the `org_mapping` configuration option to assign the user to multiple organizations and specify their role based on their Entra ID group membership. For more information, refer to [Org roles mapping example](#org-roles-mapping-example). If the org role mapping (`org_mapping`) is specified and Entra ID returns a valid role, then the user will get the highest of the two roles. @@ -476,7 +476,7 @@ org_mapping = ["032cb8e0-240f-4347-9120-6f33013e817a:org_foo:Viewer", "bce1c492- ## Skip organization role sync If Azure AD authentication is not intended to sync user roles and organization membership and prevent the sync of org roles from Entra ID, set `skip_org_role_sync` to `true`. This is useful if you want to manage the organization roles for your users from within Grafana or that your organization roles are synced from another provider. -See [Configure Grafana]({{< relref "../../../configure-grafana#authazuread" >}}) for more details. +See [Configure Grafana](../../../configure-grafana/#authazuread) for more details. ```ini [auth.azuread] @@ -487,7 +487,7 @@ skip_org_role_sync = true ## Configuration options -The following table outlines the various Azure AD/Entra ID configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The following table outlines the various Azure AD/Entra ID configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). | Setting | Required | Supported on Cloud | Description | Default | | ---------------------------- | -------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------- | @@ -502,12 +502,12 @@ The following table outlines the various Azure AD/Entra ID configuration options | `scopes` | No | Yes | List of comma- or space-separated OAuth2 scopes. | `openid email profile` | | `allow_sign_up` | No | Yes | Controls Grafana user creation through the Azure AD/Entra ID login. Only existing Grafana users can log in with Azure AD/Entra ID if set to `false`. | `true` | | `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | -| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Map roles]({{< relref "#map-roles" >}}). | `false` | +| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Map roles](#map-roles). | `false` | | `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no value is returned, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | | `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `allow_assign_grafana_admin` | No | No | Set to `true` to automatically sync the Grafana server administrator role. When enabled, if the Azure AD/Entra ID user's App role is `GrafanaAdmin`, Grafana grants the user server administrator privileges and the organization administrator role. If disabled, the user will only receive the organization administrator role. For more details on user role mapping, refer to [Map roles]({{< relref "#map-roles" >}}). | `false` | +| `allow_assign_grafana_admin` | No | No | Set to `true` to automatically sync the Grafana server administrator role. When enabled, if the Azure AD/Entra ID user's App role is `GrafanaAdmin`, Grafana grants the user server administrator privileges and the organization administrator role. If disabled, the user will only receive the organization administrator role. For more details on user role mapping, refer to [Map roles](#map-roles). | `false` | | `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | -| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure Azure AD/Entra ID to include the `groups` claim following [Configure group membership claims on the Azure Portal]({{< relref "#configure-group-membership-claims-on-the-azure-portal" >}}). | | +| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure Azure AD/Entra ID to include the `groups` claim following [Configure group membership claims on the Azure Portal](#configure-group-membership-claims-on-the-azure-portal). | | | `allowed_organizations` | No | Yes | List of comma- or space-separated Azure tenant identifiers. The user should be a member of at least one tenant to log in. | | | `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | | `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/enhanced-ldap/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/enhanced-ldap/index.md index a8992e015d6..ee6f7c6335f 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/enhanced-ldap/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/enhanced-ldap/index.md @@ -21,12 +21,12 @@ weight: 400 # Configure enhanced LDAP integration -The enhanced LDAP integration adds additional functionality on top of the [LDAP integration]({{< relref "../ldap" >}}) available in the open source edition of Grafana. +The enhanced LDAP integration adds additional functionality on top of the [LDAP integration](../ldap/) available in the open source edition of Grafana. -> **Note:** Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). +> **Note:** Available in [Grafana Enterprise](../../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). > If you are a Grafana Cloud customer, please [open a support ticket in the Cloud Portal](/profile/org#support) to request this feature. -> To control user access with role-based permissions, refer to [role-based access control]({{< relref "../../../../administration/roles-and-permissions/access-control" >}}). +> To control user access with role-based permissions, refer to [role-based access control](../../../../administration/roles-and-permissions/access-control/). ## LDAP group synchronization @@ -70,7 +70,7 @@ sync_cron = "0 1 * * *" # This is default value (At 1 am every day) active_sync_enabled = true # enabled by default ``` -Single bind configuration (as in the [Single bind example]({{< relref "../ldap#single-bind-example" >}})) is not supported with active LDAP synchronization because Grafana needs user information to perform LDAP searches. +Single bind configuration (as in the [Single bind example](../ldap/#single-bind-example)) is not supported with active LDAP synchronization because Grafana needs user information to perform LDAP searches. For the synchronization to work, the `servers.search_filter` and `servers.attributes.username` in the ldap.toml config file must match. By default, the `servers.attributes.username` is `cn`, so if you use another attribute as the search filter, you must also update the username attribute. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md index 1c9571f712d..99e9abb057a 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/generic-oauth/index.md @@ -23,17 +23,17 @@ weight: 700 Grafana provides OAuth2 integrations for the following auth providers: -- [Azure AD OAuth]({{< relref "../azuread" >}}) -- [GitHub OAuth]({{< relref "../github" >}}) -- [GitLab OAuth]({{< relref "../gitlab" >}}) -- [Google OAuth]({{< relref "../google" >}}) -- [Grafana Com OAuth]({{< relref "../grafana-cloud" >}}) -- [Keycloak OAuth]({{< relref "../keycloak" >}}) -- [Okta OAuth]({{< relref "../okta" >}}) +- [Azure AD OAuth](../azuread/) +- [GitHub OAuth](../github/) +- [GitLab OAuth](../gitlab/) +- [Google OAuth](../google/) +- [Grafana Com OAuth](../grafana-cloud/) +- [Keycloak OAuth](../keycloak/) +- [Okta OAuth](../okta/) If your OAuth2 provider is not listed, you can use Generic OAuth authentication. -This topic describes how to configure Generic OAuth authentication using different methods and includes [examples of setting up Generic OAuth]({{< relref "#examples-of-setting-up-generic-oauth2" >}}) with specific OAuth2 providers. +This topic describes how to configure Generic OAuth authentication using different methods and includes [examples of setting up Generic OAuth](#examples-of-setting-up-generic-oauth2) with specific OAuth2 providers. ## Before you begin @@ -44,7 +44,7 @@ To follow this guide: - If you are using refresh tokens, ensure you know how to set them up with your OAuth2 provider. Consult the documentation of your OAuth2 provider for more information. {{% admonition type="note" %}} -If Users use the same email address in Azure AD that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in Azure AD that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} ## Configure generic OAuth authentication client using the Grafana UI @@ -63,7 +63,7 @@ If you need to reset changes you made in the UI back to the default values, clic If you run Grafana in high availability mode, configuration changes may not get applied to all Grafana instances immediately. You may need to wait a few minutes for the configuration to propagate to all Grafana instances. {{% /admonition %}} -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. ## Configure generic OAuth authentication client using the Terraform provider @@ -94,7 +94,7 @@ Refer to [Terraform Registry](https://registry.terraform.io/providers/grafana/gr ## Configure generic OAuth authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Steps @@ -116,9 +116,9 @@ To integrate your OAuth2 provider with Grafana using our Generic OAuth authentic | `api_url` | The user information endpoint of your OAuth2 provider. Information returned by this endpoint must be compatible with [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo). | | `enabled` | Enables Generic OAuth authentication. Set this value to `true`. | - Review the list of other Generic OAuth [configuration options]({{< relref "#configuration-options" >}}) and complete them, as necessary. + Review the list of other Generic OAuth [configuration options](#configuration-options) and complete them, as necessary. -1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}): +1. Optional: [Configure a refresh token](#configure-a-refresh-token): a. Extend the `scopes` field of `[auth.generic_oauth]` section in Grafana configuration file with refresh token scope used by your OAuth2 provider. @@ -126,8 +126,8 @@ To integrate your OAuth2 provider with Grafana using our Generic OAuth authentic c. Enable the refresh token on the provider if required. -1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). -1. Optional: [Configure group synchronization]({{< relref "#configure-group-synchronization" >}}). +1. [Configure role mapping](#configure-role-mapping). +1. Optional: [Configure group synchronization](#configure-group-synchronization). 1. Restart Grafana. You should now see a Generic OAuth login button on the login page and be able to log in or sign up with your OAuth2 provider. @@ -198,9 +198,9 @@ Unless `skip_org_role_sync` option is enabled, the user's role will be set to th The user's role is retrieved using a [JMESPath](http://jmespath.org/examples.html) expression from the `role_attribute_path` configuration option. To map the server administrator role, use the `allow_assign_grafana_admin` configuration option. -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. -If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned after evaluating the `role_attribute_path` and the `org_mapping` expressions. You can use the `org_attribute_path` and `org_mapping` configuration options to assign the user to organizations and specify their role. For more information, refer to [Org roles mapping example](#org-roles-mapping-example). If both org role mapping (`org_mapping`) and the regular role mapping (`role_attribute_path`) are specified, then the user will get the highest of the two mapped roles. @@ -320,7 +320,7 @@ Grafana supports synchronization of OAuth2 groups with Grafana teams and roles. Teams and roles get synchronized when the user logs in. Generic OAuth groups can be referenced by group ID, such as `8bab1c86-8fba-33e5-2089-1d1c80ec267d` or `myteam`. -For information on configuring OAuth2 groups with Grafana using the `groups_attribute_path` configuration option, refer to [configuration options]({{< relref "#configuration-options" >}}). +For information on configuring OAuth2 groups with Grafana using the `groups_attribute_path` configuration option, refer to [configuration options](#configuration-options). To learn more about group synchronization, refer to [Configure team sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-team-sync) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync). @@ -347,52 +347,52 @@ Payload: ## Configuration options -The following table outlines the various Generic OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The following table outlines the various Generic OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). {{< admonition type="note" >}} If the configuration option requires a JMESPath expression that includes a colon, enclose the entire expression in quotes to prevent parsing errors. For example `role_attribute_path: "role:view"` {{< /admonition >}} -| Setting | Required | Supported on Cloud | Description | Default | -| ---------------------------- | -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | -| `enabled` | No | Yes | Enables Generic OAuth authentication. | `false` | -| `name` | No | Yes | Name that refers to the Generic OAuth authentication from the Grafana user interface. | `OAuth` | -| `icon` | No | Yes | Icon used for the Generic OAuth authentication in the Grafana user interface. | `signin` | -| `client_id` | Yes | Yes | Client ID provided by your OAuth2 app. | | -| `client_secret` | Yes | Yes | Client secret provided by your OAuth2 app. | | -| `auth_url` | Yes | Yes | Authorization endpoint of your OAuth2 provider. | | -| `token_url` | Yes | Yes | Endpoint used to obtain the OAuth2 access token. | | -| `api_url` | Yes | Yes | Endpoint used to obtain user information compatible with [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo). | | -| `auth_style` | No | Yes | Name of the [OAuth2 AuthStyle](https://pkg.go.dev/golang.org/x/oauth2#AuthStyle) to be used when ID token is requested from OAuth2 provider. It determines how `client_id` and `client_secret` are sent to Oauth2 provider. Available values are `AutoDetect`, `InParams` and `InHeader`. | `AutoDetect` | -| `scopes` | No | Yes | List of comma- or space-separated OAuth2 scopes. | `user:email` | -| `empty_scopes` | No | Yes | Set to `true` to use an empty scope during authentication. | `false` | -| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Generic OAuth login. Only existing Grafana users can log in with Generic OAuth if set to `false`. | `true` | -| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | -| `id_token_attribute_name` | No | Yes | The name of the key used to extract the ID token from the returned OAuth2 token. | `id_token` | -| `login_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user login lookup from the user ID token. For more information on how user login is retrieved, refer to [Configure login]({{< relref "#configure-login" >}}). | | -| `name_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user name lookup from the user ID token. This name will be used as the user's display name. For more information on how user display name is retrieved, refer to [Configure display name]({{< relref "#configure-display-name" >}}). | | -| `email_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user email lookup from the user information. For more information on how user email is retrieved, refer to [Configure email address]({{< relref "#configure-email-address" >}}). | | -| `email_attribute_name` | No | Yes | Name of the key to use for user email lookup within the `attributes` map of OAuth2 ID token. For more information on how user email is retrieved, refer to [Configure email address]({{< relref "#configure-email-address" >}}). | `email:primary` | -| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | | -| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | -| `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no value is returned, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `groups_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user group lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no groups are found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a string array of groups. | | -| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure `groups_attribute_path`. | | -| `allowed_organizations` | No | Yes | List of comma- or space-separated organizations. The user should be a member of at least one organization to log in. | | -| `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | -| `team_ids` | No | Yes | String list of team IDs. If set, the user must be a member of one of the given teams to log in. If you configure `team_ids`, you must also configure `teams_url` and `team_ids_attribute_path`. | | -| `team_ids_attribute_path` | No | Yes | The [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana team ID lookup within the results returned by the `teams_url` endpoint. | | -| `teams_url` | No | Yes | The URL used to query for team IDs. If not set, the default value is `/teams`. If you configure `teams_url`, you must also configure `team_ids_attribute_path`. | | -| `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | -| `tls_client_cert` | No | No | The path to the certificate. | | -| `tls_client_key` | No | No | The path to the key. | | -| `tls_client_ca` | No | No | The path to the trusted certificate authority list. | | -| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `false` | -| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. | `false` | -| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | +| Setting | Required | Supported on Cloud | Description | Default | +| ---------------------------- | -------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------- | +| `enabled` | No | Yes | Enables Generic OAuth authentication. | `false` | +| `name` | No | Yes | Name that refers to the Generic OAuth authentication from the Grafana user interface. | `OAuth` | +| `icon` | No | Yes | Icon used for the Generic OAuth authentication in the Grafana user interface. | `signin` | +| `client_id` | Yes | Yes | Client ID provided by your OAuth2 app. | | +| `client_secret` | Yes | Yes | Client secret provided by your OAuth2 app. | | +| `auth_url` | Yes | Yes | Authorization endpoint of your OAuth2 provider. | | +| `token_url` | Yes | Yes | Endpoint used to obtain the OAuth2 access token. | | +| `api_url` | Yes | Yes | Endpoint used to obtain user information compatible with [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo). | | +| `auth_style` | No | Yes | Name of the [OAuth2 AuthStyle](https://pkg.go.dev/golang.org/x/oauth2#AuthStyle) to be used when ID token is requested from OAuth2 provider. It determines how `client_id` and `client_secret` are sent to Oauth2 provider. Available values are `AutoDetect`, `InParams` and `InHeader`. | `AutoDetect` | +| `scopes` | No | Yes | List of comma- or space-separated OAuth2 scopes. | `user:email` | +| `empty_scopes` | No | Yes | Set to `true` to use an empty scope during authentication. | `false` | +| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Generic OAuth login. Only existing Grafana users can log in with Generic OAuth if set to `false`. | `true` | +| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | +| `id_token_attribute_name` | No | Yes | The name of the key used to extract the ID token from the returned OAuth2 token. | `id_token` | +| `login_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user login lookup from the user ID token. For more information on how user login is retrieved, refer to [Configure login](#configure-login). | | +| `name_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user name lookup from the user ID token. This name will be used as the user's display name. For more information on how user display name is retrieved, refer to [Configure display name](#configure-display-name). | | +| `email_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user email lookup from the user information. For more information on how user email is retrieved, refer to [Configure email address](#configure-email-address). | | +| `email_attribute_name` | No | Yes | Name of the key to use for user email lookup within the `attributes` map of OAuth2 ID token. For more information on how user email is retrieved, refer to [Configure email address](#configure-email-address). | `email:primary` | +| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | | +| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | +| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | +| `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no value is returned, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | +| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | +| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | +| `groups_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for user group lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no groups are found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a string array of groups. | | +| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure `groups_attribute_path`. | | +| `allowed_organizations` | No | Yes | List of comma- or space-separated organizations. The user should be a member of at least one organization to log in. | | +| `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | +| `team_ids` | No | Yes | String list of team IDs. If set, the user must be a member of one of the given teams to log in. If you configure `team_ids`, you must also configure `teams_url` and `team_ids_attribute_path`. | | +| `team_ids_attribute_path` | No | Yes | The [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana team ID lookup within the results returned by the `teams_url` endpoint. | | +| `teams_url` | No | Yes | The URL used to query for team IDs. If not set, the default value is `/teams`. If you configure `teams_url`, you must also configure `team_ids_attribute_path`. | | +| `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | +| `tls_client_cert` | No | No | The path to the certificate. | | +| `tls_client_key` | No | No | The path to the key. | | +| `tls_client_ca` | No | No | The path to the trusted certificate authority list. | | +| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `false` | +| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. | `false` | +| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | ## Examples of setting up Generic OAuth @@ -435,7 +435,7 @@ To set up Generic OAuth authentication with Descope, follow these steps: ### Set up OAuth2 with Auth0 {{< admonition type="note" >}} -Support for the Auth0 "audience" feature is not currently available in Grafana. For roles and permissions, the available options are described [here]({{< relref "../../../../administration/roles-and-permissions/" >}}). +Support for the Auth0 "audience" feature is not currently available in Grafana. For roles and permissions, the available options are described [here](../../../../administration/roles-and-permissions/). {{< /admonition >}} To set up Generic OAuth authentication with Auth0, follow these steps: @@ -577,4 +577,4 @@ steps: `` corresponds to the `issuer: ` configuration in Dex (e.g. the Dex domain possibly including a path such as e.g. `/dex`). The `offline_access` scope is - needed when using [refresh tokens]({{< relref "#configure-a-refresh-token" >}}). + needed when using [refresh tokens](#configure-a-refresh-token). diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md index 5792c3a4a70..ffde83ab6d1 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/github/index.md @@ -24,7 +24,7 @@ weight: 900 This topic describes how to configure GitHub OAuth authentication. {{% admonition type="note" %}} -If Users use the same email address in GitHub that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in GitHub that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} ## Before you begin @@ -57,7 +57,7 @@ If you need to reset changes you made in the UI back to the default values, clic If you run Grafana in high availability mode, configuration changes may not get applied to all Grafana instances immediately. You may need to wait a few minutes for the configuration to propagate to all Grafana instances. {{% /admonition %}} -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. ## Configure GitHub authentication client using the Terraform provider @@ -87,7 +87,7 @@ Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafa ## Configure GitHub authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Configure GitHub authentication @@ -107,10 +107,10 @@ To configure GitHub authentication with Grafana, follow these steps: | `client_id`, `client_secret` | These values must match the client ID and client secret from your GitHub OAuth app. | | `enabled` | Enables GitHub authentication. Set this value to `true`. | - Review the list of other GitHub [configuration options]({{< relref "#configuration-options" >}}) and complete them, as necessary. + Review the list of other GitHub [configuration options](#configuration-options) and complete them, as necessary. -1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). -1. Optional: [Configure group synchronization]({{< relref "#configure-group-synchronization" >}}). +1. [Configure role mapping](#configure-role-mapping). +1. Optional: [Configure group synchronization](#configure-group-synchronization). 1. Restart Grafana. You should now see a GitHub login button on the login page and be able to log in or sign up with your GitHub accounts. @@ -121,9 +121,9 @@ Unless `skip_org_role_sync` option is enabled, the user's role will be set to th The user's role is retrieved using a [JMESPath](http://jmespath.org/examples.html) expression from the `role_attribute_path` configuration option. To map the server administrator role, use the `allow_assign_grafana_admin` configuration option. -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. -If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned after evaluating the `role_attribute_path` and the `org_mapping` expressions. You can use the `org_mapping` configuration options to assign the user to organizations and specify their role based on their GitHub team membership. For more information, refer to [Org roles mapping example](#org-roles-mapping-example). If both org role mapping (`org_mapping`) and the regular role mapping (`role_attribute_path`) are specified, then the user will get the highest of the two mapped roles. @@ -236,7 +236,7 @@ To learn more about group synchronization, refer to [Configure team sync](https: ## Configuration options -The table below describes all GitHub OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The table below describes all GitHub OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). {{< admonition type="note" >}} If the configuration option requires a JMESPath expression that includes a colon, enclose the entire expression in quotes to prevent parsing errors. For example `role_attribute_path: "role:view"` @@ -259,7 +259,7 @@ If the configuration option requires a JMESPath expression that includes a colon | `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#org-roles-mapping-example). | `false` | | `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | | `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. | `false` | -| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | +| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | | `allowed_organizations` | No | Yes | List of comma- or space-separated organizations. User must be a member of at least one organization to log in. | | | `allowed_domains` | No | Yes | List of comma- or space-separated domains. User must belong to at least one domain to log in. | | | `team_ids` | No | Yes | Integer list of team IDs. If set, user has to be a member of one of the given teams to log in. | | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md index d1503808910..230eeb1873f 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/gitlab/index.md @@ -24,7 +24,7 @@ weight: 1000 This topic describes how to configure GitLab OAuth authentication. {{% admonition type="note" %}} -If Users use the same email address in GitLab that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in GitLab that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} ## Before you begin @@ -57,7 +57,7 @@ If you need to reset changes you made in the UI back to the default values, clic If you run Grafana in high availability mode, configuration changes may not get applied to all Grafana instances immediately. You may need to wait a few minutes for the configuration to propagate to all Grafana instances. {{% /admonition %}} -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. ## Configure GitLab authentication client using the Terraform provider @@ -89,7 +89,7 @@ Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafa ## Configure GitLab authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Steps @@ -112,14 +112,14 @@ To configure GitLab authentication with Grafana, follow these steps: | `client_id`, `client_secret` | These values must match the `Application ID` and `Secret` from your GitLab OAuth application. | | `enabled` | Enables GitLab authentication. Set this value to `true`. | - Review the list of other GitLab [configuration options]({{< relref "#configuration-options" >}}) and complete them, as necessary. + Review the list of other GitLab [configuration options](#configuration-options) and complete them, as necessary. -1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}): +1. Optional: [Configure a refresh token](#configure-a-refresh-token): a. Set `use_refresh_token` to `true` in `[auth.gitlab]` section in Grafana configuration file. -1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). -1. Optional: [Configure group synchronization]({{< relref "#configure-group-synchronization" >}}). +1. [Configure role mapping](#configure-role-mapping). +1. Optional: [Configure group synchronization](#configure-group-synchronization). 1. Restart Grafana. You should now see a GitLab login button on the login page and be able to log in or sign up with your GitLab accounts. @@ -154,11 +154,11 @@ Unless `skip_org_role_sync` option is enabled, the user's role will be set to th The user's role is retrieved using a [JMESPath](http://jmespath.org/examples.html) expression from the `role_attribute_path` configuration option. To map the server administrator role, use the `allow_assign_grafana_admin` configuration option. -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. You can use the `org_mapping` configuration option to assign the user to multiple organizations and specify their role based on their GitLab group membership. For more information, refer to [Org roles mapping example](#org-roles-mapping-example). If the org role mapping (`org_mapping`) is specified and Entra ID returns a valid role, then the user will get the highest of the two roles. -If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned after evaluating the `role_attribute_path` and the `org_mapping` expressions. To ease configuration of a proper JMESPath expression, go to [JMESPath](http://jmespath.org/) to test and evaluate expressions with custom payloads. @@ -259,36 +259,36 @@ To learn more about group synchronization, refer to [Configure team sync](https: ## Configuration options -The table below describes all GitLab OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The table below describes all GitLab OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). {{< admonition type="note" >}} If the configuration option requires a JMESPath expression that includes a colon, enclose the entire expression in quotes to prevent parsing errors. For example `role_attribute_path: "role:view"` {{< /admonition >}} -| Setting | Required | Supported on Cloud | Description | Default | -| ---------------------------- | -------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | -| `enabled` | Yes | Yes | Whether GitLab OAuth authentication is allowed. | `false` | -| `client_id` | Yes | Yes | Client ID provided by your GitLab OAuth app. | | -| `client_secret` | Yes | Yes | Client secret provided by your GitLab OAuth app. | | -| `auth_url` | Yes | Yes | Authorization endpoint of your GitLab OAuth provider. If you use your own instance of GitLab instead of gitlab.com, adjust `auth_url` by replacing the `gitlab.com` hostname with your own. | `https://gitlab.com/oauth/authorize` | -| `token_url` | Yes | Yes | Endpoint used to obtain GitLab OAuth access token. If you use your own instance of GitLab instead of gitlab.com, adjust `token_url` by replacing the `gitlab.com` hostname with your own. | `https://gitlab.com/oauth/token` | -| `api_url` | No | Yes | Grafana uses `/user` endpoint to obtain GitLab user information compatible with [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo). | `https://gitlab.com/api/v4` | -| `name` | No | Yes | Name used to refer to the GitLab authentication in the Grafana user interface. | `GitLab` | -| `icon` | No | Yes | Icon used for GitLab authentication in the Grafana user interface. | `gitlab` | -| `scopes` | No | Yes | List of comma or space-separated GitLab OAuth scopes. | `openid email profile` | -| `allow_sign_up` | No | Yes | Whether to allow new Grafana user creation through GitLab login. If set to `false`, then only existing Grafana users can log in with GitLab OAuth. | `true` | -| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | -| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the GitLab OAuth token. If no role is found, Grafana creates a JSON data with `groups` key that maps to groups obtained from GitLab's `/oauth/userinfo` endpoint, and evaluates the expression using this data. Finally, if a valid role is still not found, the expression is evaluated against the user information retrieved from `api_url/users` endpoint and groups retrieved from `api_url/groups` endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | | -| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana role cannot be extracted using `role_attribute_path`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. | `false` | -| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `allowed_domains` | No | Yes | List of comma or space-separated domains. User must belong to at least one domain to log in. | | -| `allowed_groups` | No | Yes | List of comma or space-separated groups. The user should be a member of at least one group to log in. | | -| `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | -| `tls_client_cert` | No | No | The path to the certificate. | | -| `tls_client_key` | No | No | The path to the key. | | -| `tls_client_ca` | No | No | The path to the trusted certificate authority list. | | -| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | -| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `true` | -| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | +| Setting | Required | Supported on Cloud | Description | Default | +| ---------------------------- | -------- | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------ | +| `enabled` | Yes | Yes | Whether GitLab OAuth authentication is allowed. | `false` | +| `client_id` | Yes | Yes | Client ID provided by your GitLab OAuth app. | | +| `client_secret` | Yes | Yes | Client secret provided by your GitLab OAuth app. | | +| `auth_url` | Yes | Yes | Authorization endpoint of your GitLab OAuth provider. If you use your own instance of GitLab instead of gitlab.com, adjust `auth_url` by replacing the `gitlab.com` hostname with your own. | `https://gitlab.com/oauth/authorize` | +| `token_url` | Yes | Yes | Endpoint used to obtain GitLab OAuth access token. If you use your own instance of GitLab instead of gitlab.com, adjust `token_url` by replacing the `gitlab.com` hostname with your own. | `https://gitlab.com/oauth/token` | +| `api_url` | No | Yes | Grafana uses `/user` endpoint to obtain GitLab user information compatible with [OpenID UserInfo](https://connect2id.com/products/server/docs/api/userinfo). | `https://gitlab.com/api/v4` | +| `name` | No | Yes | Name used to refer to the GitLab authentication in the Grafana user interface. | `GitLab` | +| `icon` | No | Yes | Icon used for GitLab authentication in the Grafana user interface. | `gitlab` | +| `scopes` | No | Yes | List of comma or space-separated GitLab OAuth scopes. | `openid email profile` | +| `allow_sign_up` | No | Yes | Whether to allow new Grafana user creation through GitLab login. If set to `false`, then only existing Grafana users can log in with GitLab OAuth. | `true` | +| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | +| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the GitLab OAuth token. If no role is found, Grafana creates a JSON data with `groups` key that maps to groups obtained from GitLab's `/oauth/userinfo` endpoint, and evaluates the expression using this data. Finally, if a valid role is still not found, the expression is evaluated against the user information retrieved from `api_url/users` endpoint and groups retrieved from `api_url/groups` endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | | +| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana role cannot be extracted using `role_attribute_path`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | +| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | +| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. | `false` | +| `allow_assign_grafana_admin` | No | No | Set to `true` to enable automatic sync of the Grafana server administrator role. If this option is set to `true` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user the server administrator privileges and organization administrator role. If this option is set to `false` and the result of evaluating `role_attribute_path` for a user is `GrafanaAdmin`, Grafana grants the user only organization administrator role. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | +| `allowed_domains` | No | Yes | List of comma or space-separated domains. User must belong to at least one domain to log in. | | +| `allowed_groups` | No | Yes | List of comma or space-separated groups. The user should be a member of at least one group to log in. | | +| `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | +| `tls_client_cert` | No | No | The path to the certificate. | | +| `tls_client_key` | No | No | The path to the key. | | +| `tls_client_ca` | No | No | The path to the trusted certificate authority list. | | +| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | +| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. The `accessTokenExpirationCheck` feature toggle should also be enabled to use refresh token. | `true` | +| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md index 9e4740c6914..ce130da6e0d 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/google/index.md @@ -17,7 +17,7 @@ weight: 1100 To enable Google OAuth you must register your application with Google. Google will generate a client ID and secret key for you to use. {{% admonition type="note" %}} -If Users use the same email address in Google that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in Google that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} ## Create Google OAuth keys @@ -86,11 +86,11 @@ Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafa ## Configure Google authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Enable Google OAuth in Grafana -Specify the Client ID and Secret in the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). For example: +Specify the Client ID and Secret in the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). For example: ```bash [auth.google] @@ -189,7 +189,7 @@ To set up group sync for Google OAuth: The external group ID for a Google group is the group's email address, such as `dev@grafana.com`. -To learn more about how to configure group synchronization, refer to [Configure team sync]({{< relref "../../configure-team-sync" >}}) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. #### Configure allowed groups @@ -209,7 +209,7 @@ Unless `skip_org_role_sync` option is enabled, the user's role will be set to th The user's role is retrieved using a [JMESPath](http://jmespath.org/examples.html) expression from the `role_attribute_path` configuration option. To map the server administrator role, use the `allow_assign_grafana_admin` configuration option. -If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned after evaluating the `role_attribute_path` and the `org_mapping` expressions. To ease configuration of a proper JMESPath expression, go to [JMESPath](http://jmespath.org/) to test and evaluate expressions with custom payloads. @@ -281,7 +281,7 @@ skip_org_role_sync = false ## Configuration options -The following table outlines the various Google OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The following table outlines the various Google OAuth configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). | Setting | Required | Supported on Cloud | Description | Default | | ---------------------------- | -------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- | @@ -298,13 +298,13 @@ The following table outlines the various Google OAuth configuration options. You | `allow_sign_up` | No | Yes | Controls Grafana user creation through the Google login. Only existing Grafana users can log in with Google if set to `false`. | `true` | | `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | | `hosted_domain` | No | Yes | Specifies the domain to restrict access to users from that domain. This value is appended to the authorization request using the `hd` parameter. | | -| `validate_hd` | No | Yes | Set to `false` to disable the validation of the `hd` parameter from the Google ID token. For more informatiion, refer to [Enable Google OAuth in Grafana]({{< relref "#enable-google-oauth-in-grafana" >}}). | `true` | -| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | +| `validate_hd` | No | Yes | Set to `false` to disable the validation of the `hd` parameter from the Google ID token. For more informatiion, refer to [Enable Google OAuth in Grafana](#enable-google-oauth-in-grafana). | `true` | +| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | | `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. Grafana will first evaluate the expression using the OAuth2 ID token. If no value is returned, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | | `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `allow_assign_grafana_admin` | No | No | Set to `true` to automatically sync the Grafana server administrator role. When enabled, if the Google user's App role is `GrafanaAdmin`, Grafana grants the user server administrator privileges and the organization administrator role. If disabled, the user will only receive the organization administrator role. For more details on user role mapping, refer to [Map roles]({{< relref "#map-roles" >}}). | `false` | +| `allow_assign_grafana_admin` | No | No | Set to `true` to automatically sync the Grafana server administrator role. When enabled, if the Google user's App role is `GrafanaAdmin`, Grafana grants the user server administrator privileges and the organization administrator role. If disabled, the user will only receive the organization administrator role. For more details on user role mapping, refer to [Map roles](#map-roles). | `false` | | `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | -| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure Google to include the `groups` claim following [Configure allowed groups]({{< relref "#configure-allowed-groups" >}}). | | +| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. If you configure `allowed_groups`, you must also configure Google to include the `groups` claim following [Configure allowed groups](#configure-allowed-groups). | | | `allowed_organizations` | No | Yes | List of comma- or space-separated Azure tenant identifiers. The user should be a member of at least one tenant to log in. | | | `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | | `tls_skip_verify_insecure` | No | No | If set to `true`, the client accepts any certificate presented by the server and any host name in that certificate. _You should only use this for testing_, because this mode leaves SSL/TLS susceptible to man-in-the-middle attacks. | `false` | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/jwt/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/jwt/index.md index dc73b488a1b..29dfa1f17ae 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/jwt/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/jwt/index.md @@ -31,7 +31,7 @@ Grafana does not currently support refresh tokens. To use JWT authentication: -1. Enable JWT in the [main config file]({{< relref "../../../configure-grafana" >}}). +1. Enable JWT in the [main config file](../../../configure-grafana/). 1. Specify the header name that contains a token. ```ini @@ -106,7 +106,7 @@ provided in the HTTP header and a reverse proxy should rewrite requests to the Grafana instance to include the JWT in the request's headers. {{% admonition type="note" %}} -For embedding to work, you must enable `allow_embedding` in the [security section]({{< relref "../../../configure-grafana#allow_embedding" >}}). This setting is not available in Grafana Cloud. +For embedding to work, you must enable `allow_embedding` in the [security section](../../../configure-grafana/#allow_embedding). This setting is not available in Grafana Cloud. {{% /admonition %}} In a scenario where it is not possible to rewrite the request headers you @@ -200,7 +200,7 @@ expect_claims = {"iss": "https://your-token-issuer", "your-custom-claim": "foo"} Grafana checks for the presence of a role using the [JMESPath](http://jmespath.org/examples.html) specified via the `role_attribute_path` configuration option. The JMESPath is applied to JWT token claims. The result after evaluation of the `role_attribute_path` JMESPath expression should be a valid Grafana role, for example, `None`, `Viewer`, `Editor` or `Admin`. To assign the role to a specific organization include the `X-Grafana-Org-Id` header along with your JWT when making API requests to Grafana. -To learn more about the header, please refer to the [documentation]({{< relref "../../../../developers/http_api#x-grafana-org-id-header" >}}). +To learn more about the header, please refer to the [documentation](../../../../developers/http_api/#x-grafana-org-id-header). ### JMESPath examples diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md index 323e6e1614d..347d5fbc4dc 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/keycloak/index.md @@ -22,10 +22,10 @@ weight: 1300 Keycloak OAuth2 authentication allows users to log in to Grafana using their Keycloak credentials. This guide explains how to set up Keycloak as an authentication provider in Grafana. -Refer to [Generic OAuth authentication]({{< relref "../generic-oauth" >}}) for extra configuration options available for this provider. +Refer to [Generic OAuth authentication](../generic-oauth/) for extra configuration options available for this provider. {{% admonition type="note" %}} -If Users use the same email address in Keycloak that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in Keycloak that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} You may have to set the `root_url` option of `[server]` for the callback URL to be @@ -143,7 +143,7 @@ If you use nested groups containing special characters such as quotes or colons, groups_attribute_path = reverse("Global:department") ``` -To learn more about how to configure group synchronization, refer to [Configure team sync]({{< relref "../../configure-team-sync" >}}) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. ## Enable Single Logout diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/ldap-ui/_index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/ldap-ui/_index.md index 89ae937a995..0710af26b0e 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/ldap-ui/_index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/ldap-ui/_index.md @@ -14,7 +14,7 @@ weight: 300 # Configure LDAP authentication using the Grafana user interface -This page explains how to configure LDAP authentication in Grafana using the Grafana user interface. For more detailed information about configuring LDAP authentication using the configuration file, refer to [LDAP authentication]({{< relref "../ldap" >}}). +This page explains how to configure LDAP authentication in Grafana using the Grafana user interface. For more detailed information about configuring LDAP authentication using the configuration file, refer to [LDAP authentication](../ldap/). Benefits of using the Grafana user interface to configure LDAP authentication include: diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/ldap/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/ldap/index.md index 68e45f10032..bde7f28b541 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/ldap/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/ldap/index.md @@ -19,10 +19,10 @@ The LDAP integration in Grafana allows your Grafana users to login with their LD group memberships and Grafana Organization user roles. {{% 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" >}}). +[Enhanced LDAP authentication](../enhanced-ldap/) is available in [Grafana Cloud](/docs/grafana-cloud/) and in [Grafana Enterprise](../../../../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](../../../../administration/roles-and-permissions/access-control/) to understand how you can control access with role-based permissions. ## Supported LDAP Servers @@ -32,7 +32,7 @@ This means that you should be able to configure LDAP integration using any compl ## Enable LDAP -In order to use LDAP integration you'll first need to enable LDAP in the [main config file]({{< relref "../../../configure-grafana" >}}) as well as specify the path to the LDAP +In order to use LDAP integration you'll first need to enable LDAP in the [main config file](../../../configure-grafana/) as well as specify the path to the LDAP specific configuration file (default: `/etc/grafana/ldap.toml`). After enabling LDAP, the default behavior is for Grafana users to be created automatically upon successful LDAP authentication. If you prefer for only existing Grafana users to be able to sign in, you can change `allow_sign_up` to `false` in the `[auth.ldap]` section. @@ -160,7 +160,7 @@ Note that this does not work if you are using the single bind configuration outl {{< figure src="/static/img/docs/ldap_debug_mapping_testing.png" class="docs-image--no-shadow" max-width="600px" alt="LDAP mapping displayed" >}} -[Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) users with [enhanced LDAP integration]({{< relref "../enhanced-ldap" >}}) enabled can also see sync status in the debug view. This requires the `ldap.status:read` permission. +[Grafana Enterprise](../../../../introduction/grafana-enterprise/) users with [enhanced LDAP integration](../enhanced-ldap/) enabled can also see sync status in the debug view. This requires the `ldap.status:read` permission. {{< figure src="/static/img/docs/ldap_sync_debug.png" class="docs-image--no-shadow" max-width="600px" alt="LDAP sync status" >}} @@ -414,7 +414,7 @@ Please inspect your Active Directory configuration and documentation to find the ## Troubleshooting -To troubleshoot and get more log info enable LDAP debug logging in the [main config file]({{< relref "../../../configure-grafana" >}}). +To troubleshoot and get more log info enable LDAP debug logging in the [main config file](../../../configure-grafana/). ```bash [log] diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md index 39d77ca3f7f..4cc50a36f2a 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/okta/index.md @@ -17,7 +17,7 @@ weight: 1400 {{< docs/shared lookup="auth/intro.md" source="grafana" version="" >}} {{% admonition type="note" %}} -If Users use the same email address in Okta that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers]({{< relref "../../configure-authentication#using-the-same-email-address-to-login-with-different-identity-providers" >}}) documentation for more information. +If Users use the same email address in Okta that they use with other authentication providers (such as Grafana.com), you need to do additional configuration to ensure that the users are matched correctly. Please refer to the [Using the same email address to login with different identity providers](../#using-the-same-email-address-to-login-with-different-identity-providers) documentation for more information. {{% /admonition %}} ## Before you begin @@ -67,7 +67,7 @@ To follow this guide, ensure you have permissions in your Okta workspace to crea The remaining attributes are optional and can be set as needed. 1. Click **Save**. -1. (Optional) You can add the role attribute to the default User profile. To do this, please follow the steps in the [Optional: Add the role attribute to the User (default) Okta profile]({{< relref "#optional-add-the-role-attribute-to-the-user-default-okta-profile" >}}) section. +1. (Optional) You can add the role attribute to the default User profile. To do this, please follow the steps in the [Optional: Add the role attribute to the User (default) Okta profile](#optional-add-the-role-attribute-to-the-user-default-okta-profile) section. ### Configure Groups claim @@ -115,7 +115,7 @@ If you need to reset changes you made in the UI back to the default values, clic If you run Grafana in high availability mode, configuration changes may not get applied to all Grafana instances immediately. You may need to wait a few minutes for the configuration to propagate to all Grafana instances. {{% /admonition %}} -Refer to [configuration options]({{< relref "#configuration-options" >}}) for more information. +Refer to [configuration options](#configuration-options) for more information. ## Configure Okta authentication client using the Terraform provider @@ -147,13 +147,13 @@ Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafa ## Configure Okta authentication client using the Grafana configuration file -Ensure that you have access to the [Grafana configuration file]({{< relref "../../../configure-grafana#configuration-file-location" >}}). +Ensure that you have access to the [Grafana configuration file](../../../configure-grafana/#configuration-file-location). ### Steps To integrate your Okta OIDC provider with Grafana using our Okta OIDC integration, follow these steps: -1. Follow the [Create an Okta app]({{< relref "#create-an-okta-app" >}}) steps to create an OIDC app in Okta. +1. Follow the [Create an Okta app](#create-an-okta-app) steps to create an OIDC app in Okta. 1. Refer to the following table to update field values located in the `[auth.okta]` section of the Grafana configuration file: @@ -165,11 +165,11 @@ To integrate your Okta OIDC provider with Grafana using our Okta OIDC integratio | `api_url` | The user information endpoint of your Okta OIDC provider. `https://.okta.com/oauth2/v1/userinfo` | | `enabled` | Enables Okta OIDC authentication. Set this value to `true`. | -1. Review the list of other Okta OIDC [configuration options]({{< relref "#configuration-options" >}}) and complete them as necessary. +1. Review the list of other Okta OIDC [configuration options](#configuration-options) and complete them as necessary. -1. Optional: [Configure a refresh token]({{< relref "#configure-a-refresh-token" >}}). -1. [Configure role mapping]({{< relref "#configure-role-mapping" >}}). -1. Optional: [Configure group synchronization]({{< relref "#configure-group-synchronization-enterprise-only" >}}). +1. Optional: [Configure a refresh token](#configure-a-refresh-token). +1. [Configure role mapping](#configure-role-mapping). +1. Optional: [Configure group synchronization](#configure-group-synchronization-enterprise-only). 1. Restart Grafana. You should now see a Okta OIDC login button on the login page and be able to log in or sign up with your OIDC provider. @@ -214,17 +214,17 @@ Unless `skip_org_role_sync` option is enabled, the user's role will be set to th The user's role is retrieved using a [JMESPath](http://jmespath.org/examples.html) expression from the `role_attribute_path` configuration option against the `api_url` (`/userinfo` OIDC endpoint) endpoint payload. -If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option]({{< relref "../../../configure-grafana#auto_assign_org_role" >}}). +If no valid role is found, the user is assigned the role specified by [the `auto_assign_org_role` option](../../../configure-grafana/#auto_assign_org_role). You can disable this default role assignment by setting `role_attribute_strict = true`. This setting denies user access if no role or an invalid role is returned after evaluating the `role_attribute_path` and the `org_mapping` expressions. You can use the `org_attribute_path` and `org_mapping` configuration options to assign the user to organizations and specify their role. For more information, refer to [Org roles mapping example](#org-roles-mapping-example). If both org role mapping (`org_mapping`) and the regular role mapping (`role_attribute_path`) are specified, then the user will get the highest of the two mapped roles. To allow mapping Grafana server administrator role, use the `allow_assign_grafana_admin` configuration option. -Refer to [configuration options]({{< relref "../generic-oauth/index.md#configuration-options" >}}) for more information. +Refer to [configuration options](../generic-oauth/#configuration-options) for more information. -In [Create an Okta app]({{< relref "#create-an-okta-app" >}}), you created a custom attribute in Okta to store the role. You can use this attribute to map the role to a Grafana role by setting the `role_attribute_path` configuration option to the custom attribute name: `role_attribute_path = grafana_role`. +In [Create an Okta app](#create-an-okta-app), you created a custom attribute in Okta to store the role. You can use this attribute to map the role to a Grafana role by setting the `role_attribute_path` configuration option to the custom attribute name: `role_attribute_path = grafana_role`. -If you want to map the role based on the user's group, you can use the `groups` attribute from the user info endpoint. An example of this is `role_attribute_path = contains(groups[*], 'Example::DevOps') && 'Admin' || 'None'`. You can find more examples of JMESPath expressions on the Generic OAuth page for [JMESPath examples]({{< relref "../generic-oauth/index.md#role-mapping-examples" >}}). +If you want to map the role based on the user's group, you can use the `groups` attribute from the user info endpoint. An example of this is `role_attribute_path = contains(groups[*], 'Example::DevOps') && 'Admin' || 'None'`. You can find more examples of JMESPath expressions on the Generic OAuth page for [JMESPath examples](../generic-oauth/#role-mapping-examples). To learn about adding custom claims to the user info in Okta, refer to [add custom claims](https://developer.okta.com/docs/guides/customize-tokens-returned-from-okta/main/#add-a-custom-claim-to-a-token). @@ -254,36 +254,36 @@ Teams and roles get synchronized when the user logs in. Okta groups can be referenced by group names, like `Admins` or `Editors`. -To learn more about how to configure group synchronization, refer to [Configure team sync]({{< relref "../../configure-team-sync" >}}) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. ## Configuration options -The following table outlines the various Okta OIDC configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The following table outlines the various Okta OIDC configuration options. You can apply these options as environment variables, similar to any other configuration within Grafana. For more information, refer to [Override configuration with environment variables](../../../configure-grafana/#override-configuration-with-environment-variables). {{< admonition type="note" >}} If the configuration option requires a JMESPath expression that includes a colon, enclose the entire expression in quotes to prevent parsing errors. For example `role_attribute_path: "role:view"` {{< /admonition >}} -| Setting | Required | Supported on Cloud | Description | Default | -| ----------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------- | -| `enabled` | No | Yes | Enables Okta OIDC authentication. | `false` | -| `name` | No | Yes | Name that refers to the Okta OIDC authentication from the Grafana user interface. | `Okta` | -| `icon` | No | Yes | Icon used for the Okta OIDC authentication in the Grafana user interface. | `okta` | -| `client_id` | Yes | Yes | Client ID provided by your Okta OIDC app. | | -| `client_secret` | Yes | Yes | Client secret provided by your Okta OIDC app. | | -| `auth_url` | Yes | Yes | Authorization endpoint of your Okta OIDC provider. | | -| `token_url` | Yes | Yes | Endpoint used to obtain the Okta OIDC access token. | | -| `api_url` | Yes | Yes | Endpoint used to obtain user information. | | -| `scopes` | No | Yes | List of comma- or space-separated Okta OIDC scopes. | `openid profile email groups` | -| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Okta OIDC login. Only existing Grafana users can log in with Okta OIDC if set to `false`. | `true` | -| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | -| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the Okta OIDC ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | | -| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping]({{< relref "#configure-role-mapping" >}}). | `false` | -| `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | -| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | -| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. | | -| `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | -| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | -| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. | `false` | -| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | +| Setting | Required | Supported on Cloud | Description | Default | +| ----------------------- | -------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------- | +| `enabled` | No | Yes | Enables Okta OIDC authentication. | `false` | +| `name` | No | Yes | Name that refers to the Okta OIDC authentication from the Grafana user interface. | `Okta` | +| `icon` | No | Yes | Icon used for the Okta OIDC authentication in the Grafana user interface. | `okta` | +| `client_id` | Yes | Yes | Client ID provided by your Okta OIDC app. | | +| `client_secret` | Yes | Yes | Client secret provided by your Okta OIDC app. | | +| `auth_url` | Yes | Yes | Authorization endpoint of your Okta OIDC provider. | | +| `token_url` | Yes | Yes | Endpoint used to obtain the Okta OIDC access token. | | +| `api_url` | Yes | Yes | Endpoint used to obtain user information. | | +| `scopes` | No | Yes | List of comma- or space-separated Okta OIDC scopes. | `openid profile email groups` | +| `allow_sign_up` | No | Yes | Controls Grafana user creation through the Okta OIDC login. Only existing Grafana users can log in with Okta OIDC if set to `false`. | `true` | +| `auto_login` | No | Yes | Set to `true` to enable users to bypass the login screen and automatically log in. This setting is ignored if you configure multiple auth providers to use auto-login. | `false` | +| `role_attribute_path` | No | Yes | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana role lookup. Grafana will first evaluate the expression using the Okta OIDC ID token. If no role is found, the expression will be evaluated using the user information obtained from the UserInfo endpoint. The result of the evaluation should be a valid Grafana role (`None`, `Viewer`, `Editor`, `Admin` or `GrafanaAdmin`). For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | | +| `role_attribute_strict` | No | Yes | Set to `true` to deny user login if the Grafana org role cannot be extracted using `role_attribute_path` or `org_mapping`. For more information on user role mapping, refer to [Configure role mapping](#configure-role-mapping). | `false` | +| `org_attribute_path` | No | No | [JMESPath](http://jmespath.org/examples.html) expression to use for Grafana org to role lookup. The result of the evaluation will be mapped to org roles based on `org_mapping`. For more information on org to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | +| `org_mapping` | No | No | List of comma- or space-separated `::` mappings. Value can be `*` meaning "All users". Role is optional and can have the following values: `None`, `Viewer`, `Editor` or `Admin`. For more information on external organization to role mapping, refer to [Org roles mapping example](#org-roles-mapping-example). | | +| `skip_org_role_sync` | No | Yes | Set to `true` to stop automatically syncing user roles. This will allow you to set organization roles for your users from within Grafana manually. | `false` | +| `allowed_groups` | No | Yes | List of comma- or space-separated groups. The user should be a member of at least one group to log in. | | +| `allowed_domains` | No | Yes | List of comma- or space-separated domains. The user should belong to at least one domain to log in. | | +| `use_pkce` | No | Yes | Set to `true` to use [Proof Key for Code Exchange (PKCE)](https://datatracker.ietf.org/doc/html/rfc7636). Grafana uses the SHA256 based `S256` challenge method and a 128 bytes (base64url encoded) code verifier. | `true` | +| `use_refresh_token` | No | Yes | Set to `true` to use refresh token and check access token expiration. | `false` | +| `signout_redirect_url` | No | Yes | URL to redirect to after the user logs out. | | diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/passwordless/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/passwordless/index.md new file mode 100644 index 00000000000..4a4874ecb2a --- /dev/null +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/passwordless/index.md @@ -0,0 +1,48 @@ +--- +description: Learn how to configure passwordless authentication with magic links in Grafana +labels: + products: + - enterprise + - oss +menuTitle: Passwordless +title: Configure passwordless authentication with magic links +weight: 200 +--- + +# Configure passwordless authentication with magic links + +Passwordless authentication lets Grafana users authenticate with a magic link or one-time password (OTP) sent via email. + +## Enable passwordless authentication + +{{% admonition type="note" %}} +Passwordless authentication is an experimental feature. Engineering and on-call support is not available. Documentation is either limited or not provided outside of code comments. No SLA is provided. Enable the `passwordlessMagicLinkAuthentication` feature toggle in Grafana to use this feature. +{{% /admonition %}} + +To enable passwordless authentication, use the following configuration: + +```bash +[auth.passwordless] +enabled = true +``` + +## Code expiration + +By default, the one-time password (OTP) sent to a user's email is valid for 20 minutes. Use the `code_expiration` option to change the duration that the OTP is valid. + +```bash +[auth.passwordless] +enabled = true +code_expiration = 20m +``` + +## Enable SMTP server + +The SMTP server must be enabled so that Grafana can send emails. +The following configuration enables the SMTP server. +For more information on configuring the SMTP server, refer to [SMTP](https://grafana.com/docs/grafana/latest/setup-grafana/configure-grafana/#smtp). + +```bash +[smtp] +enabled = true +``` diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/saml-ui/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/saml-ui/index.md index 1be5e2d993e..fc71df3b8bc 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/saml-ui/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/saml-ui/index.md @@ -12,10 +12,10 @@ weight: 600 # Configure SAML authentication using the Grafana user interface {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) version 10.0 and later, and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../../../introduction/grafana-enterprise/) version 10.0 and later, and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). {{% /admonition %}} -You can configure SAML authentication in Grafana through the user interface (UI) or the Grafana configuration file. For instructions on how to set up SAML using the Grafana configuration file, refer to [Configure SAML authentication using the configuration file]({{< relref "../saml" >}}). +You can configure SAML authentication in Grafana through the user interface (UI) or the Grafana configuration file. For instructions on how to set up SAML using the Grafana configuration file, refer to [Configure SAML authentication using the configuration file](../saml/). The Grafana SAML UI provides the following advantages over configuring SAML in the Grafana configuration file: @@ -25,7 +25,7 @@ The Grafana SAML UI provides the following advantages over configuring SAML in t - Access to the SAML UI only requires access to authentication settings, so it can be used by users with limited access to Grafana's configuration {{% admonition type="note" %}} -Any configuration changes made through the Grafana user interface (UI) will take precedence over settings specified in the Grafana configuration file or through environment variables. This means that if you modify any configuration settings in the UI, they will override any corresponding settings set via environment variables or defined in the configuration file. For more information on how Grafana determines the order of precedence for its settings, please refer to the [Settings update at runtime]({{< relref "../../../configure-grafana/settings-updates-at-runtime" >}}). +Any configuration changes made through the Grafana user interface (UI) will take precedence over settings specified in the Grafana configuration file or through environment variables. This means that if you modify any configuration settings in the UI, they will override any corresponding settings set via environment variables or defined in the configuration file. For more information on how Grafana determines the order of precedence for its settings, please refer to the [Settings update at runtime](../../../configure-grafana/settings-updates-at-runtime/). {{% /admonition %}} {{% admonition type="note" %}} @@ -36,13 +36,13 @@ Disabling the UI does not affect any configuration settings that were previously To follow this guide, you need: -- Knowledge of SAML authentication. Refer to [SAML authentication in Grafana]({{< relref "../saml" >}}) for an overview of Grafana's SAML integration. +- Knowledge of SAML authentication. Refer to [SAML authentication in Grafana](../saml/) for an overview of Grafana's SAML integration. - Permissions `settings:read` and `settings:write` with scope `settings:auth.saml:*` that allow you to read and update SAML authentication settings. These permissions are granted by `fixed:authentication.config:writer` role. By default, this role is granted to Grafana server administrator in self-hosted instances and to Organization admins in Grafana Cloud instances. -- Grafana instance running Grafana version 10.0 or later with [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) or [Grafana Cloud Pro or Advanced](/docs/grafana-cloud/) license. +- Grafana instance running Grafana version 10.0 or later with [Grafana Enterprise](../../../../introduction/grafana-enterprise/) or [Grafana Cloud Pro or Advanced](/docs/grafana-cloud/) license. {{% admonition type="note" %}} It is possible to set up Grafana with SAML authentication using Azure AD. However, if an Azure AD user belongs to more than 150 groups, a Graph API endpoint is shared instead. @@ -54,8 +54,8 @@ As of Grafana 11.2, the SAML integration offers a mechanism to retrieve user gro Related links: - [Azure AD SAML limitations](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) -- [Set up SAML with Azure AD]({{< relref "../saml#set-up-saml-with-azure-ad" >}}) -- [Configure a Graph API application in Azure AD]({{< relref "../saml#configure-a-graph-api-application-in-azure-ad" >}}) +- [Set up SAML with Azure AD](../saml/#set-up-saml-with-azure-ad) +- [Configure a Graph API application in Azure AD](../saml/#configure-a-graph-api-application-in-azure-ad) {{% /admonition %}} ## Steps To Configure SAML Authentication @@ -68,12 +68,12 @@ Sign in to Grafana and navigate to **Administration > Authentication > Configure For assistance, consult the following table for additional guidance about certain fields: - | Field | Description | - | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - | **Allow signup** | If enabled, you can create new users through the SAML login. If disabled, then only existing Grafana users can log in with SAML. | - | **Auto login** | If enabled, Grafana will attempt to automatically log in with SAML skipping the login screen. | - | **Single logout** | The SAML single logout feature enables users to log out from all applications associated with the current IdP session established using SAML SSO. For more information, refer to [SAML single logout documentation]]({{< relref "../saml#single-logout" >}}). | - | **Identity provider initiated login** | Enables users to log in to Grafana directly from the SAML IdP. For more information, refer to [IdP initiated login documentation]({{< relref "../saml#idp-initiated-single-sign-on-sso" >}}). | + | Field | Description | + | ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | + | **Allow signup** | If enabled, you can create new users through the SAML login. If disabled, then only existing Grafana users can log in with SAML. | + | **Auto login** | If enabled, Grafana will attempt to automatically log in with SAML skipping the login screen. | + | **Single logout** | The SAML single logout feature enables users to log out from all applications associated with the current IdP session established using SAML SSO. For more information, refer to [SAML single logout documentation]](../saml/#single-logout). | + | **Identity provider initiated login** | Enables users to log in to Grafana directly from the SAML IdP. For more information, refer to [IdP initiated login documentation](../saml/#idp-initiated-single-sign-on-sso). | 1. Click **Next: Sign requests**. @@ -85,7 +85,7 @@ Sign in to Grafana and navigate to **Administration > Authentication > Configure Use the [PKCS #8](https://en.wikipedia.org/wiki/PKCS_8) format to issue the private key. - For more information, refer to an [example on how to generate SAML credentials]({{< relref "../saml#generate-private-key-for-saml-authentication" >}}). + For more information, refer to an [example on how to generate SAML credentials](../saml/#generate-private-key-for-saml-authentication). Alternatively, you can generate a new private key and certificate pair directly from the UI. Click on the `Generate key and certificate` button to open a form where you enter some information you want to be embedded into the new certificate. @@ -111,18 +111,36 @@ Sign in to Grafana and navigate to **Administration > Authentication > Configure ### 4. User Mapping Section -1. If you wish to [map user information from SAML assertions]({{< relref "../saml#assertion-mapping" >}}), complete the **Assertion attributes mappings** section. +1. If you wish to [map user information from SAML assertions](../saml/#assertion-mapping), complete the **Assertion attributes mappings** section. - You also need to configure the **Groups attribute** field if you want to use group synchronization. Group sync allows you to automatically map users to Grafana teams or role-based access control roles based on their SAML group membership. - To learn more about how to configure group synchronization, refer to [Configure team sync]({{< relref "../../configure-team-sync" >}}) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +If Azure is the Identity Provider over SAML there are caveats for the assertion attribute mappings. Due to how Azure interprets these attributes the full URL will need to be entered in the corresponding fields within the UI, which should match the URLs from the metadata XML. There are differences depending on whether it's a Role or Group claim vs other assertions which Microsoft has [documented](https://learn.microsoft.com/en-us/entra/identity-platform/reference-claims-customization#table-2-saml-restricted-claim-set). + +Group and Role: + +``` +http://schemas.microsoft.com/ws/2008/06/identity/claims/role +http://schemas.microsoft.com/ws/2008/06/identity/claims/groups +http://schemas.microsoft.com/identity/claims/displayname +``` + +Other Assertions: + +``` +http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress +``` + +![image](https://github.com/user-attachments/assets/23910ab8-20ec-4dfd-8ef6-7dbaec51ac90) + +You also need to configure the **Groups attribute** field if you want to use group synchronization. Group sync allows you to automatically map users to Grafana teams or role-based access control roles based on their SAML group membership. +To learn more about how to configure group synchronization, refer to [Configure team sync](../../configure-team-sync/) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. 1. If you want to automatically assign users' roles based on their SAML roles, complete the **Role mapping** section. First, you need to configure the **Role attribute** field to specify which SAML attribute should be used to retrieve SAML role information. Then enter the SAML roles that you want to map to Grafana roles in **Role mapping** section. If you want to map multiple SAML roles to a Grafana role, separate them by a comma and a space. For example, `Editor: editor, developer`. - Role mapping will automatically update user's [basic role]({{< relref "../../../../administration/roles-and-permissions/access-control#basic-roles" >}}) based on their SAML roles every time the user logs in to Grafana. - Learn more about [SAML role synchronization]({{< relref "../saml#configure-role-sync" >}}). + Role mapping will automatically update user's [basic role](../../../../administration/roles-and-permissions/access-control/#basic-roles) based on their SAML roles every time the user logs in to Grafana. + Learn more about [SAML role synchronization](../saml/#configure-role-sync). 1. If you're setting up Grafana with Azure AD using the SAML protocol and want to fetch user groups from the Graph API, complete the **Azure AD Service Account Configuration** subsection. 1. Set up a service account in Azure AD and provide the necessary details in the **Azure AD Service Account Configuration** section. @@ -137,7 +155,7 @@ Sign in to Grafana and navigate to **Administration > Authentication > Configure If you want users to have different roles in different organizations, you can additionally specify a role. For example, `Org mapping: Engineering:2:Editor` will map users who belong to `Engineering` organizations in SAML to Grafana organization with ID 2 and assign them Editor role. Organization mapping will automatically update user's organization memberships (and roles, if they have been configured) based on their SAML organization every time the user logs in to Grafana. - Learn more about [SAML organization mapping]({{< relref "../saml#configure-organization-mapping" >}}). + Learn more about [SAML organization mapping](../saml/#configure-organization-mapping). 1. If you want to limit the access to Grafana based on user's SAML organization membership, fill in the **Allowed organizations** field. 1. Click **Next: Test and enable**. diff --git a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md index 0a438b8c727..a04761c8b13 100644 --- a/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-authentication/saml/index.md @@ -22,23 +22,23 @@ weight: 500 # Configure SAML authentication using the configuration file {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud). +Available in [Grafana Enterprise](/docs/grafana//introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud). {{% /admonition %}} SAML authentication integration allows your Grafana users to log in by using an external SAML 2.0 Identity Provider (IdP). To enable this, Grafana becomes a Service Provider (SP) in the authentication flow, interacting with the IdP to exchange user information. You can configure SAML authentication in Grafana through one of the following methods: -- the Grafana configuration file -- the API (refer to [SSO Settings API]({{< relref "../../../../developers/http_api/sso-settings" >}})) -- the user interface (refer to [Configure SAML authentication using the Grafana user interface]({{< relref "../saml-ui" >}})) -- the Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings)) +- The Grafana configuration file +- The API (refer to [SSO Settings API](/docs/grafana//developers/http_api/sso-settings/) +- The user interface (refer to [Configure SAML authentication using the Grafana user interface](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/saml-ui/) +- The Terraform provider (refer to [Terraform docs](https://registry.terraform.io/providers/grafana/grafana//docs/resources/sso_settings)) {{% admonition type="note" %}} The API and Terraform support are available in Public Preview in Grafana v11.1 behind the `ssoSettingsSAML` feature toggle. You must also enable the `ssoSettingsApi` flag. {{% /admonition %}} -All methods offer the same configuration options, but you might prefer using the Grafana configuration file or the Terraform provider if you want to keep all of Grafana's authentication settings in one place. Grafana Cloud users do not have access to Grafana configuration file, so they should configure SAML through the other methods. +All methods offer the same configuration options. However, if you want to keep all of Grafana authentication settings in one place, use the Grafana configuration file or the Terraform provider. If you are a Grafana Cloud user, you do not have access to Grafana configuration file. Instead, configure SAML through the other methods. {{% admonition type="note" %}} Configuration in the API takes precedence over the configuration in the Grafana configuration file. SAML settings from the API will override any SAML configuration set in the Grafana configuration file. @@ -46,6 +46,10 @@ Configuration in the API takes precedence over the configuration in the Grafana ## Supported SAML +The following indicate what Grafana supports. + +### Bindings + Grafana supports the following SAML 2.0 bindings: - From the Service Provider (SP) to the Identity Provider (IdP): @@ -56,44 +60,45 @@ Grafana supports the following SAML 2.0 bindings: - From the Identity Provider (IdP) to the Service Provider (SP): - `HTTP-POST` binding -In terms of security: +### Security -- Grafana supports signed and encrypted assertions. -- Grafana does not support signed or encrypted requests. +Grafana supports signed and encrypted assertions, and does _not_ support encrypted requests. -In terms of initiation, Grafana supports: +### Initiation + +Grafana supports: - SP-initiated requests - IdP-initiated requests -By default, SP-initiated requests are enabled. For instructions on how to enable IdP-initiated logins, see [IdP-initiated Single Sign-On (SSO)]({{< relref "#idp-initiated-single-sign-on-sso" >}}). +By default, SP-initiated requests are enabled. For instructions on how to enable IdP-initiated logins, see [IdP-initiated Single Sign-On (SSO)](#idp-initiated-single-sign-on-sso). {{% admonition type="note" %}} It is possible to set up Grafana with SAML authentication using Azure AD. However, if an Azure AD user belongs to more than 150 groups, a Graph API endpoint is shared instead. -Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows,. +Grafana versions 11.1 and below, do not support fetching the groups from the Graph API endpoint. As a result, users with more than 150 groups will not be able to retrieve their groups. Instead, it is recommended that you use OIDC/OAuth workflows. As of Grafana 11.2, the SAML integration offers a mechanism to retrieve user groups from the Graph API. Related links: - [Azure AD SAML limitations](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) -- [Set up SAML with Azure AD]({{< relref "#set-up-saml-with-azure-ad" >}}) -- [Configure a Graph API application in Azure AD]({{< relref "#configure-a-graph-api-application-in-azure-ad" >}}) +- [Set up SAML with Azure AD](#set-up-saml-with-azure-ad) +- [Configure a Graph API application in Azure AD](#configure-a-graph-api-application-in-azure-ad) {{% /admonition %}} ### Edit SAML options in the Grafana config file -1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`]({{< relref "../../../configure-grafana/enterprise-configuration#enabled" >}}) to `true`. -1. Configure the [certificate and private key]({{< relref "#certificate-and-private-key" >}}). +1. In the `[auth.saml]` section in the Grafana configuration file, set [`enabled`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#enabled-3) to `true`. +1. Optionally, configure the [certificate and private key](#certificate-and-private-key"). 1. On the Okta application page where you have been redirected after application created, navigate to the **Sign On** tab and find **Identity Provider metadata** link in the **Settings** section. -1. Set the [`idp_metadata_url`]({{< relref "../../../configure-grafana/enterprise-configuration#idp_metadata_url" >}}) to the URL obtained from the previous step. The URL should look like `https://.okta.com/app//sso/saml/metadata`. +1. Set the [`idp_metadata_url`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#idp_metadata_url) to the URL obtained from the previous step. The URL should look like `https://.okta.com/app//sso/saml/metadata`. 1. Set the following options to the attribute names configured at the **step 10** of the SAML integration setup. You can find this attributes on the **General** tab of the application page (**ATTRIBUTE STATEMENTS** and **GROUP ATTRIBUTE STATEMENTS** in the **SAML Settings** section). - - [`assertion_attribute_login`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_login" >}}) - - [`assertion_attribute_email`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_email" >}}) - - [`assertion_attribute_name`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_name" >}}) - - [`assertion_attribute_groups`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_groups" >}}) -1. (Optional) Set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button. + - [`assertion_attribute_login`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_login) + - [`assertion_attribute_email`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_email) + - [`assertion_attribute_name`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_name) + - [`assertion_attribute_groups`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups) +1. Optionally, set the `name` parameter in the `[auth.saml]` section in the Grafana configuration file. This parameter replaces SAML in the Grafana user interface in locations such as the sign-in button. 1. Save the configuration file and then restart the Grafana server. When you are finished, the Grafana configuration might look like this example: @@ -119,7 +124,7 @@ assertion_attribute_groups = Group To use the SAML integration, in the `auth.saml` section of in the Grafana custom configuration file, set `enabled` to `true`. -Refer to [Configuration]({{< relref "../../../configure-grafana" >}}) for more information about configuring Grafana. +Refer to [Configuration](/docs/grafana//setup-grafana/configure-grafana/) for more information about configuring Grafana. ## Additional configuration for HTTP-Post binding @@ -133,9 +138,11 @@ For Grafana Cloud instances, please contact Grafana Support to update the `conte ## Certificate and private key +Commonly, the certificate and key are embedded in the [IDP metadata](#configure-the-saml-toolkit-application-endpoints) and refreshed as needed by Grafana automatically. However, if your IdP expects signed requests, you must supply a certificate and private key. + The SAML SSO standard uses asymmetric encryption to exchange information between the SP (Grafana) and the IdP. To perform such encryption, you need a public part and a private part. In this case, the X.509 certificate provides the public part, while the private key provides the private part. The private key needs to be issued in a [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format. -Grafana supports two ways of specifying both the `certificate` and `private_key`. +If you are directly supplying the certificate and key, Grafana supports two ways of specifying both the `certificate` and `private_key`: - Without a suffix (`certificate` or `private_key`), the configuration assumes you've supplied the base64-encoded file contents. - With the `_path` suffix (`certificate_path` or `private_key_path`), then Grafana treats the value entered as a file path and attempts to read the file from the file system. @@ -144,9 +151,9 @@ Grafana supports two ways of specifying both the `certificate` and `private_key` You can only use one form of each configuration option. Using multiple forms, such as both `certificate` and `certificate_path`, results in an error. {{% /admonition %}} ---- +Always work with your company's security team on setting up certificates and private keys. If you need to generate them yourself (such as in the short term, for testing purposes, and so on), use the following example to generate your certificate and private key, including the step of ensuring that the key is generated with the [PKCS#8](https://en.wikipedia.org/wiki/PKCS_8) format. -### Generate private key for SAML authentication: +### Example of private key generation for SAML authentication An example of how to generate a self-signed certificate and private key that's valid for one year: @@ -154,7 +161,15 @@ An example of how to generate a self-signed certificate and private key that's v $ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes​ ``` -The generated `key.pem` and `cert.pem` files are then used for certificate and private_key. +Base64-encode the cert.pem and key.pem files: +(-w0 switch is not needed on Mac, only for Linux) + +```sh +$ base64 -i key.pem -o key.pem.base64 +$ base64 -i cert.pem -o cert.pem.base64 +``` + +The base64-encoded values (`key.pem.base64, cert.pem.base64` files) are then used for certificate and private key. The key you provide should look like: @@ -169,16 +184,15 @@ The key you provide should look like: Grafana supports user authentication through Azure AD, which is useful when you want users to access Grafana using single sign-on. This topic shows you how to configure SAML authentication in Grafana with [Azure AD](https://azure.microsoft.com/en-us/services/active-directory/). -**Before you begin:** +**Before you begin** -- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana. - - [Roles and permissions]({{< relref "../../../../administration/roles-and-permissions" >}}). -- Learn the limitations of Azure AD SAML integration. - - [Azure AD SAML limitations](https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) -- Configure SAML integration with Azure AD, create an app integration inside the Azure AD organization first. - - [Add app integration in Azure AD](https://docs.microsoft.com/en-us/azure/active-directory/manage-apps/add-application-portal-configure) -- If you have users that belong to more than 150 groups, you need to configure a registered application to provide an Azure Graph API to retrieve the groups. - - [Setup Azure AD Graph API applications]({{< relref "#set-up-saml-with-azure-ad" >}}) +Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). + +Learn the [limitations of Azure AD SAML] (https://learn.microsoft.com/en-us/entra/identity-platform/id-token-claims-reference#groups-overage-claim) integration. + +Configure SAML integration with Azure AD, [creating an Enterprise Application](#add-microsoft-entra-saml-toolkit-from-the-gallery) inside the Azure AD organization first and then [enable single sign-on](#configure-the-saml-toolkit-application-endpoints). + +If you have users that belong to more than 150 groups, configure a registered application to provide an Azure Graph API to retrieve the groups. Refer to [Setup Azure AD Graph API applications](#configure-a-graph-api-application-in-azure-ad). ### Generate self-signed certificates @@ -277,7 +291,7 @@ Grafana supports user authentication through Okta, which is useful when you want **Before you begin:** - To configure SAML integration with Okta, create an app integration inside the Okta organization first. [Add app integration in Okta](https://help.okta.com/en/prod/Content/Topics/Apps/apps-overview-add-apps.htm) -- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions]({{< relref "../../../../administration/roles-and-permissions" >}}). +- Ensure you have permission to administer SAML authentication. For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). **To set up SAML with Okta:** @@ -391,7 +405,7 @@ Additionally, Grafana did not support IdP sessions and could not include the `Se Starting from Grafana version 11.5, Grafana uses the `NameID` from the SAML assertion to create the logout request. If the `NameID` is not present in the assertion, Grafana defaults to using the user's `Login` attribute. Additionally, Grafana supports including the `SessionIndex` in the logout request if it is provided in the SAML assertion by the IdP. {{% admonition type="note" %}} -These improvements are available in public preview behind the `improvedExternalSessionHandling` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles]({{< relref "../../../../setup-grafana/configure-grafana/feature-toggles/" >}}) +These improvements are available in public preview behind the `improvedExternalSessionHandlingSAML` feature toggle, starting from Grafana v11.5. To enable it, refer to the [Configure feature toggles](/docs/grafana//setup-grafana/configure-grafana/feature-toggles/) {{% /admonition %}} ### Assertion mapping @@ -435,11 +449,11 @@ auto_login = true Group synchronization allows you to map user groups from an identity provider to Grafana teams and roles. -To use SAML group synchronization, set [`assertion_attribute_groups`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_groups" >}}) to the attribute name where you store user groups. +To use SAML group synchronization, set [`assertion_attribute_groups`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_groups) to the attribute name where you store user groups. Then Grafana will use attribute values extracted from SAML assertion to add user to Grafana teams and grant them roles. {{% admonition type="note" %}} -Team sync allows you sync users from SAML to Grafana teams. It does not automatically create teams in Grafana. You need to create teams in Grafana before you can use this feature. +Team sync allows you sync users from SAML to Grafana teams, but you must create teams in Grafana before you can use this feature. It does not automatically create teams in Grafana. {{% /admonition %}} Given the following partial SAML assertion: @@ -474,22 +488,22 @@ The following `External Group ID`s would be valid for configuring team sync or r - `admins_group` - `division_1` -To learn more about how to configure group synchronization, refer to [Configure team sync]({{< relref "../../configure-team-sync" >}}) and [Configure group attribute sync](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. +To learn more about how to configure group synchronization, refer to [Configure team sync](/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync/) and [Configure group attribute sync](/docs/grafana//setup-grafana/configure-security/configure-group-attribute-sync) documentation. ### Configure role sync -Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions]({{< relref "../../../../administration/roles-and-permissions" >}}). +Role sync allows you to map user roles from an identity provider to Grafana. To enable role sync, configure role attribute and possible values for the Editor, Admin, and Grafana Admin roles. For more information about user roles, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). -1. In the configuration file, set [`assertion_attribute_role`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_role" >}}) option to the attribute name where the role information will be extracted from. -1. Set the [`role_values_none`]({{< relref "../../../configure-grafana/enterprise-configuration#role_values_none" >}}) option to the values mapped to the `None` role. -1. Set the [`role_values_viewer`]({{< relref "../../../configure-grafana/enterprise-configuration#role_values_viewer" >}}) option to the values mapped to the `Viewer` role. -1. Set the [`role_values_editor`]({{< relref "../../../configure-grafana/enterprise-configuration#role_values_editor" >}}) option to the values mapped to the `Editor` role. -1. Set the [`role_values_admin`]({{< relref "../../../configure-grafana/enterprise-configuration#role_values_admin" >}}) option to the values mapped to the organization `Admin` role. -1. Set the [`role_values_grafana_admin`]({{< relref "../../../configure-grafana/enterprise-configuration#role_values_grafana_admin" >}}) option to the values mapped to the `Grafana Admin` role. +1. In the configuration file, set [`assertion_attribute_role`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_role) option to the attribute name where the role information will be extracted from. +1. Set the [`role_values_none`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_none) option to the values mapped to the `None` role. +1. Set the [`role_values_viewer`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_viewer) option to the values mapped to the `Viewer` role. +1. Set the [`role_values_editor`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_editor) option to the values mapped to the `Editor` role. +1. Set the [`role_values_admin`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_admin) option to the values mapped to the organization `Admin` role. +1. Set the [`role_values_grafana_admin`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#role_values_grafana_admin) option to the values mapped to the `Grafana Admin` role. If a user role doesn't match any of configured values, then the role specified by the `auto_assign_org_role` config option will be assigned. If the `auto_assign_org_role` field is not set then the user role will default to `Viewer`. -For more information about roles and permissions in Grafana, refer to [Roles and permissions]({{< relref "../../../../administration/roles-and-permissions" >}}). +For more information about roles and permissions in Grafana, refer to [Roles and permissions](/docs/grafana//administration/roles-and-permissions/). Example configuration: @@ -518,8 +532,8 @@ skip_org_role_sync = true Organization mapping allows you to assign users to particular organization in Grafana depending on attribute value obtained from identity provider. -1. In configuration file, set [`assertion_attribute_org`]({{< relref "../../../configure-grafana/enterprise-configuration#assertion_attribute_org" >}}) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations. -1. Set [`org_mapping`]({{< relref "../../../configure-grafana/enterprise-configuration#org_mapping" >}}) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings. +1. In configuration file, set [`assertion_attribute_org`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#assertion_attribute_org) to the attribute name you store organization info in. This attribute can be an array if you want a user to be in multiple organizations. +1. Set [`org_mapping`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#org_mapping) option to the comma-separated list of `Organization:OrgId` pairs to map organization from IdP to Grafana organization specified by ID. If you want users to have different roles in multiple organizations, you can set this option to a comma-separated list of `Organization:OrgId:Role` mappings. For example, use following configuration to assign users from `Engineering` organization to the Grafana organization with ID `2` as Editor and users from `Sales` - to the org with ID `3` as Admin, based on `Org` assertion attribute value: @@ -566,7 +580,7 @@ You can use `*` as the Grafana organization in the mapping if you want all users ### Configure allowed organizations -With the [`allowed_organizations`]({{< relref "../../../configure-grafana/enterprise-configuration#allowed_organizations" >}}) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana. +With the [`allowed_organizations`](/docs/grafana//setup-grafana/configure-grafana/enterprise-configuration/#allowed_organizations) option you can specify a list of organizations where the user must be a member of at least one of them to be able to log in to Grafana. To put values containing spaces in the list, use the following JSON syntax: @@ -632,11 +646,11 @@ resource "grafana_sso_settings" "saml_sso_settings" { } ``` -Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana/latest/docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource. +Go to [Terraform Registry](https://registry.terraform.io/providers/grafana/grafana//docs/resources/sso_settings) for a complete reference on using the `grafana_sso_settings` resource. ## Troubleshoot SAML authentication in Grafana -To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration]({{< relref "../../../configure-grafana#filters" >}}) for more information. +To troubleshoot and get more log information, enable SAML debug logging in the configuration file. Refer to [Configuration](/docs/grafana//setup-grafana/configure-grafana/#filters) for more information. ```ini [log] @@ -692,7 +706,7 @@ The keys you provide should look like: When the user logs in using SAML and gets presented with "origin not allowed", the user might be issuing the login from an IdP (identity provider) service or the user is behind a reverse proxy. This potentially happens as Grafana's CSRF checks deem the requests to be invalid. For more information [CSRF](https://owasp.org/www-community/attacks/csrf). -To solve this issue, you can configure either the [`csrf_trusted_origins`]({{< relref "../../../configure-grafana#csrf_trusted_origins" >}}) or [`csrf_additional_headers`]({{< relref "../../../configure-grafana#csrf_additional_headers" >}}) option in the SAML configuration. +To solve this issue, you can configure either the [`csrf_trusted_origins`](/docs/grafana//setup-grafana/configure-grafana/#csrf_trusted_origins) or [`csrf_additional_headers`](/docs/grafana//setup-grafana/configure-grafana/#csrf_additional_headers) option in the SAML configuration. Example of a configuration file: @@ -735,7 +749,7 @@ Ensure cookie_secure is set to true to ensure that cookies are only sent over HT ## Configure SAML authentication in Grafana -The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables]({{< relref "../../../configure-grafana#override-configuration-with-environment-variables" >}}). +The table below describes all SAML configuration options. Continue reading below for details on specific options. Like any other Grafana configuration, you can apply these options as [environment variables](/docs/grafana//setup-grafana/configure-grafana/#override-configuration-with-environment-variables). | Setting | Required | Description | Default | | ---------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------- | diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/_index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/_index.md index 52a34ebc39b..a6f7f132ca0 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/_index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/_index.md @@ -16,32 +16,32 @@ weight: 700 Grafana’s database contains secrets, which are used to query data sources, send alert notifications, and perform other functions within Grafana. -Grafana encrypts these secrets before they are written to the database, by using a symmetric-key encryption algorithm called Advanced Encryption Standard (AES). These secrets are signed using a [secret key]({{< relref "../../configure-grafana#secret_key" >}}) that you can change when you configure a new Grafana instance. +Grafana encrypts these secrets before they are written to the database, by using a symmetric-key encryption algorithm called Advanced Encryption Standard (AES). These secrets are signed using a [secret key](../../configure-grafana/#secret_key) that you can change when you configure a new Grafana instance. {{% admonition type="note" %}} Grafana v9.0 and newer use [envelope encryption](#envelope-encryption) by default, which adds a layer of indirection to the encryption process that introduces an [**implicit breaking change**](#implicit-breaking-change) for older versions of Grafana. {{% /admonition %}} -For further details about how to operate a Grafana instance with envelope encryption, see the [Operational work]({{< relref "#operational-work" >}}) section. +For further details about how to operate a Grafana instance with envelope encryption, see the [Operational work](#operational-work) section. {{% admonition type="note" %}} -In Grafana Enterprise, you can also [encrypt secrets in AES-GCM (Galois/Counter Mode)]({{< relref "#changing-your-encryption-mode-to-aes-gcm" >}}) instead of the default AES-CFB (Cipher FeedBack mode). +In Grafana Enterprise, you can also [encrypt secrets in AES-GCM (Galois/Counter Mode)](#changing-your-encryption-mode-to-aes-gcm) instead of the default AES-CFB (Cipher FeedBack mode). {{% /admonition %}} ## Envelope encryption {{% admonition type="note" %}} -Since Grafana v9.0, you can turn envelope encryption off by adding the feature toggle `disableEnvelopeEncryption` to your [Grafana configuration]({{< relref "../../configure-grafana#feature_toggles" >}}). +Since Grafana v9.0, you can turn envelope encryption off by adding the feature toggle `disableEnvelopeEncryption` to your [Grafana configuration](../../configure-grafana/#feature_toggles). {{% /admonition %}} Instead of encrypting all secrets with a single key, Grafana uses a set of keys called data encryption keys (DEKs) to encrypt them. These data encryption keys are themselves encrypted with a single key encryption key (KEK), configured through the `secret_key` attribute in your -[Grafana configuration]({{< relref "../../configure-grafana#secret_key" >}}) or by [Encrypting your database with a key from a key management service (KMS)](#encrypting-your-database-with-a-key-from-a-key-management-service-kms). +[Grafana configuration](../../configure-grafana/#secret_key) or by [Encrypting your database with a key from a key management service (KMS)](#encrypting-your-database-with-a-key-from-a-key-management-service-kms). ### Implicit breaking change Envelope encryption introduces an implicit breaking change to versions of Grafana prior to v9.0, because it changes how secrets stored in the Grafana database are encrypted. Grafana administrators can upgrade to Grafana v9.0 with no action required from the database encryption perspective, but must be extremely careful if they need to roll an upgrade back to Grafana v8.5 or earlier because secrets created or modified after upgrading to Grafana v9.0 can’t be decrypted by previous versions. -Grafana v8.5 implemented envelope encryption behind an optional feature toggle. Grafana administrators who need to downgrade to Grafana v8.5 can enable envelope encryption as a workaround by adding the feature toggle `envelopeEncryption` to the [Grafana configuration]({{< relref "../../configure-grafana#feature_toggles" >}}). +Grafana v8.5 implemented envelope encryption behind an optional feature toggle. Grafana administrators who need to downgrade to Grafana v8.5 can enable envelope encryption as a workaround by adding the feature toggle `envelopeEncryption` to the [Grafana configuration](../../configure-grafana/#feature_toggles). ## Operational work @@ -59,19 +59,19 @@ You can re-encrypt secrets in order to: - Move already existing secrets' encryption forward from legacy to envelope encryption. - Re-encrypt secrets after a [data keys rotation](#rotate-data-keys). -To re-encrypt secrets, use the [Grafana CLI]({{< relref "../../../cli" >}}) by running the `grafana cli admin secrets-migration re-encrypt` command or the `/encryption/reencrypt-secrets` endpoint of the Grafana [Admin API]({{< relref "../../../developers/http_api/admin#roll-back-secrets" >}}). It's safe to run more than once, more recommended under maintenance mode. +To re-encrypt secrets, use the [Grafana CLI](../../../cli/) by running the `grafana cli admin secrets-migration re-encrypt` command or the `/encryption/reencrypt-secrets` endpoint of the Grafana [Admin API](../../../developers/http_api/admin/#roll-back-secrets). It's safe to run more than once, more recommended under maintenance mode. ### Roll back secrets You can roll back secrets encrypted with envelope encryption to legacy encryption. This might be necessary to downgrade to Grafana versions prior to v9.0 after an unsuccessful upgrade. -To roll back secrets, use the [Grafana CLI]({{< relref "../../../cli" >}}) by running the `grafana cli admin secrets-migration rollback` command or the `/encryption/rollback-secrets` endpoint of the Grafana [Admin API]({{< relref "../../../developers/http_api/admin#re-encrypt-secrets" >}}). It's safe to run more than once, more recommended under maintenance mode. +To roll back secrets, use the [Grafana CLI](../../../cli/) by running the `grafana cli admin secrets-migration rollback` command or the `/encryption/rollback-secrets` endpoint of the Grafana [Admin API](../../../developers/http_api/admin/#re-encrypt-secrets). It's safe to run more than once, more recommended under maintenance mode. ### Re-encrypt data keys You can re-encrypt data keys encrypted with a specific key encryption key (KEK). This allows you to either re-encrypt existing data keys with a new KEK version or to re-encrypt them with a completely different KEK. -To re-encrypt data keys, use the [Grafana CLI]({{< relref "../../../cli" >}}) by running the `grafana cli admin secrets-migration re-encrypt-data-keys` command or the `/encryption/reencrypt-data-keys` endpoint of the Grafana [Admin API]({{< relref "../../../developers/http_api/admin#re-encrypt-data-encryption-keys" >}}). It's safe to run more than once, more recommended under maintenance mode. +To re-encrypt data keys, use the [Grafana CLI](../../../cli/) by running the `grafana cli admin secrets-migration re-encrypt-data-keys` command or the `/encryption/reencrypt-data-keys` endpoint of the Grafana [Admin API](../../../developers/http_api/admin/#re-encrypt-data-encryption-keys). It's safe to run more than once, more recommended under maintenance mode. ### Rotate data keys @@ -85,7 +85,7 @@ secrets still encrypted with them. To completely stop using rotated data keys for both encryption and decryption, see [secrets re-encryption](#re-encrypt-secrets). {{% /admonition %}} -To rotate data keys, use the `/encryption/rotate-data-keys` endpoint of the Grafana [Admin API]({{< relref "../../../developers/http_api/admin#rotate-data-encryption-keys" >}}). It's safe to call more than once, more recommended under maintenance mode. +To rotate data keys, use the `/encryption/rotate-data-keys` endpoint of the Grafana [Admin API](../../../developers/http_api/admin/#rotate-data-encryption-keys). It's safe to call more than once, more recommended under maintenance mode. ## Encrypting your database with a key from a key management service (KMS) @@ -95,13 +95,13 @@ You can choose to encrypt secrets stored in the Grafana database using a key fro Grafana integrates with the following key management services: -- [AWS KMS]({{< relref "./encrypt-secrets-using-aws-kms" >}}) -- [Azure Key Vault]({{< relref "./encrypt-secrets-using-azure-key-vault" >}}) -- [Google Cloud KMS]({{< relref "./encrypt-secrets-using-google-cloud-kms" >}}) -- [Hashicorp Key Vault]({{< relref "./encrypt-secrets-using-hashicorp-key-vault" >}}) +- [AWS KMS](encrypt-secrets-using-aws-kms/) +- [Azure Key Vault](encrypt-secrets-using-azure-key-vault/) +- [Google Cloud KMS](encrypt-secrets-using-google-cloud-kms/) +- [Hashicorp Key Vault](encrypt-secrets-using-hashicorp-key-vault/) ## Changing your encryption mode to AES-GCM Grafana encrypts secrets using Advanced Encryption Standard in Cipher FeedBack mode (AES-CFB). You might prefer to use AES in Galois/Counter Mode (AES-GCM) instead, to meet your company’s security requirements or in order to maintain consistency with other services. -To change your encryption mode, update the `algorithm` value in the `[security.encryption]` section of your Grafana configuration file. For further details, refer to [Enterprise configuration]({{< relref "../../configure-grafana/enterprise-configuration#securityencryption" >}}). +To change your encryption mode, update the `algorithm` value in the `[security.encryption]` section of your Grafana configuration file. For further details, refer to [Enterprise configuration](../../configure-grafana/enterprise-configuration/#securityencryption). diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-aws-kms/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-aws-kms/index.md index f27851f1bd4..d081a085cb6 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-aws-kms/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-aws-kms/index.md @@ -17,7 +17,7 @@ You can use an encryption key from AWS Key Management Service to encrypt secrets **Prerequisites:** - An AWS account with permission to view and create KMS keys and programmatic credentials to access those keys -- Access to the Grafana [configuration]({{< relref "../../../configure-grafana#configuration-file-location" >}}) file +- Access to the Grafana [configuration](../../../configure-grafana/#configuration-file-location) file 1. Create a symmetric API key either from the AWS Management Console or by using the AWS KMS API.

For detailed instructions, refer to [Creating keys](https://docs.aws.amazon.com/kms/latest/developerguide/create-keys.html). diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-azure-key-vault/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-azure-key-vault/index.md index e90f81bc6d0..a13d6f7b41e 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-azure-key-vault/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-azure-key-vault/index.md @@ -17,7 +17,7 @@ You can use an encryption key from Azure Key Vault to encrypt secrets in the Gra **Prerequisites:** - An Azure account with permission to view and create Key Vault keys and programmatic credentials to access those keys -- Access to the Grafana [configuration]({{< relref "../../../configure-grafana#configuration-file-location" >}}) file +- Access to the Grafana [configuration](../../../configure-grafana/#configuration-file-location) file 1. [Create a vault](https://docs.microsoft.com/en-us/azure/key-vault/general/quick-create-portal#create-a-vault). diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-google-cloud-kms/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-google-cloud-kms/index.md index 240836fa303..3d90697e310 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-google-cloud-kms/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-google-cloud-kms/index.md @@ -17,7 +17,7 @@ You can use an encryption key from Google Cloud Key Management Service to encryp **Prerequisites:** - A Google Cloud account with permission to list and create KMS keys and service accounts to access those keys -- Access to the Grafana [configuration]({{< relref "../../../configure-grafana#configuration-file-location" >}}) file +- Access to the Grafana [configuration](../../../configure-grafana/#configuration-file-location) file 1. [Create a key ring](https://cloud.google.com/kms/docs/creating-keys#kms-create-key-ring-console) in Google Cloud KMS. diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/index.md index 76bfd46686a..e15a46679b0 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/encrypt-secrets-using-hashicorp-key-vault/index.md @@ -17,7 +17,7 @@ You can use an encryption key from Hashicorp Vault to encrypt secrets in the Gra **Prerequisites:** - Permissions to manage Hashicorp Vault to enable secrets engines and issue tokens. -- Access to the Grafana [configuration]({{< relref "../../../configure-grafana#configuration-file-location" >}}) file +- Access to the Grafana [configuration](../../../configure-grafana/#configuration-file-location) file 1. [Enable the transit secrets engine](https://www.vaultproject.io/docs/secrets/transit#setup) in Hashicorp Vault. diff --git a/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md b/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md index 12e8707d459..4af6636eaef 100644 --- a/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/index.md @@ -13,14 +13,14 @@ weight: 500 # Integrate Grafana with Hashicorp Vault -If you manage your secrets with [Hashicorp Vault](https://www.hashicorp.com/products/vault), you can use them for [Configuration]({{< relref "../../../configure-grafana" >}}) and [Provisioning]({{< relref "../../../../administration/provisioning" >}}). +If you manage your secrets with [Hashicorp Vault](https://www.hashicorp.com/products/vault), you can use them for [Configuration](../../../configure-grafana/) and [Provisioning](../../../../administration/provisioning/). {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../../introduction/grafana-enterprise" >}}). +Available in [Grafana Enterprise](../../../../introduction/grafana-enterprise/). {{% /admonition %}} {{% admonition type="note" %}} -If you have Grafana [set up for high availability]({{< relref "../../../set-up-for-high-availability" >}}), then we advise not to use dynamic secrets for provisioning files. +If you have Grafana [set up for high availability](../../../set-up-for-high-availability/), then we advise not to use dynamic secrets for provisioning files. Each Grafana instance is responsible for renewing its own leases. Your data source leases might expire when one of your Grafana servers shuts down. {{% /admonition %}} @@ -63,7 +63,7 @@ token = s.sAZLyI0r7sFLMPq6MWtoOhAN # replace with your key ## Using the Vault expander After you configure Vault, you must set the configuration or provisioning files you wish to -use Vault. Vault configuration is an extension of configuration's [variable expansion]({{< relref "../../../configure-grafana#variable-expansion" >}}) and follows the +use Vault. Vault configuration is an extension of configuration's [variable expansion](../../../configure-grafana/#variable-expansion) and follows the `$__vault{}` syntax. The argument to Vault consists of three parts separated by a colon: @@ -101,12 +101,12 @@ $__vault{database:database/creds/grafana:username} ### Examples -The following examples show you how to set your [configuration]({{< relref "../../../configure-grafana" >}}) or [provisioning]({{< relref "../../../../administration/provisioning" >}}) files to use Vault to retrieve configuration values. +The following examples show you how to set your [configuration](../../../configure-grafana/) or [provisioning](../../../../administration/provisioning/) files to use Vault to retrieve configuration values. #### Configuration The following is a partial example for using Vault to set up a Grafana configuration file's email and database credentials. -Refer to [Configuration]({{< relref "../../../configure-grafana" >}}) for more information. +Refer to [Configuration](../../../configure-grafana/) for more information. ```ini [smtp] @@ -127,7 +127,7 @@ password = $__vault{database:database/creds/grafana:password} The following is a full examples of a provisioning YAML file setting up a MySQL data source using Vault's database secrets engine. -Refer to [Provisioning]({{< relref "../../../../administration/provisioning" >}}) for more information. +Refer to [Provisioning](../../../../administration/provisioning/) for more information. **provisioning/custom.yaml** diff --git a/docs/sources/setup-grafana/configure-security/configure-group-attribute-sync.md b/docs/sources/setup-grafana/configure-security/configure-group-attribute-sync.md index 0ebe9f3db6c..ff963122050 100644 --- a/docs/sources/setup-grafana/configure-security/configure-group-attribute-sync.md +++ b/docs/sources/setup-grafana/configure-security/configure-group-attribute-sync.md @@ -16,8 +16,7 @@ Groups are mapped to [fixed](https://grafana.com/docs/grafana// > **Note:** Available in [Grafana Enterprise](https://grafana.com/docs/grafana//introduction/grafana-enterprise) and [Grafana Cloud](/docs/grafana-cloud/). {{% admonition type="note" %}} -This feature is behind the `groupAttributeSync` feature toggle. -You can enable feature toggles through configuration file or environment variables. See configuration [docs](/docs/grafana//setup-grafana/configure-grafana/#feature_toggles) for details. +This feature is currently in [private preview](https://grafana.com/docs/release-life-cycle/#private-preview) and behind the `groupAttributeSync` feature toggle. Please contact support to have this feature enabled. {{% /admonition %}} When a user logs in, Grafana checks the user's external group memberships and the configured group to role mappings to assign the corresponding roles to the user. diff --git a/docs/sources/setup-grafana/configure-security/configure-request-security.md b/docs/sources/setup-grafana/configure-security/configure-request-security.md index 3a5c393a22d..3ef83ccdcb6 100644 --- a/docs/sources/setup-grafana/configure-security/configure-request-security.md +++ b/docs/sources/setup-grafana/configure-security/configure-request-security.md @@ -19,7 +19,7 @@ Request security allows you to limit requests from the Grafana server by targeti This can be used to limit access to internal systems that the server Grafana runs on can access but that users of Grafana should not be able to access. This feature does not affect traffic from the Grafana users browser. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). {{% /admonition %}} {{% admonition type="note" %}} diff --git a/docs/sources/setup-grafana/configure-security/configure-security-hardening/index.md b/docs/sources/setup-grafana/configure-security/configure-security-hardening/index.md index bc0dae58b4a..f5e66394faf 100644 --- a/docs/sources/setup-grafana/configure-security/configure-security-hardening/index.md +++ b/docs/sources/setup-grafana/configure-security/configure-security-hardening/index.md @@ -15,7 +15,7 @@ title: Configure security hardening Security hardening enables you to apply additional security, which can help stop certain vulnerabilities from being exploited by a malicious attacker. {{% admonition type="note" %}} -These settings are available in the [grafana.ini configuration file]({{< relref "../../configure-grafana#configuration-file-location" >}}). To apply changes to the configuration file, restart the Grafana server. +These settings are available in the [grafana.ini configuration file](../../configure-grafana/#configuration-file-location). To apply changes to the configuration file, restart the Grafana server. {{% /admonition %}} ## Additional security for cookies diff --git a/docs/sources/setup-grafana/configure-security/configure-team-sync.md b/docs/sources/setup-grafana/configure-security/configure-team-sync.md index f5d50cff311..dfe6d4f2c99 100644 --- a/docs/sources/setup-grafana/configure-security/configure-team-sync.md +++ b/docs/sources/setup-grafana/configure-security/configure-team-sync.md @@ -16,7 +16,7 @@ weight: 1000 Team sync lets you set up synchronization between your auth providers teams and teams in Grafana. This enables LDAP, OAuth, or SAML users who are members of certain teams or groups to automatically be added or removed as members of certain teams in Grafana. -> **Note:** Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud Advanced](/docs/grafana-cloud/). +> **Note:** Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud Advanced](/docs/grafana-cloud/). Grafana keeps track of all synchronized users in teams, and you can see which users have been synchronized in the team members list, see `LDAP` label in screenshot. This mechanism allows Grafana to remove an existing synchronized user from a team when its group membership changes. This mechanism also enables you to manually add a user as member of a team, and it will not be removed when the user signs in. This gives you flexibility to combine LDAP group memberships and Grafana team memberships. @@ -27,16 +27,15 @@ This mechanism allows Grafana to remove an existing synchronized user from a tea ## Supported providers -- [Auth Proxy]({{< relref "./configure-authentication/auth-proxy#team-sync-enterprise-only" >}}) -- [Azure AD](https://grafana.com/docs/grafana//configure-authentication/azuread#group-sync-enterprise-only) -- [Azure AD](https://grafana.com/docs/grafana//configure-security/configure-authentication/azuread#group-sync-enterprise-only) -- [Generic OAuth integration](https://grafana.com/docs/grafana//configure-security/configure-authentication/generic-oauth#configure-group-synchronization) -- [GitHub OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/github#configure-group-synchronization) -- [GitLab OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/gitlab#configure-group-synchronization) -- [Google OAuth](https://grafana.com/docs/grafana//configure-security/configure-authentication/google#configure-group-synchronization) -- [LDAP](https://grafana.com/docs/grafana//configure-security/configure-authentication/enhanced-ldap#ldap-group-synchronization) -- [Okta](https://grafana.com/docs/grafana//configure-security/configure-authentication/okta#configure-group-synchronization-enterprise-only) -- [SAML](https://grafana.com/docs/grafana//configure-security/configure-authentication/saml#configure-group-synchronization) +- [Auth Proxy](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/auth-proxy/#team-sync-enterprise-only) +- [Azure AD](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/azuread#group-sync-enterprise-only) +- [Generic OAuth integration](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/generic-oauth#configure-group-synchronization) +- [GitHub OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/github#configure-group-synchronization) +- [GitLab OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/gitlab#configure-group-synchronization) +- [Google OAuth](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/google#configure-group-synchronization) +- [LDAP](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/enhanced-ldap#ldap-group-synchronization) +- [Okta](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/okta#configure-group-synchronization-enterprise-only) +- [SAML](https://grafana.com/docs/grafana//setup-grafana/configure-security/configure-authentication/saml#configure-group-synchronization) ## Synchronize a Grafana team with an external group diff --git a/docs/sources/setup-grafana/configure-security/export-logs.md b/docs/sources/setup-grafana/configure-security/export-logs.md index 56c6dfc9831..d3b1c1e1530 100644 --- a/docs/sources/setup-grafana/configure-security/export-logs.md +++ b/docs/sources/setup-grafana/configure-security/export-logs.md @@ -18,7 +18,7 @@ weight: 900 # Export logs of usage insights {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud Pro and Advanced](/docs/grafana-cloud/). {{% /admonition %}} By exporting usage logs to Loki, you can directly query them and create dashboards of the information that matters to you most, such as dashboard errors, most active organizations, or your top-10 most-used queries. This configuration is done for you in Grafana Cloud, with provisioned dashboards. Read about them in the [Grafana Cloud documentation](/docs/grafana-cloud/usage-insights/). @@ -66,7 +66,7 @@ Logs of usage insights contain the following fields, where the fields followed b ## Configuration -To export your logs, enable the usage insights feature and [configure]({{< relref "../../setup-grafana/configure-grafana" >}}) an export location in the configuration file: +To export your logs, enable the usage insights feature and [configure](../../configure-grafana/) an export location in the configuration file: ```ini [usage_insights.export] @@ -96,7 +96,7 @@ tls = true tenant_id = ``` -Using `logger` will print usage insights to your [Grafana server log]({{< relref "../../setup-grafana/configure-grafana#log" >}}). +Using `logger` will print usage insights to your [Grafana server log](../../configure-grafana/#log). There is no option for configuring the `logger` storage type. ## Visualize Loki usage insights in Grafana @@ -110,4 +110,4 @@ If you export logs into Loki, you can build Grafana dashboards to understand you 1. Play with usage insights to understand them: - In Explore, you can use the query `{datasource="gdev-loki",kind="usage_insights"}` to retrieve all logs related to your `gdev-loki` data source. - In a dashboard, you can build a table panel with the query `topk(10, sum by (error) (count_over_time({kind="usage_insights", datasource="gdev-prometheus"} | json | error != "" [$__interval])))` to display the 10 most common errors your users see using the `gdev-prometheus` data source. - - In a dashboard, you can build a graph panel with the queries `sum by(host) (count_over_time({kind="usage_insights"} | json | eventName="data-request" | error != "" [$__interval]))` and `sum by(host) (count_over_time({kind="usage_insights"} | json | eventName="data-request" | error = "" [$__interval]))` to show the evolution of the data request count over time. Using `by (host)` allows you to have more information for each Grafana server you have if you have set up Grafana for [high availability](<{{< relref "../../setup-grafana/set-up-for-high-availability/" >}}>). + - In a dashboard, you can build a graph panel with the queries `sum by(host) (count_over_time({kind="usage_insights"} | json | eventName="data-request" | error != "" [$__interval]))` and `sum by(host) (count_over_time({kind="usage_insights"} | json | eventName="data-request" | error = "" [$__interval]))` to show the evolution of the data request count over time. Using `by (host)` allows you to have more information for each Grafana server you have if you have set up Grafana for [high availability](../../set-up-for-high-availability/). diff --git a/docs/sources/setup-grafana/configure-security/planning-iam-strategy/index.md b/docs/sources/setup-grafana/configure-security/planning-iam-strategy/index.md index 92ac9f1c5f3..d553d33c343 100644 --- a/docs/sources/setup-grafana/configure-security/planning-iam-strategy/index.md +++ b/docs/sources/setup-grafana/configure-security/planning-iam-strategy/index.md @@ -12,7 +12,7 @@ keywords: # Plan your IAM integration strategy -This section describes the decisions you should make when using an Identity and Access Management (IAM) provider to manage access to Grafana. IAM ensures that users have secure access to sensitive data and [other resources]({{< relref "../../../administration/data-source-management" >}}), simplifying user management and authentication. +This section describes the decisions you should make when using an Identity and Access Management (IAM) provider to manage access to Grafana. IAM ensures that users have secure access to sensitive data and [other resources](../../../administration/data-source-management/), simplifying user management and authentication. ## Benefits of integrating with an IAM provider @@ -33,12 +33,12 @@ In order to plan an integration with Grafana, assess your organization's current As a first step, determine how you want to manage users who will access Grafana. Do you already use an identity provider to manage users? If so, Grafana might be able to integrate with your identity provider through one of our IdP integrations. -Refer to [Configure authentication documentation]({{< relref "../../configure-security/configure-authentication" >}}) for the list of supported providers. +Refer to [Configure authentication documentation](../configure-authentication/) for the list of supported providers. If you are not interested in setting up an external identity provider, but still want to limit access to your Grafana instance, consider using Grafana's basic authentication. Finally, if you want your Grafana instance to be accessible to everyone, you can enable anonymous access to Grafana. -For information, refer to the [anonymous authentication documentation]({{< relref "../../configure-security/configure-authentication#anonymous-authentication" >}}). +For information, refer to the [anonymous authentication documentation](../configure-authentication/#anonymous-authentication). ## Ways to organize users @@ -51,7 +51,7 @@ Organize users in subgroups that are sensible to the organization. For example: ### Users in Grafana teams -You can organize users into [teams]({{< relref "../../../administration/team-management" >}}) and assign them roles and permissions reflecting the current organization. For example, instead of assigning five users access to the same dashboard, you can create a team of those users and assign dashboard permissions to the team. +You can organize users into [teams](../../../administration/team-management/) and assign them roles and permissions reflecting the current organization. For example, instead of assigning five users access to the same dashboard, you can create a team of those users and assign dashboard permissions to the team. A user can belong to multiple teams and be a member or an administrator for a given team. Team members inherit permissions from the team but cannot edit the team itself. Team administrators can add members to a team and update its settings, such as the team name, team members, roles assigned, and UI preferences. @@ -59,17 +59,17 @@ Teams are a perfect solution for working with a subset of users. Teams can share ### Users in Grafana organizations -[Grafana organizations]({{< relref "../../../administration/organization-management" >}}) allow complete isolation of resources, such as dashboards and data sources. Users can be members of one or several organizations, and they can only access resources from an organization they belong to. +[Grafana organizations](../../../administration/organization-management/) allow complete isolation of resources, such as dashboards and data sources. Users can be members of one or several organizations, and they can only access resources from an organization they belong to. Having multiple organizations in a single instance of Grafana lets you manage your users in one place while completely separating resources. -Organizations provide a higher measure of isolation within Grafana than teams do and can be helpful in certain scenarios. However, because organizations lack the scalability and flexibility of teams and [folders]({{< relref "../../../dashboards/manage-dashboards#create-a-dashboard-folder" >}}), we do not recommend using them as the default way to group users and resources. +Organizations provide a higher measure of isolation within Grafana than teams do and can be helpful in certain scenarios. However, because organizations lack the scalability and flexibility of teams and [folders](../../../dashboards/manage-dashboards/#create-a-dashboard-folder), we do not recommend using them as the default way to group users and resources. Note that Grafana Cloud does not support having more than 1 organizations per instance. ### Choosing between teams and organizations -[Grafana teams]({{< relref "../../../administration/team-management" >}}) and Grafana organizations serve similar purposes in the Grafana platform. Both are designed to help group users and manage and control access to resources. +[Grafana teams](../../../administration/team-management/) and Grafana organizations serve similar purposes in the Grafana platform. Both are designed to help group users and manage and control access to resources. Teams provide more flexibility, as resources can be accessible by multiple teams, and team creation and management are simple. @@ -106,7 +106,7 @@ A common use case for creating a service account is to perform operations on aut - Set up an external SAML authentication provider - Interact with Grafana without signing in as a user -In [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}), you can also use service accounts in combination with [role-based access control]({{< relref "../../../administration/roles-and-permissions/access-control" >}}) to grant very specific permissions to applications that interact with Grafana. +In [Grafana Enterprise](../../../introduction/grafana-enterprise/), you can also use service accounts in combination with [role-based access control](../../../administration/roles-and-permissions/access-control/) to grant very specific permissions to applications that interact with Grafana. {{% admonition type="note" %}} Service accounts can only act in the organization they are created for. We recommend creating service accounts in each organization if you have the same task needed for multiple organizations. @@ -136,7 +136,7 @@ Service account access tokens inherit permissions from the service account. ### API keys {{% admonition type="note" %}} -Grafana recommends using service accounts instead of API keys. API keys will be deprecated in the near future. For more information, refer to [Grafana service accounts]({{< relref ".#service-accounts" >}}). +Grafana recommends using service accounts instead of API keys. API keys will be deprecated in the near future. For more information, refer to [Grafana service accounts](./#service-accounts). {{% /admonition %}} You can use Grafana API keys to interact with data sources via HTTP APIs. @@ -149,7 +149,7 @@ You can assign roles through the user interface or APIs, establish them through ### What are roles? -Within an organization, Grafana has established three primary [organization roles]({{< relref "../../../administration/roles-and-permissions#organization-roles" >}}) - organization administrator, editor, and viewer - which dictate the user's level of access and permissions, including the ability to edit data sources or create teams. Grafana also has an empty role that you can start with and to which you can gradually add custom permissions. +Within an organization, Grafana has established three primary [organization roles](../../../administration/roles-and-permissions/#organization-roles) - organization administrator, editor, and viewer - which dictate the user's level of access and permissions, including the ability to edit data sources or create teams. Grafana also has an empty role that you can start with and to which you can gradually add custom permissions. To be a member of any organization, every user must be assigned a role. In addition, Grafana provides a server administrator role that grants access to and enables interaction with resources that affect the entire instance, including organizations, users, and server-wide settings. @@ -157,23 +157,23 @@ This particular role can only be accessed by users of self-hosted Grafana instan ### What are permissions? -Each role consists of a set of [permissions]({{< relref "../../../administration/roles-and-permissions#dashboard-permissions" >}}) that determine the tasks a user can perform in the system. +Each role consists of a set of [permissions](../../../administration/roles-and-permissions/#dashboard-permissions) that determine the tasks a user can perform in the system. For example, the **Admin** role includes permissions that let an administrator create and delete users. Grafana allows for precise permission settings on both dashboards and folders, giving you the ability to control which users and teams can view, edit, and administer them. For example, you might want a certain viewer to be able to edit a dashboard. While that user can see all dashboards, you can grant them access to update only one of them. -In [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}), you can also grant granular permissions for data sources to control who can query and edit them. +In [Grafana Enterprise](../../../introduction/grafana-enterprise/), you can also grant granular permissions for data sources to control who can query and edit them. Dashboard, folder, and data source permissions can be set through the UI or APIs or provisioned through Terraform. ### Role-based access control {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud/). {{% /admonition %}} -If you think that the basic organization and server administrator roles are too limiting, it might be beneficial to employ [role-based access control (RBAC)]({{< relref "../../../administration/roles-and-permissions/access-control" >}}). +If you think that the basic organization and server administrator roles are too limiting, it might be beneficial to employ [role-based access control (RBAC)](../../../administration/roles-and-permissions/access-control/). RBAC is a flexible approach to managing user access to Grafana resources, including users, data sources, and reports. It enables easy granting, changing, and revoking of read and write access for users. RBAC comes with pre-defined roles, such as data source writer, which allows updating, reading, or querying all data sources. @@ -190,7 +190,7 @@ When connecting Grafana to an identity provider, it's important to think beyond Team sync is a feature that allows you to synchronize teams or groups from your authentication provider with teams in Grafana. This means that users of specific teams or groups in LDAP, OAuth, or SAML will be automatically added or removed as members of corresponding teams in Grafana. Whenever a user logs in, Grafana will check for any changes in the teams or groups of the authentication provider and update the user's teams in Grafana accordingly. This makes it easy to manage user permissions across multiple systems. {{% admonition type="note" %}} -Available in [Grafana Enterprise]({{< relref "../../../introduction/grafana-enterprise" >}}) and [Grafana Cloud Advanced](/docs/grafana-cloud/). +Available in [Grafana Enterprise](../../../introduction/grafana-enterprise/) and [Grafana Cloud Advanced](/docs/grafana-cloud/). {{% /admonition %}} {{% admonition type="note" %}} diff --git a/docs/sources/setup-grafana/configure-security/secret-scan.md b/docs/sources/setup-grafana/configure-security/secret-scan.md index 031c1c06175..8029c476ded 100644 --- a/docs/sources/setup-grafana/configure-security/secret-scan.md +++ b/docs/sources/setup-grafana/configure-security/secret-scan.md @@ -11,7 +11,7 @@ weight: 1000 # Configure Grafana secret scanning and notifications -With Grafana, you can use the GitHub Secret Scanning service to determine if your [service account tokens]({{< relref "../../administration/service-accounts" >}}) have been leaked on GitHub. +With Grafana, you can use the GitHub Secret Scanning service to determine if your [service account tokens](../../../administration/service-accounts/) have been leaked on GitHub. When GitHub Secret Scanning detects a Grafana secret, its hash is stored in Grafana Labs' secret scanning service. diff --git a/docs/sources/setup-grafana/image-rendering/_index.md b/docs/sources/setup-grafana/image-rendering/_index.md index 639f00b6f79..a445d0d2072 100644 --- a/docs/sources/setup-grafana/image-rendering/_index.md +++ b/docs/sources/setup-grafana/image-rendering/_index.md @@ -18,19 +18,17 @@ weight: 1000 # Set up image rendering -Grafana supports automatic rendering of panels as PNG images. This allows Grafana to automatically generate images of your panels to include in alert notifications, [PDF export]({{< relref "../../dashboards/create-reports#export-dashboard-as-pdf" >}}), and [Reporting]({{< relref "../../dashboards/create-reports" >}}). PDF Export and Reporting are available only in [Grafana Enterprise]({{< relref "../../introduction/grafana-enterprise" >}}) and [Grafana Cloud](/docs/grafana-cloud/). - -> **Note:** Image rendering of dashboards is not supported at this time. +Grafana supports automatic rendering of panels as PNG images. This allows Grafana to automatically generate images of your panels to include in alert notifications, [PDF export](../../dashboards/create-reports/#export-dashboard-as-pdf), and [Reporting](../../dashboards/create-reports/). PDF Export and Reporting are available only in [Grafana Enterprise](../../introduction/grafana-enterprise/) and [Grafana Cloud](/docs/grafana-cloud/). While an image is being rendered, the PNG image is temporarily written to the file system. When the image is rendered, the PNG image is temporarily written to the `png` folder in the Grafana `data` folder. -A background job runs every 10 minutes and removes temporary images. You can configure how long an image should be stored before being removed by configuring the [temp_data_lifetime]({{< relref "../configure-grafana#temp_data_lifetime" >}}) setting. +A background job runs every 10 minutes and removes temporary images. You can configure how long an image should be stored before being removed by configuring the [temp_data_lifetime](../configure-grafana/#temp_data_lifetime) setting. You can also render a PNG by hovering over the panel to display the actions menu in the top-right corner, and then clicking **Share > Share link**. The **Render image** option is displayed in the link settings. ## Alerting and render limits -Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [max_concurrent_screenshots]({{< relref "../configure-grafana#max_concurrent_screenshots" >}}). +Alert notifications can include images, but rendering many images at the same time can overload the server where the renderer is running. For instructions of how to configure this, see [max_concurrent_screenshots](../configure-grafana/#max_concurrent_screenshots). ## Install Grafana Image Renderer plugin @@ -50,7 +48,7 @@ Rendering multiple images in parallel requires an even bigger memory footprint. The Grafana Image Renderer plugin has a number of configuration options that are used in plugin or remote rendering modes. -In plugin mode, you can specify them directly in the [Grafana configuration file]({{< relref "../configure-grafana#plugingrafana-image-renderer" >}}). +In plugin mode, you can specify them directly in the [Grafana configuration file](../configure-grafana/#plugingrafana-image-renderer). In remote rendering mode, you can specify them in a `.json` [configuration file](#configuration-file) or, for some of them, you can override the configuration defaults using environment variables. @@ -96,7 +94,7 @@ AUTH_TOKEN=- } ``` -See [Grafana configuration]({{< relref "../configure-grafana#renderer_token" >}}) for how to configure the token in Grafana. +See [Grafana configuration](../configure-grafana/#renderer_token) for how to configure the token in Grafana. ### Rendering mode @@ -166,7 +164,7 @@ RENDERING_MODE=reusable #### Optimize the performance, CPU and memory usage of the image renderer -The performance and resources consumption of the different modes depend a lot on the number of concurrent requests your service is handling. To understand how many concurrent requests your service is handling, [monitor your image renderer service]({{< relref "./monitoring" >}}). +The performance and resources consumption of the different modes depend a lot on the number of concurrent requests your service is handling. To understand how many concurrent requests your service is handling, [monitor your image renderer service](monitoring/). With no concurrent requests, the different modes show very similar performance and CPU / memory usage. @@ -223,10 +221,14 @@ HTTPS protocol is supported in the image renderer v3.11.0 and later. Change the protocol of the server, it can be `http` or `https`. Default is `http`. +```bash +HTTP_PROTOCOL=https +``` + ```json { "service": { - "protocol": "http" + "protocol": "https" } } ``` @@ -235,6 +237,11 @@ Change the protocol of the server, it can be `http` or `https`. Default is `http Path to the image renderer certificate and key file used to start an HTTPS server. +```bash +HTTP_CERT_FILE=./path/to/cert +HTTP_CERT_KEY=./path/to/key +``` + ```json { "service": { @@ -248,6 +255,10 @@ Path to the image renderer certificate and key file used to start an HTTPS serve Minimum TLS version allowed. Accepted values are: `TLSv1.2`, `TLSv1.3`. Default is `TLSv1.2`. +```bash +HTTP_MIN_TLS_VERSION=TLSv1.2 +``` + ```json { "service": { @@ -258,7 +269,7 @@ Minimum TLS version allowed. Accepted values are: `TLSv1.2`, `TLSv1.3`. Default #### Enable Prometheus metrics -You can enable [Prometheus](https://prometheus.io/) metrics endpoint `/metrics` using the environment variable `ENABLE_METRICS`. Node.js and render request duration metrics are included, see [Enable Prometheus metrics endpoint]({{< relref "./monitoring#enable-prometheus-metrics-endpoint" >}}) for details. +You can enable [Prometheus](https://prometheus.io/) metrics endpoint `/metrics` using the environment variable `ENABLE_METRICS`. Node.js and render request duration metrics are included, see [Enable Prometheus metrics endpoint](monitoring/#enable-prometheus-metrics-endpoint) for details. Default is `false`. @@ -569,3 +580,21 @@ RENDERING_VIEWPORT_PAGE_ZOOM_LEVEL=1 } } ``` + +#### Tracing + +Enable OpenTelemetry Tracing by setting the tracing URL. Default is empty (disabled). + +```bash +RENDERING_TRACING_URL="http://localhost:4318/v1/traces" +``` + +```json +{ + "rendering": { + "tracing": { + "url": "http://localhost:4318/v1/traces" + } + } +} +``` diff --git a/docs/sources/setup-grafana/image-rendering/monitoring/index.md b/docs/sources/setup-grafana/image-rendering/monitoring/index.md index 1d6779133d5..ad4334f52e3 100644 --- a/docs/sources/setup-grafana/image-rendering/monitoring/index.md +++ b/docs/sources/setup-grafana/image-rendering/monitoring/index.md @@ -18,7 +18,7 @@ weight: 100 # Monitor the image renderer -Rendering images requires a lot of memory, mainly because Grafana creates browser instances in the background for the actual rendering. Monitoring your service can help you allocate the right amount of resources to your rendering service and set the right [rendering mode]({{< relref "../../image-rendering#rendering-mode" >}}). +Rendering images requires a lot of memory, mainly because Grafana creates browser instances in the background for the actual rendering. Monitoring your service can help you allocate the right amount of resources to your rendering service and set the right [rendering mode](../#rendering-mode). ## Enable Prometheus metrics endpoint diff --git a/docs/sources/setup-grafana/image-rendering/troubleshooting/index.md b/docs/sources/setup-grafana/image-rendering/troubleshooting/index.md index aa4ce5c8d96..a42ee69df2c 100644 --- a/docs/sources/setup-grafana/image-rendering/troubleshooting/index.md +++ b/docs/sources/setup-grafana/image-rendering/troubleshooting/index.md @@ -32,7 +32,7 @@ You can enable debug log messages for rendering in the Grafana configuration fil filters = rendering:debug ``` -You can also enable more logs in image renderer service itself by enabling [debug logging]({{< relref "#enable-debug-logging" >}}). +You can also enable more logs in image renderer service itself by enabling [debug logging](#enable-debug-logging). ## Missing libraries diff --git a/docs/sources/setup-grafana/installation/_index.md b/docs/sources/setup-grafana/installation/_index.md index 940a80aa91c..be7a51d7518 100644 --- a/docs/sources/setup-grafana/installation/_index.md +++ b/docs/sources/setup-grafana/installation/_index.md @@ -31,11 +31,11 @@ Grafana relies on other open source software to operate. For a list of open sour Grafana supports the following operating systems: -- [Debian or Ubuntu]({{< relref "./debian" >}}) -- [Red Hat, RHEL, or Fedora]({{< relref "./redhat-rhel-fedora" >}}) -- [SUSE or openSUSE]({{< relref "./suse-opensuse" >}}) -- [macOS]({{< relref "./mac" >}}) -- [Windows]({{< relref "./windows" >}}) +- [Debian or Ubuntu](debian/) +- [RHEL or Fedora](redhat-rhel-fedora/) +- [SUSE or openSUSE](suse-opensuse/) +- [macOS](mac/) +- [Windows](windows/) {{% admonition type="note" %}} Installation of Grafana on other operating systems is possible, but is not recommended or supported. @@ -51,8 +51,8 @@ Grafana requires the minimum system resources: Some features might require more memory or CPUs, including: - [Server side rendering of images](/grafana/plugins/grafana-image-renderer#requirements) -- [Alerting]({{< relref "../../alerting" >}}) -- [Data source proxy]({{< relref "../../developers/http_api/data_source" >}}) +- [Alerting](../../alerting/) +- [Data source proxy](../../developers/http_api/data_source/) ## Supported databases diff --git a/docs/sources/setup-grafana/installation/debian/index.md b/docs/sources/setup-grafana/installation/debian/index.md index 1aeb3203e4b..36fc5451ef5 100644 --- a/docs/sources/setup-grafana/installation/debian/index.md +++ b/docs/sources/setup-grafana/installation/debian/index.md @@ -18,9 +18,9 @@ This topic explains how to install Grafana dependencies, install Grafana on Linu There are multiple ways to install Grafana: using the Grafana Labs APT repository, by downloading a `.deb` package, or by downloading a binary `.tar.gz` file. Choose only one of the methods below that best suits your needs. -{{% admonition type="note" %}} +{{< admonition type="note" >}} If you install via the `.deb` package or `.tar.gz` file, then you must manually update Grafana for each new version. -{{% /admonition %}} +{{< /admonition >}} The following video demonstrates how to install Grafana on Debian and Ubuntu as outlined in this document: @@ -37,9 +37,9 @@ If you install from the APT repository, Grafana automatically updates when you r | Grafana OSS | grafana | `https://apt.grafana.com stable main` | | Grafana OSS (Beta) | grafana | `https://apt.grafana.com beta main` | -{{% admonition type="note" %}} +{{< admonition type="note" >}} Grafana Enterprise is the recommended and default edition. It is available for free and includes all the features of the OSS edition. You can also upgrade to the [full Enterprise feature set](/products/enterprise/?utm_source=grafana-install-page), which has support for [Enterprise plugins](/grafana/plugins/?enterprise=1&utcm_source=grafana-install-page). -{{% /admonition %}} +{{< /admonition >}} Complete the following steps to install Grafana from the APT repository: @@ -89,11 +89,11 @@ Complete the following steps to install Grafana from the APT repository: sudo apt-get install grafana-enterprise ``` -## Install Grafana using a deb package or as a standalone binary +## Install Grafana using a deb package -If you choose not to install Grafana using APT, you can download and install Grafana using the deb package or as a standalone binary. +If you install Grafana manually using the deb package, then you must manually update Grafana for each new version. -Complete the following steps to install Grafana using DEB or the standalone binaries: +Complete the following steps to install Grafana using a deb package: 1. Navigate to the [Grafana download page](/grafana/download). 1. Select the Grafana version you want to install. @@ -105,6 +105,80 @@ Complete the following steps to install Grafana using DEB or the standalone bina 1. Depending on which system you are running, click the **Linux** or **ARM** tab on the [download page](/grafana/download). 1. Copy and paste the code from the [download page](/grafana/download) into your command line and run. +## Install Grafana as a standalone binary + +Complete the following steps to install Grafana using the standalone binaries: + +1. Navigate to the [Grafana download page](/grafana/download). +1. Select the Grafana version you want to install. + - The most recent Grafana version is selected by default. + - The **Version** field displays only tagged releases. If you want to install a nightly build, click **Nightly Builds** and then select a version. +1. Select an **Edition**. + - **Enterprise:** This is the recommended version. It is functionally identical to the open source version but includes features you can unlock with a license if you so choose. + - **Open Source:** This version is functionally identical to the Enterprise version, but you will need to download the Enterprise version if you want Enterprise features. +1. Depending on which system you are running, click the **Linux** or **ARM** tab on the [download page](/grafana/download). +1. Copy and paste the code from the [download page](/grafana/download) page into your command line and run. +1. Create a user account for Grafana on your system: + + ```shell + sudo useradd -r -s /bin/false grafana + ``` + +1. Move the unpacked binary to `/usr/local/grafana`: + + ```shell + sudo mv /usr/local/grafana + ``` + +1. Change the owner of `/usr/local/grafana` to Grafana users: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. Create a Grafana server systemd unit file: + + ```shell + sudo touch /etc/systemd/system/grafana-server.service + ``` + +1. Add the following to the unit file in a text editor of your choice: + + ```ini + [Unit] + Description=Grafana Server + After=network.target + + [Service] + Type=simple + User=grafana + Group=users + ExecStart=/usr/local/grafana/bin/grafana server --config=/usr/local/grafana/conf/grafana.ini --homepath=/usr/local/grafana + Restart=on-failure + + [Install] + WantedBy=multi-user.target + ``` + +1. Use the binary to manually start the Grafana server: + + ```shell + /usr/local/grafana/bin/grafana-server --homepath /usr/local/grafana + ``` + + {{< admonition type="note" >}} + Manually invoking the binary in this step automatically creates the `/usr/local/grafana/data` directory, which needs to be created and configured before the installation can be considered complete. + {{< /admonition >}} + +1. Press `CTRL+C` to stop the Grafana server. +1. Change the owner of `/usr/local/grafana` to Grafana users again to apply the ownership to the newly created `/usr/local/grafana/data` directory: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. [Configure the Grafana server to start at boot time using systemd](https://grafana.com/docs/grafana/latest/setup-grafana/start-restart-grafana/#configure-the-grafana-server-to-start-at-boot-using-systemd). + ## Uninstall on Debian or Ubuntu Complete any of the following steps to uninstall Grafana. @@ -143,4 +217,4 @@ To uninstall Grafana, run the following commands in a terminal window: ## Next steps -- [Start the Grafana server]({{< relref "../../start-restart-grafana" >}}) +- [Start the Grafana server](../../start-restart-grafana/) diff --git a/docs/sources/setup-grafana/installation/docker/index.md b/docs/sources/setup-grafana/installation/docker/index.md index 91ab60a7764..da578681fca 100644 --- a/docs/sources/setup-grafana/installation/docker/index.md +++ b/docs/sources/setup-grafana/installation/docker/index.md @@ -24,7 +24,7 @@ Grafana Docker images come in two editions: > **Note:** The recommended and default edition of Grafana is Grafana Enterprise. It is free and includes all the features of the OSS edition. Additionally, you have the option to upgrade to the [full Enterprise feature set](/products/enterprise/?utm_source=grafana-install-page), which includes support for [Enterprise plugins](/grafana/plugins/?enterprise=1&utcm_source=grafana-install-page). -The default images for Grafana are created using the Alpine Linux project and can be found in the Alpine official image. For instructions on configuring a Docker image for Grafana, refer to [Configure a Grafana Docker image]({{< relref "../../configure-docker" >}}). +The default images for Grafana are created using the Alpine Linux project and can be found in the Alpine official image. For instructions on configuring a Docker image for Grafana, refer to [Configure a Grafana Docker image](../../configure-docker/). ## Run Grafana via Docker CLI @@ -114,7 +114,7 @@ docker run -d -p 3000:3000 --name=grafana \ ### Use environment variables to configure Grafana -Grafana supports specifying custom configuration settings using [environment variables]({{< relref "../../../setup-grafana/configure-grafana#override-configuration-with-environment-variables" >}}). +Grafana supports specifying custom configuration settings using [environment variables](../../configure-grafana/#override-configuration-with-environment-variables). ```bash # enable debug logs @@ -128,7 +128,7 @@ docker run -d -p 3000:3000 --name=grafana \ You can install plugins in Grafana from the official and community [plugins page](/grafana/plugins) or by using a custom URL to install a private plugin. These plugins allow you to add new visualization types, data sources, and applications to help you better visualize your data. -Grafana currently supports three types of plugins: panel, data source, and app. For more information on managing plugins, refer to [Plugin Management]({{< relref "../../../administration/plugin-management" >}}). +Grafana currently supports three types of plugins: panel, data source, and app. For more information on managing plugins, refer to [Plugin Management](../../../administration/plugin-management/). To install plugins in the Docker container, complete the following steps: @@ -150,7 +150,7 @@ To install plugins in the Docker container, complete the following steps: ```bash docker run -d -p 3000:3000 --name=grafana \ - -e "GF_PLUGINS_PREINSTALL=grafana-clock-panel 1.0.1" \ + -e "GF_PLUGINS_PREINSTALL=grafana-clock-panel@1.0.1" \ grafana/grafana-enterprise ``` @@ -368,12 +368,12 @@ volumes: ## Next steps -Refer to the [Getting Started]({{< relref "../../../getting-started/build-first-dashboard" >}}) guide for information about logging in, setting up data sources, and so on. +Refer to the [Getting Started](../../../getting-started/build-first-dashboard/) guide for information about logging in, setting up data sources, and so on. ## Configure Docker image -Refer to [Configure a Grafana Docker image]({{< relref "../../configure-docker" >}}) page for details on options for customizing your environment, logging, database, and so on. +Refer to [Configure a Grafana Docker image](../../configure-docker/) page for details on options for customizing your environment, logging, database, and so on. ## Configure Grafana -Refer to the [Configuration]({{< relref "../../configure-grafana" >}}) page for details on options for customizing your environment, logging, database, and so on. +Refer to the [Configuration](../../configure-grafana/) page for details on options for customizing your environment, logging, database, and so on. diff --git a/docs/sources/setup-grafana/installation/mac/index.md b/docs/sources/setup-grafana/installation/mac/index.md index 55d447c17ae..f4c3f5d7342 100644 --- a/docs/sources/setup-grafana/installation/mac/index.md +++ b/docs/sources/setup-grafana/installation/mac/index.md @@ -87,4 +87,4 @@ Alternatively, watch the Grafana for Beginners video below: ## Next steps -- [Start the Grafana server]({{< relref "../../start-restart-grafana" >}}) +- [Start the Grafana server](../../start-restart-grafana/) diff --git a/docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md b/docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md index 2a24eadc392..66e02b66f66 100644 --- a/docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md +++ b/docs/sources/setup-grafana/installation/redhat-rhel-fedora/index.md @@ -32,15 +32,15 @@ If you install from the RPM repository, then Grafana is automatically updated ev | Grafana OSS | grafana | `https://rpm.grafana.com` | | Grafana OSS (Beta) | grafana | `https://rpm-beta.grafana.com` | -{{% admonition type="note" %}} +{{< admonition type="note" >}} Grafana Enterprise is the recommended and default edition. It is available for free and includes all the features of the OSS edition. You can also upgrade to the [full Enterprise feature set](/products/enterprise/?utm_source=grafana-install-page), which has support for [Enterprise plugins](/grafana/plugins/?enterprise=1&utcm_source=grafana-install-page). -{{% /admonition %}} +{{< /admonition >}} To install Grafana from the RPM repository, complete the following steps: -{{% admonition type="note" %}} +{{< admonition type="note" >}} If you wish to install beta versions of Grafana, substitute the repository URL for the beta URL listed above. -{{% /admonition %}} +{{< /admonition >}} 1. Import the GPG key: @@ -96,6 +96,8 @@ If you install Grafana manually using YUM or RPM, then you must manually update ## Install Grafana as a standalone binary +If you install Grafana manually using the standalone binaries, then you must manually update Grafana for each new version. + Complete the following steps to install Grafana using the standalone binaries: 1. Navigate to the [Grafana download page](/grafana/download). @@ -103,10 +105,70 @@ Complete the following steps to install Grafana using the standalone binaries: - The most recent Grafana version is selected by default. - The **Version** field displays only tagged releases. If you want to install a nightly build, click **Nightly Builds** and then select a version. 1. Select an **Edition**. - - **Enterprise:** This is the recommended version. It is functionally identical to the open-source version but includes features you can unlock with a license if you so choose. + - **Enterprise:** This is the recommended version. It is functionally identical to the open source version but includes features you can unlock with a license if you so choose. - **Open Source:** This version is functionally identical to the Enterprise version, but you will need to download the Enterprise version if you want Enterprise features. 1. Depending on which system you are running, click the **Linux** or **ARM** tab on the [download page](/grafana/download). 1. Copy and paste the code from the [download page](/grafana/download) page into your command line and run. +1. Create a user account for Grafana on your system: + + ```shell + sudo useradd -r -s /bin/false grafana + ``` + +1. Move the unpacked binary to `/usr/local/grafana`: + + ```shell + sudo mv /usr/local/grafana + ``` + +1. Change the owner of `/usr/local/grafana` to Grafana users: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. Create a Grafana server systemd unit file: + + ```shell + sudo touch /etc/systemd/system/grafana-server.service + ``` + +1. Add the following to the unit file in a text editor of your choice: + + ```ini + [Unit] + Description=Grafana Server + After=network.target + + [Service] + Type=simple + User=grafana + Group=users + ExecStart=/usr/local/grafana/bin/grafana server --config=/usr/local/grafana/conf/grafana.ini --homepath=/usr/local/grafana + Restart=on-failure + + [Install] + WantedBy=multi-user.target + ``` + +1. Use the binary to manually start the Grafana server: + + ```shell + /usr/local/grafana/bin/grafana-server --homepath /usr/local/grafana + ``` + + {{< admonition type="note" >}} + Manually invoking the binary in this step automatically creates the `/usr/local/grafana/data` directory, which needs to be created and configured before the installation can be considered complete. + {{< /admonition >}} + +1. Press `CTRL+C` to stop the Grafana server. +1. Change the owner of `/usr/local/grafana` to Grafana users again to apply the ownership to the newly created `/usr/local/grafana/data` directory: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. [Configure the Grafana server to start at boot time using systemd](../../start-restart-grafana/#configure-the-grafana-server-to-start-at-boot-using-systemd). ## Uninstall on RHEL or Fedora @@ -144,4 +206,4 @@ To uninstall Grafana, run the following commands in a terminal window: ## Next steps -Refer to [Start the Grafana server]({{< relref "../../start-restart-grafana" >}}). +Refer to [Start the Grafana server](../../start-restart-grafana/). diff --git a/docs/sources/setup-grafana/installation/suse-opensuse/index.md b/docs/sources/setup-grafana/installation/suse-opensuse/index.md index 48b505ba52d..1fb76c24104 100644 --- a/docs/sources/setup-grafana/installation/suse-opensuse/index.md +++ b/docs/sources/setup-grafana/installation/suse-opensuse/index.md @@ -30,9 +30,9 @@ If you install from the RPM repository, then Grafana is automatically updated ev | Grafana Enterprise | grafana-enterprise | `https://rpm.grafana.com` | | Grafana OSS | grafana | `https://rpm.grafana.com` | -{{% admonition type="note" %}} +{{< admonition type="note" >}} Grafana Enterprise is the recommended and default edition. It is available for free and includes all the features of the OSS edition. You can also upgrade to the [full Enterprise feature set](/products/enterprise/?utm_source=grafana-install-page), which has support for [Enterprise plugins](/grafana/plugins/?enterprise=1&utcm_source=grafana-install-page). -{{% /admonition %}} +{{< /admonition >}} To install Grafana using the RPM repository, complete the following steps: @@ -84,6 +84,8 @@ If you install Grafana manually using RPM, then you must manually update Grafana ## Install Grafana as a standalone binary +If you install Grafana manually using the standalone binaries, then you must manually update Grafana for each new version. + Complete the following steps to install Grafana using the standalone binaries: 1. Navigate to the [Grafana download page](/grafana/download). @@ -91,10 +93,70 @@ Complete the following steps to install Grafana using the standalone binaries: - The most recent Grafana version is selected by default. - The **Version** field displays only tagged releases. If you want to install a nightly build, click **Nightly Builds** and then select a version. 1. Select an **Edition**. - - **Enterprise:** This is the recommended version. It is functionally identical to the open-source version but includes features you can unlock with a license if you so choose. + - **Enterprise:** This is the recommended version. It is functionally identical to the open source version but includes features you can unlock with a license if you so choose. - **Open Source:** This version is functionally identical to the Enterprise version, but you will need to download the Enterprise version if you want Enterprise features. 1. Depending on which system you are running, click the **Linux** or **ARM** tab on the [download page](/grafana/download). 1. Copy and paste the code from the [download page](/grafana/download) into your command line and run. +1. Create a user account for Grafana on your system: + + ```shell + sudo useradd -r -s /bin/false grafana + ``` + +1. Move the unpacked binary to `/usr/local/grafana`: + + ```shell + sudo mv /usr/local/grafana + ``` + +1. Change the owner of `/usr/local/grafana` to Grafana users: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. Create a Grafana server systemd unit file: + + ```shell + sudo touch /etc/systemd/system/grafana-server.service + ``` + +1. Add the following to the unit file in a text editor of your choice: + + ```ini + [Unit] + Description=Grafana Server + After=network.target + + [Service] + Type=simple + User=grafana + Group=users + ExecStart=/usr/local/grafana/bin/grafana server --config=/usr/local/grafana/conf/grafana.ini --homepath=/usr/local/grafana + Restart=on-failure + + [Install] + WantedBy=multi-user.target + ``` + +1. Use the binary to manually start the Grafana server: + + ```shell + /usr/local/grafana/bin/grafana-server --homepath /usr/local/grafana + ``` + + {{< admonition type="note" >}} + Manually invoking the binary in this step automatically creates the `/usr/local/grafana/data` directory, which needs to be created and configured before the installation can be considered complete. + {{< /admonition >}} + +1. Press `CTRL+C` to stop the Grafana server. +1. Change the owner of `/usr/local/grafana` to Grafana users again to apply the ownership to the newly created `/usr/local/grafana/data` directory: + + ```shell + sudo chown -R grafana:users /usr/local/grafana + ``` + +1. [Configure the Grafana server to start at boot time using systemd](https://grafana.com/docs/grafana/latest/setup-grafana/start-restart-grafana/#configure-the-grafana-server-to-start-at-boot-using-systemd). ## Uninstall on SUSE or openSUSE @@ -132,4 +194,4 @@ To uninstall Grafana, run the following commands in a terminal window: ## Next steps -Refer to [Start the Grafana server]({{< relref "../../start-restart-grafana" >}}). +Refer to [Start the Grafana server](../../start-restart-grafana/). diff --git a/docs/sources/setup-grafana/installation/windows/index.md b/docs/sources/setup-grafana/installation/windows/index.md index 11aca8e3723..e5673ea51cb 100644 --- a/docs/sources/setup-grafana/installation/windows/index.md +++ b/docs/sources/setup-grafana/installation/windows/index.md @@ -44,7 +44,7 @@ You install Grafana using the Windows installer or using the standalone Windows Start Grafana by executing `grafana-server.exe`, located in the `bin` directory, preferably from the command line. If you want to run Grafana as a Windows service, then download [NSSM](https://nssm.cc/). It is very easy to add Grafana as a Windows service using that tool. -1. To run Grafana, open your browser and go to the Grafana port (http://localhost:3000/ is default) and then follow the instructions in [Getting Started]({{< relref "../../../getting-started/build-first-dashboard" >}}). +1. To run Grafana, open your browser and go to the Grafana port (http://localhost:3000/ is default) and then follow the instructions in [Getting Started](../../../getting-started/build-first-dashboard/). > **Note:** The default Grafana port is `3000`. This port might require extra permissions on Windows. If it does not appear in the default port, you can change the port number. @@ -64,4 +64,4 @@ Start Grafana by executing `grafana-server.exe`, located in the `bin` directory, ## Next steps -- [Start the Grafana server]({{< relref "../../start-restart-grafana" >}}) +- [Start the Grafana server](../../start-restart-grafana/) diff --git a/docs/sources/setup-grafana/set-up-for-high-availability.md b/docs/sources/setup-grafana/set-up-for-high-availability.md index b36b64f1dd8..2db5cdba95b 100644 --- a/docs/sources/setup-grafana/set-up-for-high-availability.md +++ b/docs/sources/setup-grafana/set-up-for-high-availability.md @@ -37,13 +37,13 @@ Before you complete the following tasks, configure a MySQL or Postgres database ## Configure multiple Grafana servers to use the same database -Once you have a Postgres or MySQL database available, you can configure your multiple Grafana instances to use a shared backend database. Grafana has default and custom configuration files, and you can update the database settings by updating your custom configuration file as described in the [[database]]({{< relref "./configure-grafana#database" >}}). Once configured to use a shared database, your multiple Grafana instances will persist all long-term data in that database. +Once you have a Postgres or MySQL database available, you can configure your multiple Grafana instances to use a shared backend database. Grafana has default and custom configuration files, and you can update the database settings by updating your custom configuration file as described in the [[database]](../configure-grafana/#database). Once configured to use a shared database, your multiple Grafana instances will persist all long-term data in that database. ## Alerting high availability Grafana Alerting provides a high availability mode. It preserves the semantics of legacy dashboard alerting by executing all alerts on every server and by sending notifications only once per alert. Load distribution between servers is not supported at this time. -For further information and instructions on setting up alerting high availability, refer to [Enable alerting high availability]({{< relref "../alerting/set-up/configure-high-availability" >}}). +For further information and instructions on setting up alerting high availability, refer to [Enable alerting high availability](../../alerting/set-up/configure-high-availability/). **Legacy dashboard alerts** @@ -51,7 +51,7 @@ Legacy Grafana Alerting supports a limited form of high availability. In this mo ## Grafana Live -Grafana Live works with limitations in highly available setup. For details, refer to the [Configure Grafana Live HA setup]({{< relref "./set-up-grafana-live#configure-grafana-live-ha-setup" >}}). +Grafana Live works with limitations in highly available setup. For details, refer to the [Configure Grafana Live HA setup](../set-up-grafana-live/#configure-grafana-live-ha-setup). ## User sessions diff --git a/docs/sources/setup-grafana/set-up-grafana-live.md b/docs/sources/setup-grafana/set-up-grafana-live.md index db747f4652b..b2d1c605384 100644 --- a/docs/sources/setup-grafana/set-up-grafana-live.md +++ b/docs/sources/setup-grafana/set-up-grafana-live.md @@ -29,9 +29,9 @@ By `real-time`, we indicate a soft real-time. Due to network latencies, garbage ## Concepts -Grafana Live sends data to clients over persistent WebSocket connection. Grafana frontend subscribes on channels to receive data which was published into that channel – in other words PUB/SUB mechanics is used. All subscriptions on a page multiplexed inside a single WebSocket connection. There are some rules regarding Live channel names – see [Grafana Live channel]({{< relref "#grafana-live-channel" >}}). +Grafana Live sends data to clients over persistent WebSocket connection. Grafana frontend subscribes on channels to receive data which was published into that channel – in other words PUB/SUB mechanics is used. All subscriptions on a page multiplexed inside a single WebSocket connection. There are some rules regarding Live channel names – see [Grafana Live channel](#grafana-live-channel). -Handling persistent connections like WebSocket in scale may require operating system and infrastructure tuning. That's why by default Grafana Live supports 100 simultaneous connections max. For more details on how to tune this limit, refer to [Live configuration section]({{< relref "#configure-grafana-live" >}}). +Handling persistent connections like WebSocket in scale may require operating system and infrastructure tuning. That's why by default Grafana Live supports 100 simultaneous connections max. For more details on how to tune this limit, refer to [Live configuration section](#configure-grafana-live). ## Features @@ -99,7 +99,7 @@ Grafana Live uses persistent connections (WebSocket at the moment) to deliver re WebSocket is a persistent connection that starts with an HTTP Upgrade request (using the same HTTP port as the rest of Grafana) and then switches to a TCP mode where WebSocket frames can travel in both directions between a client and a server. Each logged-in user opens a WebSocket connection – one per browser tab. -The number of maximum WebSocket connections users can establish with Grafana is limited to 100 by default. See [max_connections]({{< relref "./configure-grafana#max_connections" >}}) option. +The number of maximum WebSocket connections users can establish with Grafana is limited to 100 by default. See [max_connections](../configure-grafana/#max_connections) option. In case you want to increase this limit, ensure that your server and infrastructure allow handling more connections. The following sections discuss several common problems which could happen when managing persistent connections, in particular WebSocket connections. @@ -107,9 +107,9 @@ In case you want to increase this limit, ensure that your server and infrastruct To avoid hijacking of WebSocket connection Grafana Live checks the Origin request header sent by a client in an HTTP Upgrade request. Requests without Origin header pass through without any origin check. -By default, Live accepts connections with Origin header that matches configured [root_url]({{< relref "./configure-grafana#root_url" >}}) (which is a public Grafana URL). +By default, Live accepts connections with Origin header that matches configured [root_url](../configure-grafana/#root_url) (which is a public Grafana URL). -It is possible to provide a list of additional origin patterns to allow WebSocket connections from. This can be achieved using the [allowed_origins]({{< relref "./configure-grafana#allowed_origins" >}}) option of Grafana Live configuration. +It is possible to provide a list of additional origin patterns to allow WebSocket connections from. This can be achieved using the [allowed_origins](../configure-grafana/#allowed_origins) option of Grafana Live configuration. #### Resource usage @@ -215,7 +215,7 @@ ha_engine = redis ha_engine_address = 127.0.0.1:6379 ``` -For additional information, refer to the [ha_engine]({{< relref "./configure-grafana#ha_engine" >}}) and [ha_engine_address]({{< relref "./configure-grafana#ha_engine_address" >}}) options. +For additional information, refer to the [ha_engine](../configure-grafana/#ha_engine) and [ha_engine_address](../configure-grafana/#ha_engine_address) options. After running: diff --git a/docs/sources/setup-grafana/set-up-grafana-monitoring.md b/docs/sources/setup-grafana/set-up-grafana-monitoring.md index 5422e4f7325..1cf7563fd45 100644 --- a/docs/sources/setup-grafana/set-up-grafana-monitoring.md +++ b/docs/sources/setup-grafana/set-up-grafana-monitoring.md @@ -24,13 +24,13 @@ Grafana can emit Jaeger or OpenTelemetry Protocol (OTLP) traces for its HTTP API All HTTP endpoints are logged evenly (annotations, dashboard, tags, and so on). When a trace ID is propagated, it is reported with operation 'HTTP /datasources/proxy/:id/\*'. -Refer to [Configuration's OpenTelemetry section]({{< relref "./configure-grafana#tracingopentelemetry" >}}) for a reference of tracing options available in Grafana. +Refer to [Configuration's OpenTelemetry section](../configure-grafana/#tracingopentelemetry) for a reference of tracing options available in Grafana. ## View Grafana internal metrics Grafana collects some metrics about itself internally. Grafana supports pushing metrics to Graphite or exposing them to be scraped by Prometheus. -For more information about configuration options related to Grafana metrics, refer to [metrics]({{< relref "./configure-grafana#metrics" >}}) and [metrics.graphite]({{< relref "./configure-grafana#metricsgraphite" >}}) in [Configuration]({{< relref "./configure-grafana" >}}). +For more information about configuration options related to Grafana metrics, refer to [metrics](../configure-grafana/#metrics) and [metrics.graphite](../configure-grafana/#metricsgraphite) in [Configuration](../configure-grafana/). ### Available metrics diff --git a/docs/sources/setup-grafana/set-up-https.md b/docs/sources/setup-grafana/set-up-https.md index 20ce98bb2a0..a8e564a3baf 100644 --- a/docs/sources/setup-grafana/set-up-https.md +++ b/docs/sources/setup-grafana/set-up-https.md @@ -48,13 +48,13 @@ This section shows you how to use `openssl` tooling to generate all necessary fi 1. Run the following command to generate a 2048-bit RSA private key, which is used to decrypt traffic: ```bash - $ sudo openssl genrsa -out /etc/grafana/grafana.key 2048 + sudo openssl genrsa -out /etc/grafana/grafana.key 2048 ``` 1. Run the following command to generate a certificate, using the private key from the previous step. ```bash - $ sudo openssl req -new -key /etc/grafana/grafana.key -out /etc/grafana/grafana.csr + sudo openssl req -new -key /etc/grafana/grafana.key -out /etc/grafana/grafana.csr ``` When prompted, answer the questions, which might include your fully-qualified domain name, email address, country code, and others. The following example is similar to the prompts you will see. @@ -209,7 +209,7 @@ To adjust permissions, perform the following steps: $ sudo chgrp -R grafana /etc/letsencrypt/* $ sudo chmod -R g+rx /etc/letsencrypt/* $ sudo chgrp -R grafana /etc/grafana/grafana.crt /etc/grafana/grafana.key - $ sudo chmod 400 /etc/grafana/grafana.crt /etc/grafana/grafana.key + $ sudo chmod 440 /etc/grafana/grafana.crt /etc/grafana/grafana.key ``` 1. Run the following command to verify that the `grafana` group can read the symlinks: @@ -224,7 +224,7 @@ To adjust permissions, perform the following steps: ## Configure Grafana HTTPS and restart Grafana -In this section you edit the `grafana.ini` file so that it includes the certificate you created. If you need help identifying where to find this file, or what each key means, refer to [Configuration file location]({{< relref "./configure-grafana#configuration-file-location" >}}). +In this section you edit the `grafana.ini` file so that it includes the certificate you created. If you need help identifying where to find this file, or what each key means, refer to [Configuration file location](../configure-grafana/#configuration-file-location). To configure Grafana HTTPS and restart Grafana, complete the following steps. @@ -244,7 +244,9 @@ To configure Grafana HTTPS and restart Grafana, complete the following steps. > **Note**: The standard port for SSL traffic is 443, which you can use instead of Grafana's default port 3000. This change might require additional operating system privileges or configuration to bind to lower-numbered privileged ports. -1. [Restart the Grafana server]({{< relref "./start-restart-grafana#linux" >}}) using `systemd`, `init.d`, or the binary as appropriate for your environment. +1. Optional. From Grafana v11.2, edit the `cert_pass` configuration option with the decryption password if you are using encrypted certificates. + +1. [Restart the Grafana server](../start-restart-grafana/#linux) using `systemd`, `init.d`, or the binary as appropriate for your environment. ## Troubleshooting diff --git a/docs/sources/setup-grafana/sign-in-to-grafana.md b/docs/sources/setup-grafana/sign-in-to-grafana.md index d33ea496821..1d8d240f328 100644 --- a/docs/sources/setup-grafana/sign-in-to-grafana.md +++ b/docs/sources/setup-grafana/sign-in-to-grafana.md @@ -14,13 +14,13 @@ This topic describes how to sign in to Grafana. ## Before you begin -- [Install Grafana]({{< relref "./installation" >}}) +- [Install Grafana](../installation/) ## Steps To sign in to Grafana for the first time, follow these steps: -1. Open your web browser and go to root URL specified in [Grafana configuration file]({{< relref "./configure-grafana" >}}). +1. Open your web browser and go to root URL specified in [Grafana configuration file](../configure-grafana/). Unless you have configured Grafana differently, it is set to use `http://localhost:3000` by default. diff --git a/docs/sources/setup-grafana/start-restart-grafana.md b/docs/sources/setup-grafana/start-restart-grafana.md index 49f99a2cf30..6e1db25203c 100644 --- a/docs/sources/setup-grafana/start-restart-grafana.md +++ b/docs/sources/setup-grafana/start-restart-grafana.md @@ -210,5 +210,5 @@ To restart Grafana: After the Grafana server is up and running, consider taking the next steps: -- Refer to [Get Started]({{< relref "../getting-started" >}}) to learn how to build your first dashboard. -- Refer to [Configuration]({{< relref "./configure-grafana" >}}) to learn about how you can customize your environment. +- Refer to [Get Started](../../getting-started/) to learn how to build your first dashboard. +- Refer to [Configuration](../configure-grafana/) to learn about how you can customize your environment. diff --git a/docs/sources/shared/alerts/alerting-provisioning-export-produces.md b/docs/sources/shared/alerts/alerting-provisioning-export-produces.md new file mode 100644 index 00000000000..032a72d96d0 --- /dev/null +++ b/docs/sources/shared/alerts/alerting-provisioning-export-produces.md @@ -0,0 +1,13 @@ +--- +title: 'Alerting Produces ' +--- + +#### Produces + +- `application/json` +- `application/yaml` +- `application/terraform+hcl` +- `text/yaml` +- `text/hcl` + +These outputs are for [file provisioning](https://grafana.com/docs/grafana//alerting/set-up/provision-alerting-resources/file-provisioning) or [Terraform provisioning](https://grafana.com/docs/grafana//alerting/set-up/provision-alerting-resources/file-provisioning), and they-including the JSON output—cannot be used to update resources via the HTTP API. diff --git a/docs/sources/shared/alerts/alerting_provisioning.md b/docs/sources/shared/alerts/alerting_provisioning.md index e928b0015da..134bd086f97 100644 --- a/docs/sources/shared/alerts/alerting_provisioning.md +++ b/docs/sources/shared/alerts/alerting_provisioning.md @@ -14,7 +14,12 @@ For more information on the differences between Grafana-managed and data source- ## Grafana-managed endpoints -Note that the JSON format from most of the following endpoints is not fully compatible with [provisioning via configuration JSON files](https://grafana.com/docs/grafana//alerting/set-up/provision-alerting-resources/file-provisioning/). +{{< admonition type="note" >}} +In the Alerting provisioning HTTP API, the endpoints use a JSON format that differs from the format returned by the `export` endpoints. + +The `export` endpoints allow you to export alerting resources in a JSON format suitable for [provisioning via files](https://grafana.com/docs/grafana//alerting/set-up/provision-alerting-resources/file-provisioning/). However, this format cannot be used to update resources via the HTTP API. + +{{< /admonition >}} ### Alert rules @@ -373,16 +378,21 @@ Content-Type: application/json ### Edit resources in the Grafana UI -By default, you cannot edit API-provisioned alerting resources in Grafana. To enable editing these resources in the Grafana UI, add the `X-Disable-Provenance` header to the following requests in the API: +By default, you cannot edit API-provisioned alerting resources in Grafana. + +To enable editing these resources in the Grafana UI, add the **`X-Disable-Provenance: true`** header to the following API requests: - `POST /api/v1/provisioning/alert-rules` -- `PUT /api/v1/provisioning/folder/{FolderUID}/rule-groups/{Group}` (calling this endpoint will change provenance for all alert rules within the alert group) +- `PUT /api/v1/provisioning/folder/{FolderUID}/rule-groups/{Group}` _(This endpoint changes provenance for all alert rules in the alert group)_ + - `POST /api/v1/provisioning/contact-points` - `POST /api/v1/provisioning/mute-timings` -- `PUT /api/v1/provisioning/policies` - `PUT /api/v1/provisioning/templates/{name}` +- `PUT /api/v1/provisioning/policies` -To reset the notification policy tree to the default and unlock it for editing in the Grafana UI, use the `DELETE /api/v1/provisioning/policies` endpoint. +To reset the notification policy tree to the default and unlock it for editing in the Grafana UI, use: + +- `DELETE /api/v1/provisioning/policies` ## Data source-managed resources @@ -408,10 +418,10 @@ DELETE /api/v1/provisioning/alert-rules/:uid {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ------ | -------- | --------- | :------: | ------- | --------------------------------------------------------- | -| UID | `path` | string | `string` | | ✓ | | Alert rule UID | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ------ | ------- | :------: | ------- | --------------------------------------------------------- | +| `UID` | path | string | string | ✓ | | Alert rule UID | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | {{% /responsive-table %}} @@ -437,9 +447,9 @@ DELETE /api/v1/provisioning/contact-points/:uid #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ---- | ------ | ------ | -------- | --------- | :------: | ------- | ------------------------------------------ | -| UID | `path` | string | `string` | | ✓ | | UID is the contact point unique identifier | +| Name | Source | Type | Go type | Required | Default | Description | +| ----- | ------ | ------ | ------- | :------: | ------- | ------------------------------------------ | +| `UID` | path | string | string | ✓ | | UID is the contact point unique identifier | #### All responses @@ -463,10 +473,10 @@ DELETE /api/v1/provisioning/mute-timings/:name #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ------- | ------- | ------ | -------- | --------- | :------: | ------- | ------------------------------------------------------------------------------------------------------------- | -| name | `path` | string | `string` | | ✓ | | Mute timing name | -| version | `query` | string | `string` | | | | Current version of the resource. Used for optimistic concurrency validation. Keep empty to bypass validation. | +| Name | Source | Type | Go type | Required | Default | Description | +| --------- | ------ | ------ | ------- | :------: | ------- | ------------------------------------------------------------------------------------------------------------- | +| `name` | path | string | string | ✓ | | Mute timing name | +| `version` | query | string | string | | | Current version of the resource. Used for optimistic concurrency validation. Keep empty to bypass validation. | #### All responses @@ -499,10 +509,10 @@ DELETE /api/v1/provisioning/templates/:name #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ------- | ------- | ------ | -------- | --------- | :------: | ------- | ------------------------------------------------------------------------------------------------------------- | -| name | `path` | string | `string` | | ✓ | | Name of the template group | -| version | `query` | string | `string` | | | | Current version of the resource. Used for optimistic concurrency validation. Keep empty to bypass validation. | +| Name | Source | Type | Go type | Required | Default | Description | +| --------- | ------ | ------ | ------- | :------: | ------- | ------------------------------------------------------------------------------------------------------------- | +| `name` | path | string | string | ✓ | | Name of the template group | +| `version` | query | string | string | | | Current version of the resource. Used for optimistic concurrency validation. Keep empty to bypass validation. | #### All responses @@ -535,9 +545,9 @@ GET /api/v1/provisioning/alert-rules/:uid #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ---- | ------ | ------ | -------- | --------- | :------: | ------- | -------------- | -| UID | `path` | string | `string` | | ✓ | | Alert rule UID | +| Name | Source | Type | Go type | Required | Default | Description | +| ----- | ------ | ------ | ------- | :------: | ------- | -------------- | +| `UID` | path | string | string | ✓ | | Alert rule UID | #### All responses @@ -568,21 +578,15 @@ Status: Not Found GET /api/v1/provisioning/alert-rules/:uid/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| UID | `path` | string | `string` | | ✓ | | Alert rule UID | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `UID` | path | string | string | ✓ | | Alert rule UID | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -615,10 +619,10 @@ GET /api/v1/provisioning/folder/:folderUid/rule-groups/:group #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| --------- | ------ | ------ | -------- | --------- | :------: | ------- | ----------- | -| FolderUID | `path` | string | `string` | | ✓ | | | -| Group | `path` | string | `string` | | ✓ | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ----------- | ------ | ------ | ------- | :------: | ------- | ----------- | +| `FolderUID` | path | string | string | ✓ | | | +| `Group` | path | string | string | ✓ | | | #### All responses @@ -649,22 +653,16 @@ Status: Not Found GET /api/v1/provisioning/folder/:folderUid/rule-groups/:group/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| --------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| FolderUID | `path` | string | `string` | | ✓ | | | -| Group | `path` | string | `string` | | ✓ | | | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ----------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `FolderUID` | path | string | string | ✓ | | | +| `Group` | path | string | string | ✓ | | | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -717,20 +715,14 @@ Status: OK GET /api/v1/provisioning/alert-rules/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -763,9 +755,9 @@ GET /api/v1/provisioning/contact-points #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ---- | ------- | ------ | -------- | --------- | :------: | ------- | -------------- | -| name | `query` | string | `string` | | | | Filter by name | +| Name | Source | Type | Go type | Required | Default | Description | +| ------ | ------ | ------ | ------- | :------: | ------- | -------------- | +| `name` | query | string | string | | | Filter by name | #### All responses @@ -789,22 +781,16 @@ Status: OK GET /api/v1/provisioning/contact-points/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| decrypt | `query` | boolean | `bool` | | | | Whether any contained secure settings should be decrypted or left redacted. Redacted settings will contain RedactedValue instead. Currently, only org admin can view decrypted secure settings. | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | -| name | `query` | string | `string` | | | | Filter by name | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `decrypt` | query | boolean | `bool` | | | Whether any contained secure settings should be decrypted or left redacted. Redacted settings will contain RedactedValue instead. Currently, only org admin can view decrypted secure settings. | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | +| `name` | query | string | string | | | Filter by name | #### All responses @@ -839,9 +825,9 @@ GET /api/v1/provisioning/mute-timings/:name #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ---- | ------ | ------ | -------- | --------- | :------: | ------- | ---------------- | -| name | `path` | string | `string` | | ✓ | | Mute timing name | +| Name | Source | Type | Go type | Required | Default | Description | +| ------ | ------ | ------ | ------- | :------: | ------- | ---------------- | +| `name` | path | string | string | ✓ | | Mute timing name | #### All responses @@ -894,20 +880,14 @@ Status: OK GET /api/v1/provisioning/mute-timings/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -940,21 +920,15 @@ Status: Forbidden GET /api/v1/provisioning/mute-timings/:name/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| name | `path` | string | `string` | | ✓ | | Mute timing name. | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `name` | path | string | string | ✓ | | Mute timing name. | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -1009,20 +983,14 @@ Status: OK GET /api/v1/provisioning/policies/export ``` -#### Produces - -- application/json -- application/yaml -- application/terraform+hcl -- text/yaml -- text/hcl +{{< docs/shared lookup="alerts/alerting-provisioning-export-produces.md" source="grafana" version="" >}} #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------- | ------- | ------- | -------- | --------- | :------: | -------- | -------------------------------------------------------------------------------------------------------------------------------------- | -| download | `query` | boolean | `bool` | | | | Whether to initiate a download of the file or not. | -| format | `query` | string | `string` | | | `"yaml"` | Format of the downloaded file, either yaml, json or hcl. Accept header can also be used, but the query parameter will take precedence. | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------- | ------ | ------- | ------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------------------------------- | +| `download` | query | boolean | `bool` | | | Whether to initiate a download of the file or not. | +| `format` | query | string | string | | `yaml` | Format of the downloaded file, either `yaml`, `json` or `hcl`. Accept header can also be used, but the query parameter will take precedence. | #### All responses @@ -1057,9 +1025,9 @@ GET /api/v1/provisioning/templates/:name #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| ---- | ------ | ------ | -------- | --------- | :------: | ------- | -------------------------- | -| name | `path` | string | `string` | | ✓ | | Name of the template group | +| Name | Source | Type | Go type | Required | Default | Description | +| ------ | ------ | ------ | ------- | :------: | ------- | -------------------------- | +| `name` | path | string | string | ✓ | | Name of the template group | #### All responses @@ -1116,10 +1084,10 @@ POST /api/v1/provisioning/alert-rules {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ----------------------------------------------- | ----------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [ProvisionedAlertRule](#provisioned-alert-rule) | `models.ProvisionedAlertRule` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ----------------------------------------------- | ----------------------------- | :------: | ------- | --------------------------------------------------------- | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [ProvisionedAlertRule](#provisioned-alert-rule) | `models.ProvisionedAlertRule` | | | | {{% /responsive-table %}} @@ -1160,10 +1128,10 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ----------------------------------------------- | ----------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [EmbeddedContactPoint](#embedded-contact-point) | `models.EmbeddedContactPoint` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ----------------------------------------------- | ----------------------------- | :------: | ------- | --------------------------------------------------------- | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [EmbeddedContactPoint](#embedded-contact-point) | `models.EmbeddedContactPoint` | | | | {{% /responsive-table %}} @@ -1202,10 +1170,10 @@ POST /api/v1/provisioning/mute-timings {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | --------------------------------------- | ------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [MuteTimeInterval](#mute-time-interval) | `models.MuteTimeInterval` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | --------------------------------------- | ------------------------- | :------: | ------- | --------------------------------------------------------- | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [MuteTimeInterval](#mute-time-interval) | `models.MuteTimeInterval` | | | | {{% /responsive-table %}} @@ -1244,11 +1212,11 @@ PUT /api/v1/provisioning/alert-rules/:uid {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ----------------------------------------------- | ----------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| UID | `path` | string | `string` | | ✓ | | Alert rule UID | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [ProvisionedAlertRule](#provisioned-alert-rule) | `models.ProvisionedAlertRule` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ----------------------------------------------- | ----------------------------- | :------: | ------- | --------------------------------------------------------- | --- | +| `UID` | path | string | string | ✓ | | Alert rule UID | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [ProvisionedAlertRule](#provisioned-alert-rule) | `models.ProvisionedAlertRule` | | | | | {{% /responsive-table %}} @@ -1287,12 +1255,12 @@ PUT /api/v1/provisioning/folder/:folderUid/rule-groups/:group {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ----------------------------------- | ----------------------- | --------- | :------: | ------- | ------------------------------------------------------------------------------------------------------- | -| FolderUID | `path` | string | `string` | | ✓ | | | -| Group | `path` | string | `string` | | ✓ | | | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [AlertRuleGroup](#alert-rule-group) | `models.AlertRuleGroup` | | | | This action is idempotent and rules included in this body will overwrite configured rules for the group | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ----------------------------------- | ----------------------- | :------: | ------- | ------------------------------------------------------------------------------------------------------- | +| `FolderUID` | path | string | string | ✓ | | | +| `Group` | path | string | string | ✓ | | | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [AlertRuleGroup](#alert-rule-group) | `models.AlertRuleGroup` | | | This action is idempotent and rules included in this body will overwrite configured rules for the group | {{% /responsive-table %}} @@ -1331,11 +1299,11 @@ PUT /api/v1/provisioning/contact-points/:uid {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ----------------------------------------------- | ----------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| UID | `path` | string | `string` | | ✓ | | UID is the contact point unique identifier | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [EmbeddedContactPoint](#embedded-contact-point) | `models.EmbeddedContactPoint` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ----------------------------------------------- | ----------------------------- | :------: | ------- | --------------------------------------------------------- | +| `UID` | path | string | string | ✓ | | UID is the contact point unique identifier | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [EmbeddedContactPoint](#embedded-contact-point) | `models.EmbeddedContactPoint` | | | | {{% /responsive-table %}} @@ -1374,11 +1342,11 @@ PUT /api/v1/provisioning/mute-timings/:name {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | --------------------------------------- | ------------------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| name | `path` | string | `string` | | ✓ | | Mute timing name | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [MuteTimeInterval](#mute-time-interval) | `models.MuteTimeInterval` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | --------------------------------------- | ------------------------- | -------- | :-----: | --------------------------------------------------------- | +| `name` | path | string | string | ✓ | | Mute timing name | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [MuteTimeInterval](#mute-time-interval) | `models.MuteTimeInterval` | | | | {{% /responsive-table %}} @@ -1426,10 +1394,10 @@ PUT /api/v1/provisioning/policies {{% responsive-table %}} -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | --------------- | -------------- | --------- | :------: | ------- | --------------------------------------------------------- | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [Route](#route) | `models.Route` | | | | The new notification routing tree to use | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | --------------- | -------------- | :------: | ------- | --------------------------------------------------------- | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [Route](#route) | `models.Route` | | | The new notification routing tree to use | {{% /responsive-table %}} @@ -1468,11 +1436,11 @@ PUT /api/v1/provisioning/templates/:name #### Parameters -| Name | Source | Type | Go type | Separator | Required | Default | Description | -| -------------------------- | -------- | ------------------------------------------------------------- | ------------------------------------ | --------- | :------: | ------- | --------------------------------------------------------- | -| name | `path` | string | `string` | | ✓ | | Name of the template group | -| X-Disable-Provenance: true | `header` | string | `string` | | | | Allows editing of provisioned resources in the Grafana UI | -| Body | `body` | [NotificationTemplateContent](#notification-template-content) | `models.NotificationTemplateContent` | | | | | +| Name | Source | Type | Go type | Required | Default | Description | +| ---------------------------- | ------ | ------------------------------------------------------------- | ------------------------------------ | -------- | :-----: | --------------------------------------------------------- | --- | +| `name` | path | string | string | ✓ | | Name of the template group | +| `X-Disable-Provenance: true` | header | string | string | | | Allows editing of provisioned resources in the Grafana UI | +| `Body` | body | [NotificationTemplateContent](#notification-template-content) | `models.NotificationTemplateContent` | | | | | {{% /responsive-table %}} @@ -1544,14 +1512,13 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| --------------------------------------------------------- | ----------------------------------------- | ------------------- | :------: | ------- | ------------------------------------------------------------------------------------------------------ | ------- | -| datasourceUid | string | `string` | | | Grafana data source unique identifier; it should be '**expr**' for a Server Side Expression operation. | | -| model | [interface{}](#interface) | `interface{}` | | | JSON is the raw JSON query and includes the above properties as well as custom properties. | | -| queryType | string | `string` | | | QueryType is an optional identifier for the type of query. | -| It can be used to distinguish different types of queries. | | -| refId | string | `string` | | | RefID is the unique identifier of the query, set by the frontend call. | | -| relativeTimeRange | [RelativeTimeRange](#relative-time-range) | `RelativeTimeRange` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------------- | ----------------------------------------- | ------------------- | :------: | ------- | -------------------------------------------------------------------------------------------------------------------- | ------- | +| `datasourceUid` | string | string | | | Grafana data source unique identifier; it should be '**expr**' for a Server Side Expression operation. | | +| `model` | [interface{}](#interface) | `interface{}` | | | JSON is the raw JSON query and includes the above properties as well as custom properties. | | +| `queryType` | string | string | | | QueryType is an optional identifier for the type of query. It can be used to distinguish different types of queries. | | +| `refId` | string | string | | | RefID is the unique identifier of the query, set by the frontend call. | | +| `relativeTimeRange` | [RelativeTimeRange](#relative-time-range) | `RelativeTimeRange` | | | | | {{% /responsive-table %}} @@ -1561,13 +1528,13 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ----------------- | ----------------------------------------- | ------------------- | :------: | ------- | ----------- | ------- | -| datasourceUid | string | `string` | | | | | -| model | [interface{}](#interface) | `interface{}` | | | | | -| queryType | string | `string` | | | | | -| refId | string | `string` | | | | | -| relativeTimeRange | [RelativeTimeRange](#relative-time-range) | `RelativeTimeRange` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------------- | ----------------------------------------- | ------------------- | :------: | ------- | ----------- | ------- | +| `datasourceUid` | string | string | | | | | +| `model` | [interface{}](#interface) | `interface{}` | | | | | +| `queryType` | string | string | | | | | +| `refId` | string | string | | | | | +| `relativeTimeRange` | [RelativeTimeRange](#relative-time-range) | `RelativeTimeRange` | | | | | {{% /responsive-table %}} @@ -1577,20 +1544,20 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ------------ | ----------------------------------------- | --------------------- | :------: | ------- | ----------- | ------- | -| annotations | map of string | `map[string]string` | | | | | -| condition | string | `string` | | | | | -| dashboardUid | string | `string` | | | | | -| data | [][AlertQueryExport](#alert-query-export) | `[]*AlertQueryExport` | | | | | -| execErrState | string | `string` | | | | | -| for | [Duration](#duration) | `Duration` | | | | | -| isPaused | boolean | `bool` | | | | | -| labels | map of string | `map[string]string` | | | | | -| noDataState | string | `string` | | | | | -| panelId | int64 (formatted integer) | `int64` | | | | | -| title | string | `string` | | | | | -| uid | string | `string` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| -------------- | ----------------------------------------- | --------------------- | :------: | ------- | ----------- | ------- | +| `annotations` | map of string | `map[string]string` | | | | | +| `condition` | string | string | | | | | +| `dashboardUid` | string | string | | | | | +| `data` | [][AlertQueryExport](#alert-query-export) | `[]*AlertQueryExport` | | | | | +| `execErrState` | string | string | | | | | +| `for` | [Duration](#duration) | Duration | | | | | +| `isPaused` | boolean | `bool` | | | | | +| `labels` | map of string | `map[string]string` | | | | | +| `noDataState` | string | string | | | | | +| `panelId` | int64 (formatted integer) | int64 | | | | | +| `title` | string | string | | | | | +| `uid` | string | string | | | | | {{% /responsive-table %}} @@ -1600,12 +1567,12 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| --------- | ------------------------------------------------- | ------------------------- | :------: | ------- | ----------- | ------- | -| folderUid | string | `string` | | | | | -| interval | int64 (formatted integer) | `int64` | | | | | -| rules | [][ProvisionedAlertRule](#provisioned-alert-rule) | `[]*ProvisionedAlertRule` | | | | | -| title | string | `string` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ----------- | ------------------------------------------------- | ------------------------- | :------: | ------- | ----------- | ------- | +| `folderUid` | string | string | | | | | +| `interval` | int64 (formatted integer) | int64 | | | | | +| `rules` | [][ProvisionedAlertRule](#provisioned-alert-rule) | `[]*ProvisionedAlertRule` | | | | | +| `title` | string | string | | | | | {{% /responsive-table %}} @@ -1615,13 +1582,13 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| -------- | --------------------------------------- | -------------------- | :------: | ------- | ----------- | ------- | -| folder | string | `string` | | | | | -| interval | [Duration](#duration) | `Duration` | | | | | -| name | string | `string` | | | | | -| orgId | int64 (formatted integer) | `int64` | | | | | -| rules | [][AlertRuleExport](#alert-rule-export) | `[]*AlertRuleExport` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ---------- | --------------------------------------- | -------------------- | :------: | ------- | ----------- | ------- | +| `folder` | string | string | | | | | +| `interval` | [Duration](#duration) | Duration | | | | | +| `name` | string | string | | | | | +| `orgId` | int64 (formatted integer) | int64 | | | | | +| `rules` | [][AlertRuleExport](#alert-rule-export) | `[]*AlertRuleExport` | | | | | {{% /responsive-table %}} @@ -1631,12 +1598,12 @@ Status: Accepted {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ------------- | --------------------------------------------------------- | ----------------------------- | :------: | ------- | ----------- | ------- | -| apiVersion | int64 (formatted integer) | `int64` | | | | | -| contactPoints | [][ContactPointExport](#contact-point-export) | `[]*ContactPointExport` | | | | | -| groups | [][AlertRuleGroupExport](#alert-rule-group-export) | `[]*AlertRuleGroupExport` | | | | | -| policies | [][NotificationPolicyExport](#notification-policy-export) | `[]*NotificationPolicyExport` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| --------------- | --------------------------------------------------------- | ----------------------------- | :------: | ------- | ----------- | ------- | +| `apiVersion` | int64 (formatted integer) | int64 | | | | | +| `contactPoints` | [][ContactPointExport](#contact-point-export) | `[]*ContactPointExport` | | | | | +| `groups` | [][AlertRuleGroupExport](#alert-rule-group-export) | `[]*AlertRuleGroupExport` | | | | | +| `policies` | [][NotificationPolicyExport](#notification-policy-export) | `[]*NotificationPolicyExport` | | | | | {{% /responsive-table %}} @@ -1644,11 +1611,11 @@ Status: Accepted **Properties** -| Name | Type | Go type | Required | Default | Description | Example | -| --------- | ------------------------------------ | ------------------- | :------: | ------- | ----------- | ------- | -| name | string | `string` | | | | | -| orgId | int64 (formatted integer) | `int64` | | | | | -| receivers | [][ReceiverExport](#receiver-export) | `[]*ReceiverExport` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ----------- | ------------------------------------ | ------------------- | :------: | ------- | ----------- | ------- | +| `name` | string | string | | | | | +| `orgId` | int64 (formatted integer) | int64 | | | | | +| `receivers` | [][ReceiverExport](#receiver-export) | `[]*ReceiverExport` | | | | | ### ContactPoints @@ -1656,9 +1623,9 @@ Status: Accepted ### Duration -| Name | Type | Go type | Default | Description | Example | -| -------- | ------ | ------- | ------- | ----------- | ------- | -| Duration | string | int64 | | | | +| Name | Type | Go type | Default | Description | Example | +| ---------- | ------ | ------- | ------- | ----------- | ------- | +| `Duration` | string | int64 | | | | ### EmbeddedContactPoint @@ -1670,14 +1637,14 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| --------------------- | ------------- | -------- | :------: | ------- | ---------------------------------------------------------------------------------- | ----------------------- | -| disableResolveMessage | boolean | `bool` | | | | `false` | -| name | string | `string` | | | `name` groups multiple contact points with the same name in the UI. | `webhook_1` | -| provenance | string | `string` | | | | | -| settings | [JSON](#json) | `JSON` | ✓ | | | | -| type | string | `string` | ✓ | | | `webhook` | -| uid | string | `string` | | | UID is the unique identifier of the contact point. The UID can be set by the user. | `my_external_reference` | +| Name | Type | Go type | Required | Default | Description | Example | +| ----------------------- | ------------- | ------- | :------: | ------- | ---------------------------------------------------------------------------------- | ----------------------- | +| `disableResolveMessage` | boolean | `bool` | | | | false | +| `name` | string | string | | | `name` groups multiple contact points with the same name in the UI. | `webhook_1` | +| `provenance` | string | string | | | | | +| `settings` | [JSON](#json) | JSON | ✓ | | | | +| `type` | string | string | ✓ | | | `webhook` | +| `uid` | string | string | | | UID is the unique identifier of the contact point. The UID can be set by the user. | `my_external_reference` | {{% /responsive-table %}} @@ -1691,9 +1658,9 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin ### MatchType -| Name | Type | Go type | Default | Description | Example | -| --------- | ------------------------- | ------- | ------- | ----------- | ------- | -| MatchType | int64 (formatted integer) | int64 | | | | +| Name | Type | Go type | Default | Description | Example | +| ----------- | ------------------------- | ------- | ------- | ----------- | ------- | +| `MatchType` | int64 (formatted integer) | int64 | | | | ### Matcher @@ -1701,11 +1668,11 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ----- | ------------------------ | ----------- | :------: | ------- | ----------- | ------- | -| Name | string | `string` | | | | | -| Type | [MatchType](#match-type) | `MatchType` | | | | | -| Value | string | `string` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------- | ------------------------ | --------- | :------: | ------- | ----------- | ------- | +| `Name` | string | string | | | | | +| `Type` | [MatchType](#match-type) | MatchType | | | | | +| `Value` | string | string | | | | | {{% /responsive-table %}} @@ -1723,11 +1690,11 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| -------------- | -------------------------------- | ----------------- | :------: | ------- | ------------------- | ------- | -| name | string | `string` | | | | | -| time_intervals | [][TimeInterval](#time-interval) | `[]*TimeInterval` | | | | | -| version | string | `string` | | | Version of resource | | +| Name | Type | Go type | Required | Default | Description | Example | +| ---------------- | -------------------------------- | ----------------- | :------: | ------- | ------------------- | ------- | +| `name` | string | string | | | | | +| `time_intervals` | [][TimeInterval](#time-interval) | `[]*TimeInterval` | | | | | +| `version` | string | string | | | Version of resource | | {{% /responsive-table %}} @@ -1751,10 +1718,10 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin **Properties** -| Name | Type | Go type | Required | Default | Description | Example | -| ------ | ---------------------------- | ------------- | :------: | ------- | ----------- | ------- | -| Policy | [RouteExport](#route-export) | `RouteExport` | | | inline | | -| orgId | int64 (formatted integer) | `int64` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| -------- | ---------------------------- | ---------------------------- | :------: | ------- | ----------- | ------- | +| `Policy` | [RouteExport](#route-export) | [RouteExport](#route-export) | | | inline | | +| `orgId` | int64 (formatted integer) | int64 | | | | | ### NotificationTemplate @@ -1762,12 +1729,12 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ---------- | ------------------------- | ------------ | :------: | ------- | ------------------- | ------- | -| name | string | `string` | | | | | -| provenance | [Provenance](#provenance) | `Provenance` | | | | | -| template | string | `string` | | | | | -| version | string | `string` | | | Version of resource | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------ | ------------------------- | ------------------------- | :------: | ------- | ------------------- | ------- | +| `name` | string | string | | | | | +| `provenance` | [Provenance](#provenance) | [Provenance](#provenance) | | | | | +| `template` | string | string | | | | | +| `version` | string | string | | | Version of resource | | {{% /responsive-table %}} @@ -1777,10 +1744,10 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| -------- | ------ | -------- | :------: | ------- | ------------------------------------------------------- | ------- | -| template | string | `string` | | | | | -| version | string | `string` | | | Version of resource. Should be empty for new templates. | | +| Name | Type | Go type | Required | Default | Description | Example | +| ---------- | ------ | ------- | :------: | ------- | ------------------------------------------------------- | ------- | +| `template` | string | string | | | | | +| `version` | string | string | | | Version of resource. Should be empty for new templates. | | {{% /responsive-table %}} @@ -1800,9 +1767,9 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin ### Provenance -| Name | Type | Go type | Default | Description | Example | -| ---------- | ------ | ------- | ------- | ----------- | ------- | -| Provenance | string | string | | | | +| Name | Type | Go type | Default | Description | Example | +| ------------ | ------ | ------- | ------- | ----------- | ------- | +| `Provenance` | string | string | | | | ### ProvisionedAlertRule @@ -1810,24 +1777,24 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ------------ | ---------------------------- | ------------------- | :------: | ------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| annotations | map of string | `map[string]string` | | | Optional key-value pairs. `dashboardUId` and `panelId` must be set together; one cannot be set without the other. | `{"runbook_url":"https://supercoolrunbook.com/page/13"}` | -| condition | string | `string` | ✓ | | | `A` | -| data | [][AlertQuery](#alert-query) | `[]*AlertQuery` | ✓ | | | `[{"datasourceUid":"__expr__","model":{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":[]},"reducer":{"params":[],"type":"avg"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1 == 1","hide":false,"intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"},"queryType":"","refId":"A","relativeTimeRange":{"from":0,"to":0}}]` | -| execErrState | string | `string` | ✓ | | | | -| folderUID | string | `string` | ✓ | | | `project_x` | -| for | [Duration](#duration) | `Duration` | ✓ | | | | -| id | int64 (formatted integer) | `int64` | | | | | -| isPaused | boolean | `bool` | | | | `false` | -| labels | map of string | `map[string]string` | | | | `{"team":"sre-team-1"}` | -| noDataState | string | `string` | ✓ | | | | -| orgID | int64 (formatted integer) | `int64` | ✓ | | | | -| provenance | [Provenance](#provenance) | `Provenance` | | | | | -| ruleGroup | string | `string` | ✓ | | | `eval_group_1` | -| title | string | `string` | ✓ | | | `Always firing` | -| uid | string | `string` | | | | | -| updated | date-time (formatted string) | `strfmt.DateTime` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------- | ---------------------------- | ------------------------- | :------: | ------- | ----------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `annotations` | map of string | `map[string]string` | | | Optional key-value pairs. `dashboardUId` and `panelId` must be set together; one cannot be set without the other. | `{"runbook_url":"https://supercoolrunbook.com/page/13"}` | +| `condition` | string | string | ✓ | | | `A` | +| `data` | [][AlertQuery](#alert-query) | `[]*AlertQuery` | ✓ | | | `[{"datasourceUid":"__expr__","model":{"conditions":[{"evaluator":{"params":[0,0],"type":"gt"},"operator":{"type":"and"},"query":{"params":[]},"reducer":{"params":[],"type":"avg"},"type":"query"}],"datasource":{"type":"__expr__","uid":"__expr__"},"expression":"1 == 1","hide":false,"intervalMs":1000,"maxDataPoints":43200,"refId":"A","type":"math"},"queryType":"","refId":"A","relativeTimeRange":{"from":0,"to":0}}]` | +| execErrState | string | string | ✓ | | | | +| `folderUID` | string | string | ✓ | | | `project_x` | +| `for` | [Duration](#duration) | [Duration](#duration) | ✓ | | | | +| `id` | int64 (formatted integer) | int64 | | | | | +| `isPaused` | boolean | `bool` | | | | `false` | +| `labels` | map of string | `map[string]string` | | | | `{"team":"sre-team-1"}` | +| `noDataState` | string | string | ✓ | | | | +| `orgID` | int64 (formatted integer) | `int64 | ✓ | | | | +| `provenance` | [Provenance](#provenance) | [Provenance](#provenance) | | | | | +| `ruleGroup` | string | string | ✓ | | | `eval_group_1` | +| `title` | string | string | ✓ | | | `Always firing` | +| `uid` | string | string | | | | | +| `updated` | date-time (formatted string) | `strfmt.DateTime` | | | | | {{% /responsive-table %}} @@ -1843,12 +1810,12 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin **Properties** -| Name | Type | Go type | Required | Default | Description | Example | -| --------------------- | -------------------------- | ------------ | :------: | ------- | ----------- | ------- | -| disableResolveMessage | boolean | `bool` | | | | | -| settings | [RawMessage](#raw-message) | `RawMessage` | | | | | -| type | string | `string` | | | | | -| uid | string | `string` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ----------------------- | -------------------------- | ---------- | :------: | ------- | ----------- | ------- | +| `disableResolveMessage` | boolean | `bool` | | | | | +| `settings` | [RawMessage](#raw-message) | RawMessage | | | | | +| `type` | string | string | | | | | +| `uid` | string | string | | | | | ### Regexp @@ -1866,10 +1833,10 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ---- | --------------------- | ---------- | :------: | ------- | ----------- | ------- | -| from | [Duration](#duration) | `Duration` | | | | | -| to | [Duration](#duration) | `Duration` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------ | --------------------- | -------- | :------: | ------- | ----------- | ------- | +| `from` | [Duration](#duration) | Duration | | | | | +| `to` | [Duration](#duration) | Duration | | | | | {{% /responsive-table %}} @@ -1882,21 +1849,21 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ------------------- | ---------------------------------- | ------------------- | :------: | ------- | --------------------------------------- | ------- | -| continue | boolean | `bool` | | | | | -| group_by | []string | `[]string` | | | | | -| group_interval | string | `string` | | | | | -| group_wait | string | `string` | | | | | -| match | map of string | `map[string]string` | | | Deprecated. Remove before v1.0 release. | | -| match_re | [MatchRegexps](#match-regexps) | `MatchRegexps` | | | | | -| matchers | [Matchers](#matchers) | `Matchers` | | | | | -| mute_time_intervals | []string | `[]string` | | | | | -| object_matchers | [ObjectMatchers](#object-matchers) | `ObjectMatchers` | | | | | -| provenance | [Provenance](#provenance) | `Provenance` | | | | | -| receiver | string | `string` | | | | | -| repeat_interval | string | `string` | | | | | -| routes | [][Route](#route) | `[]*Route` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| --------------------- | ---------------------------------- | ------------------- | :------: | ------- | --------------------------------------- | ------- | +| `continue` | boolean | `bool` | | | | | +| `group_by` | []string | `[]string` | | | | | +| `group_interval` | string | string | | | | | +| `group_wait` | string | string | | | | | +| `match` | map of string | `map[string]string` | | | Deprecated. Remove before v1.0 release. | | +| `match_re` | [MatchRegexps](#match-regexps) | `MatchRegexps` | | | | | +| `matchers` | [Matchers](#matchers) | `Matchers` | | | | | +| `mute_time_intervals` | []string | `[]string` | | | | | +| `object_matchers` | [ObjectMatchers](#object-matchers) | `ObjectMatchers` | | | | | +| `provenance` | [Provenance](#provenance) | Provenance | | | | | +| `receiver` | string | string | | | | | +| `repeat_interval` | string | string | | | | | +| `routes` | [][Route](#route) | `[]*Route` | | | | | {{% /responsive-table %}} @@ -1907,20 +1874,20 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin **Properties** -| Name | Type | Go type | Required | Default | Description | Example | -| ------------------- | ---------------------------------- | ------------------- | :------: | ------- | --------------------------------------- | ------- | -| continue | boolean | `bool` | | | | | -| group_by | []string | `[]string` | | | | | -| group_interval | string | `string` | | | | | -| group_wait | string | `string` | | | | | -| match | map of string | `map[string]string` | | | Deprecated. Remove before v1.0 release. | | -| match_re | [MatchRegexps](#match-regexps) | `MatchRegexps` | | | | | -| matchers | [Matchers](#matchers) | `Matchers` | | | | | -| mute_time_intervals | []string | `[]string` | | | | | -| object_matchers | [ObjectMatchers](#object-matchers) | `ObjectMatchers` | | | | | -| receiver | string | `string` | | | | | -| repeat_interval | string | `string` | | | | | -| routes | [][RouteExport](#route-export) | `[]*RouteExport` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| --------------------- | ---------------------------------- | ------------------- | :------: | ------- | --------------------------------------- | ------- | +| `continue` | boolean | `bool` | | | | | +| `group_by` | []string | `[]string` | | | | | +| `group_interval` | string | string | | | | | +| `group_wait` | string | string | | | | | +| `match` | map of string | `map[string]string` | | | Deprecated. Remove before v1.0 release. | | +| `match_re` | [MatchRegexps](#match-regexps) | `MatchRegexps` | | | | | +| `matchers` | [Matchers](#matchers) | `Matchers` | | | | | +| `mute_time_intervals` | []string | `[]string` | | | | | +| `object_matchers` | [ObjectMatchers](#object-matchers) | `ObjectMatchers` | | | | | +| `receiver` | string | string | | | | | +| `repeat_interval` | string | string | | | | | +| `routes` | [][RouteExport](#route-export) | `[]*RouteExport` | | | | | ### TimeInterval @@ -1931,14 +1898,14 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ------------- | -------------------------- | -------------- | :------: | ------- | ----------- | ------- | -| days_of_month | []string | `[]string` | | | | | -| location | string | `string` | | | | | -| months | []string | `[]string` | | | | | -| times | [][TimeRange](#time-range) | `[]*TimeRange` | | | | | -| weekdays | []string | `[]string` | | | | | -| years | []string | `[]string` | | | | | +| Name | Type | Go type | Required | Default | Description | Example | +| --------------- | -------------------------- | -------------- | :------: | ------- | ----------- | ------- | +| `days_of_month` | []string | []string | | | | | +| `location` | string | string | | | | | +| `months` | []string | []string | | | | | +| `times` | [][TimeRange](#time-range) | `[]*TimeRange` | | | | | +| `weekdays` | []string | []string | | | | | +| `years` | []string | []string | | | | | {{% /responsive-table %}} @@ -1950,10 +1917,10 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ---------- | ------ | -------- | :------: | ------- | ----------- | ----------------------- | -| end_time | string | `string` | | | | `"end_time": "24:00"` | -| start_time | string | `string` | | | | `"start_time": "18:00"` | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------ | ------ | ------- | :------: | ------- | ----------- | ----------------------- | +| `end_time` | string | string | | | | `"end_time": "24:00"` | +| `start_time` | string | string | | | | `"start_time": "18:00"` | {{% /responsive-table %}} @@ -1963,9 +1930,9 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ---- | ------ | -------- | :------: | ------- | ----------- | --------------- | -| msg | string | `string` | | | | `error message` | +| Name | Type | Go type | Required | Default | Description | Example | +| ----- | ------ | ------- | :------: | ------- | ----------- | --------------- | +| `msg` | string | string | | | | `error message` | {{% /responsive-table %}} @@ -1975,11 +1942,11 @@ When creating a contact point, the `EmbeddedContactPoint.name` property determin {{% responsive-table %}} -| Name | Type | Go type | Required | Default | Description | Example | -| ---------- | ---------- | ---------------- | :------: | ------- | ------------------------------------------------------------------------ | ------- | -| statusCode | string | `string` | ✓ | | HTTP Status Code | | -| messageId | string | `string` | ✓ | | Unique code of the error | | -| message | string | `string` | | | Error message | | -| extra | map of any | `map[string]any` | | | Extra information about the error. Format is specific to the error code. | | +| Name | Type | Go type | Required | Default | Description | Example | +| ------------ | ---------- | ---------------- | :------: | ------- | ------------------------------------------------------------------------ | ------- | +| `statusCode` | string | string | ✓ | | HTTP Status Code | | +| `messageId` | string | string | ✓ | | Unique code of the error | | +| `message` | string | string | | | Error message | | +| `extra` | map of any | `map[string]any` | | | Extra information about the error. Format is specific to the error code. | | {{% /responsive-table %}} diff --git a/docs/sources/shared/alerts/first-step.md b/docs/sources/shared/alerts/first-step.md index 8aa44edf357..afd760ef52e 100644 --- a/docs/sources/shared/alerts/first-step.md +++ b/docs/sources/shared/alerts/first-step.md @@ -8,7 +8,7 @@ title: TBD ## TBD -Use the instructions in [Getting started with Grafana]({{< relref "../../getting-started/getting-started/" >}}) to: +Use the instructions in [Getting started with Grafana](/docs/grafana//getting-started/getting-started/) to: - Install Grafana. - Log in to Grafana. diff --git a/docs/sources/shared/alerts/grafana-managed-alerts.md b/docs/sources/shared/alerts/grafana-managed-alerts.md index 3207be93214..77dbbf221cf 100644 --- a/docs/sources/shared/alerts/grafana-managed-alerts.md +++ b/docs/sources/shared/alerts/grafana-managed-alerts.md @@ -22,7 +22,7 @@ Alerting rules can only query backend data sources with alerting enabled: ## Metrics from the alerting engine -The alerting engine publishes some internal metrics about itself. You can read more about how Grafana publishes [internal metrics]({{< relref "../../setup-grafana/set-up-grafana-monitoring/" >}}). See also, [View alert rules and their current state]({{< relref "../../alerting/fundamentals/state-and-health/" >}}). +The alerting engine publishes some internal metrics about itself. You can read more about how Grafana publishes [internal metrics](/docs/grafana//setup-grafana/set-up-grafana-monitoring/). See also, [View alert rules and their current state](/docs/grafana//alerting/fundamentals/state-and-health/). | Metric Name | Type | Description | | --------------------------------------------------- | --------- | ---------------------------------------------------------------------------------------- | diff --git a/docs/sources/shared/alerts/note-dynamic-labels.md b/docs/sources/shared/alerts/note-dynamic-labels.md new file mode 100644 index 00000000000..d657c4249a6 --- /dev/null +++ b/docs/sources/shared/alerts/note-dynamic-labels.md @@ -0,0 +1,14 @@ +--- +labels: + products: + - oss +title: 'Note Dynamic labels' +--- + +{{% admonition type="note" %}} + +An alert instance is uniquely identified by its set of labels. + +- Avoid displaying query values in labels, as this can create numerous alert instances—one for each distinct label set. Instead, use annotations for query values. +- If a templated label's value changes, it maps to a different alert instance, and the previous instance transitions to the `No data` state when its label value is no longer present. + {{% /admonition %}} diff --git a/docs/sources/shared/alerts/table-configure-no-data-and-error.md b/docs/sources/shared/alerts/table-configure-no-data-and-error.md index 5c303f4b4ae..c906a8dc736 100644 --- a/docs/sources/shared/alerts/table-configure-no-data-and-error.md +++ b/docs/sources/shared/alerts/table-configure-no-data-and-error.md @@ -5,10 +5,10 @@ labels: title: 'Table configure no data and error' --- -| Configure | Set alert state | Description | -| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| No Data | No Data | The default option for **No Data** events.
Sets alert instance state to `No Data`.
The alert rule also creates a new alert instance `DatasourceNoData` with the name and UID of the alert rule, and UID of the datasource that returned no data as labels. | -| Error | Error | The default option for **Error** events.
Sets alert instance state to `Error`.
The alert rule also creates a new alert instance `DatasourceError` with the name and UID of the alert rule, and UID of the datasource that returned no data as labels. | -| No Data or Error | Alerting | Sets the alert instance state to `Pending` and then transitions to `Alerting` once the pending period ends. If you sent the pending period to 0, the alert instance state is immediately set to `Alerting`. | -| No Data or Error | Normal | Sets alert instance state to `Normal`. | -| No Data or Error | Keep Last State | Maintains the alert instance in its last state. Useful for mitigating temporary issues. | +| Configure | Set alert state | Description | +| ---------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| No Data | No Data | The default option for **No Data** events.
Sets alert instance state to `No Data`.
The alert rule immediately creates a new `DatasourceNoData` alert instance after evaluation, with the alert rule's name, UID, and the data source UID as labels. | +| Error | Error | The default option for **Error** events.
Sets alert instance state to `Error`.
The alert rule immediately creates a new `DatasourceError` alert instance after evaluation, with the alert rule's name, UID, and the data source UID as labels. | +| No Data or Error | Alerting | Sets the alert instance state to `Pending` and then transitions to `Alerting` once the pending period ends. If you sent the pending period to 0, the alert instance state is immediately set to `Alerting`. | +| No Data or Error | Normal | Sets alert instance state to `Normal`. | +| No Data or Error | Keep Last State | Maintains the alert instance in its last state. Useful for mitigating temporary issues. | diff --git a/docs/sources/shared/auth/intro.md b/docs/sources/shared/auth/intro.md index 92c1e0da425..06f702afc87 100644 --- a/docs/sources/shared/auth/intro.md +++ b/docs/sources/shared/auth/intro.md @@ -10,4 +10,4 @@ There are numerous authentication methods available in Grafana to verify user id You can also configure Grafana to automatically update users' roles and team memberships in Grafana based on the information returned by the auth provider integration. When deciding on an authentication method, it's important to take into account your current identity and access management system as well as the specific authentication and authorization features you require. -For a complete list of the available authentication options and the features they support, refer to [Configure authentication]({{< relref "/docs/grafana/latest/setup-grafana/configure-security/configure-authentication" >}}). +For a complete list of the available authentication options and the features they support, refer to [Configure authentication](/docs/grafana//setup-grafana/configure-security/configure-authentication). diff --git a/docs/sources/shared/datasources/sql-query-builder-macros.md b/docs/sources/shared/datasources/sql-query-builder-macros.md index 10425a73ab4..686302fee78 100644 --- a/docs/sources/shared/datasources/sql-query-builder-macros.md +++ b/docs/sources/shared/datasources/sql-query-builder-macros.md @@ -10,8 +10,6 @@ labels: You can enable macros support in the select clause to create time-series queries. -{{< docs/experimental product="Macros support in visual query builder" featureFlag="`sqlQuerybuilderFunctionParameters`" >}} - Use the **Data operations** drop-down to select a macro like `$__timeGroup` or `$__timeGroupAlias`. Select a time column from the **Column** drop-down and a time interval from the **Interval** drop-down to create a time-series query. diff --git a/docs/sources/shared/developers/authentication.md b/docs/sources/shared/developers/authentication.md index 6e5158dc46f..7c5d400303e 100644 --- a/docs/sources/shared/developers/authentication.md +++ b/docs/sources/shared/developers/authentication.md @@ -21,7 +21,7 @@ curl http://admin:admin@localhost:3000/api/org ### Service account token To create a service account token, click on **Administration** in the left-side menu, click **Users and access**, then **Service Accounts**. -For more information on how to use service account tokens, refer to the [Service Accounts]({{< relref "../../administration/service-accounts/" >}}) documentation. +For more information on how to use service account tokens, refer to the [Service Accounts](/docs/grafana//administration/service-accounts/) documentation. You use the token in all requests in the `Authorization` header, like this: diff --git a/docs/sources/shared/plugins/rename-note.md b/docs/sources/shared/plugins/rename-note.md new file mode 100644 index 00000000000..4fec1abb499 --- /dev/null +++ b/docs/sources/shared/plugins/rename-note.md @@ -0,0 +1,19 @@ +--- +headless: true +labels: + products: + - enterprise + - oss +--- + +[//]: # 'This file contains a rename note for Explore to Drilldown apps.' +[//]: # 'This shared file is included in a lot of files. Check the app docs in' +[//]: # 'drilldown-traces, drilldown-logs, drilldown-profiles, grafana, and website/grafana-cloud.' +[//]: # 'If you make changes to this file, verify that the meaning and content are not changed in any place where the file is included.' +[//]: # 'Any links should be fully qualified and not relative: /docs/grafana/ instead of ../grafana/.' + +{{< admonition type="note" >}} +The Grafana Explore apps have changed to Grafana Drilldown apps. +For example, Explore Logs is now Logs Drilldown. +To learn more, read [Grafana Drilldown apps: the improved queryless experience formerly known as the Explore apps](https://grafana.com/blog/2025/02/20/grafana-drilldown-apps-the-improved-queryless-experience-formerly-known-as-the-explore-apps/). +{{< /admonition >}} diff --git a/docs/sources/shared/preferences/some-tasks-require-permissions.md b/docs/sources/shared/preferences/some-tasks-require-permissions.md index aee8a2c4072..e805648f8f7 100644 --- a/docs/sources/shared/preferences/some-tasks-require-permissions.md +++ b/docs/sources/shared/preferences/some-tasks-require-permissions.md @@ -6,4 +6,4 @@ labels: title: Some tasks require permissions --- -Some tasks require certain permissions. For more information about roles, refer to [About users and permission]({{< relref "../../administration/manage-users-and-permissions/about-users-and-permissions/" >}}). +Some tasks require certain permissions. For more information about roles, refer to [About users and permission](/docs/grafana//administration/manage-users-and-permissions/about-users-and-permissions/). diff --git a/docs/sources/shared/visualizations/axis-options-all.md b/docs/sources/shared/visualizations/axis-options-all.md new file mode 100644 index 00000000000..e2c833ab9e2 --- /dev/null +++ b/docs/sources/shared/visualizations/axis-options-all.md @@ -0,0 +1,21 @@ +--- +title: Axis options +comments: | + This file is used in the following visualizations: time series. +--- + +Options under the **Axis** section control how the x- and y-axes are rendered. Some options don't take effect until you click outside of the field option box you're editing. You can also press `Enter`. + +| Option | Description | +| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------ | +| Time zone | Set the desired time zones to display along the x-axis. | +| [Placement](#placement) | Select the placement of the y-axis. | +| Label | Set a y-axis text label. If you have more than one y-axis, then you can assign different labels using an override. | +| Width | Set a fixed width for the axis. By default, Grafana dynamically calculates the width of an axis. | +| Show grid lines | Set the axis grid line visibility.
| +| Color | Set the color of the axis. | +| Show border | Set the axis border visibility. | +| Scale | Set the y-axis values scale.
| +| Centered zero | Set the y-axis so it's centered on zero. | +| [Soft min](#soft-min-and-soft-max) | Set a soft min to better control the y-axis limits. zero. | +| [Soft max](#soft-min-and-soft-max) | Set a soft max to better control the y-axis limits. zero. | diff --git a/docs/sources/shared/visualizations/axis-options-state-status.md b/docs/sources/shared/visualizations/axis-options-state-status.md new file mode 100644 index 00000000000..8b1bacfd78c --- /dev/null +++ b/docs/sources/shared/visualizations/axis-options-state-status.md @@ -0,0 +1,10 @@ +--- +title: Axis options +comments: | + This file is used in the following visualizations: state timeline, status history. +--- + +| Option | Description | +| --------- | ------------------------------------------------------------------------------------------------ | +| Placement | Control the visibility of series names along the y-axis or time values along the x-axis. | +| Width | Set a fixed width for the axis. By default, Grafana dynamically calculates the width of an axis. | diff --git a/docs/sources/shared/visualizations/change-axis-link.md b/docs/sources/shared/visualizations/change-axis-link.md index 22023736e4d..00256bc6967 100644 --- a/docs/sources/shared/visualizations/change-axis-link.md +++ b/docs/sources/shared/visualizations/change-axis-link.md @@ -4,4 +4,4 @@ title: Stack series link ## Axis -For full instructions, refer to [Change axis display]({{< relref "../../visualizations/time-series/change-axis-display/" >}}). +For full instructions, refer to [Change axis display](/docs/grafana//visualizations/time-series/change-axis-display/). diff --git a/docs/sources/shared/visualizations/datalink-options-1.md b/docs/sources/shared/visualizations/datalink-options-1.md new file mode 100644 index 00000000000..5cfe706abf6 --- /dev/null +++ b/docs/sources/shared/visualizations/datalink-options-1.md @@ -0,0 +1,22 @@ +--- +title: Data links and actions options +comments: | + This file is used in the following visualizations: bar gauge, gauge, pie chart, stat +--- + +Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. +You can create links that include the series name or even the value under the cursor. +To learn more, refer to [Configure data links and actions](../../configure-data-links/). + +{{< admonition type="note" >}} +Actions are not supported for this visualization. +{{< /admonition >}} + +For each data link, set the following options: + +- **Title** +- **URL** +- **Open in new tab** + +Data links for this visualization don't include the **One click** switch, however, if there's only one data link configured, that data link has single-click functionality. +If multiple data links are configured, then clicking the visualization opens a menu that displays all the data links. diff --git a/docs/sources/shared/visualizations/datalink-options-2.md b/docs/sources/shared/visualizations/datalink-options-2.md new file mode 100644 index 00000000000..b74b753b4e6 --- /dev/null +++ b/docs/sources/shared/visualizations/datalink-options-2.md @@ -0,0 +1,34 @@ +--- +title: Data links and actions options +comments: | + This file is used in the following visualizations: bar chart, candlestick, state timeline, status history, time series, trend, xy chart +--- + +_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls. +In both cases, you can carry out these tasks while maintaining the context of the source panel. + +For each data link, set the following options: + +- **Title** +- **URL** +- **Open in new tab** +- **One click** - Opens the data link with a single click. Only one data link can have **One click** enabled at a time. + +For each action, define the following API call settings: + + + +| Option | Description | +| -------------------- | ----------------------------------------------------------------- | +| Title | A human-readable label for the action that's displayed in the UI. | +| Confirmation message | A descriptive prompt to confirm or cancel the action. | +| Method | Select from **POST**, **PUT**, or **GET**. | +| URL | The request URL.

To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. | +| Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. | +| Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.

Click the **+** icon to add as many key/value pairs as you need. | +| Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. | +| Body | The body of the request. | + + + +To learn more, refer to [Configure data links and actions](../../configure-data-links/). diff --git a/docs/sources/shared/visualizations/datalink-options-3.md b/docs/sources/shared/visualizations/datalink-options-3.md new file mode 100644 index 00000000000..738a5898596 --- /dev/null +++ b/docs/sources/shared/visualizations/datalink-options-3.md @@ -0,0 +1,36 @@ +--- +title: Data links and actions options +comments: | + This file is used in the following visualizations: table +--- + +_Data links_ allow you to link to other panels, dashboards, and external resources and _actions_ let you trigger basic, unauthenticated, API calls. +In both cases, you can carry out these tasks while maintaining the context of the source panel. + +For each data link, set the following options: + +- **Title** +- **URL** +- **Open in new tab** + +Data links for this visualization don't include the **One click** switch, however, if there's only one data link configured, that data link has single-click functionality. +If multiple data links are configured, then clicking the visualization opens a menu that displays all the data links. + +For each action, define the following API call settings: + + + +| Option | Description | +| -------------------- | ----------------------------------------------------------------- | +| Title | A human-readable label for the action that's displayed in the UI. | +| Confirmation message | A descriptive prompt to confirm or cancel the action. | +| Method | Select from **POST**, **PUT**, or **GET**. | +| URL | The request URL.

To add a variable, click in the **URL** field and enter `$` or press Ctrl+Space or Cmd+Space to see a list of available variables. | +| Query parameters | **Key** and **Value** pairs. Click the **+** icon to add as many key/value pairs as you need. | +| Headers | Comprised of **Key** and **Value** pairs and a **Content-Type**.

Click the **+** icon to add as many key/value pairs as you need. | +| Content-Type | Select from the following: **application/json**, **text/plain**, **application/XML**, and **application/x-www-form-urlencoded**. | +| Body | The body of the request. | + + + +To learn more, refer to [Configure data links and actions](../../configure-data-links/). diff --git a/docs/sources/shared/visualizations/datalink-options.md b/docs/sources/shared/visualizations/datalink-options.md index e3d77551cf5..131640d86ee 100644 --- a/docs/sources/shared/visualizations/datalink-options.md +++ b/docs/sources/shared/visualizations/datalink-options.md @@ -1,10 +1,15 @@ --- -title: Data link options +title: Data links and actions options comments: | - This file is used in the following visualizations: bar chart, bar gauge, candlestick, gauge, geomap, heatmap, histogram, stat, state timeline, status history, table, time series, trend, xy chart + This file is used in the following visualizations: geomap, heatmap, histogram --- -Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. You can create links that include the series name or even the value under the cursor. +Data links allow you to link to other panels, dashboards, and external resources while maintaining the context of the source panel. +You can create links that include the series name or even the value under the cursor. + +{{< admonition type="note" >}} +Actions are not supported for this visualization. +{{< /admonition >}} For each data link, set the following options: @@ -12,4 +17,4 @@ For each data link, set the following options: - **URL** - **Open in new tab** -To learn more, refer to [Configure data links](../../configure-data-links/). +To learn more, refer to [Configure data links and actions](../../configure-data-links/). diff --git a/docs/sources/shared/visualizations/stack-series-link.md b/docs/sources/shared/visualizations/stack-series-link.md index 328f3293109..c8c92e11fe0 100644 --- a/docs/sources/shared/visualizations/stack-series-link.md +++ b/docs/sources/shared/visualizations/stack-series-link.md @@ -4,4 +4,4 @@ title: Stack series link ### Stack series -For full instructions, refer to [Graph stacked time series]({{< relref "../../visualizations/time-series/graph-time-series-stacking/" >}}). +For full instructions, refer to [Graph stacked time series](/docs/grafana//visualizations/time-series/graph-time-series-stacking/). diff --git a/docs/sources/troubleshooting/_index.md b/docs/sources/troubleshooting/_index.md index 77582c18678..0ba9820f64e 100644 --- a/docs/sources/troubleshooting/_index.md +++ b/docs/sources/troubleshooting/_index.md @@ -26,23 +26,23 @@ If you encounter an error or problem, then you can check the Grafana server log. You can enable more logging by changing log level in the Grafana configuration file. -For more information, refer to [Enable debug logging in Grafana CLI]({{< relref "../cli/#enable-debug-logging" >}}) and the [log section in Configuration]({{< relref "../setup-grafana/configure-grafana/#log" >}}). +For more information, refer to [Enable debug logging in Grafana CLI](../cli/#enable-debug-logging) and the [log section in Configuration](../setup-grafana/configure-grafana/#log). ## Troubleshoot with Dashboards Panels -If you have an issue with your Dashboard panel, you can send us debug information. For more information, refer to [Send a panel to Grafana Labs support]({{< relref "./send-panel-to-grafana-support/" >}}). +If you have an issue with your Dashboard panel, you can send us debug information. For more information, refer to [Send a panel to Grafana Labs support](send-panel-to-grafana-support/). ## Troubleshoot with support bundles If you have an issue with your Grafana instance, you can generate an archive containing information concerning the state and the configuration of the instance. -To send us a bundle for advanced support, refer to [Send a support bundle to Grafana Labs support]({{< relref "./support-bundles/" >}}). +To send us a bundle for advanced support, refer to [Send a support bundle to Grafana Labs support](support-bundles/). ## Troubleshoot transformations Order of transformations matters. If the final data output from multiple transformations looks wrong, try changing the transformation order. Each transformation transforms data returned by the previous transformation, not the original raw data. -For more information, refer to [Debug a transformation]({{< relref "../panels-visualizations/query-transform-data/transform-data/#debug-a-transformation" >}}). +For more information, refer to [Debug a transformation](../panels-visualizations/query-transform-data/transform-data/#debug-a-transformation). ## Text missing with server-side image rendering (RPM-based Linux) @@ -58,7 +58,7 @@ sudo yum install urw-fonts ## Troubleshoot backend performance -If you're experiencing backend performance problems, such as high memory or CPU usage, please refer to [Configure profiling and tracing to troubleshoot Grafana]({{< relref "../setup-grafana/configure-grafana/configure-tracing/index.md" >}}). +If you're experiencing backend performance problems, such as high memory or CPU usage, please refer to [Configure profiling and tracing to troubleshoot Grafana](../setup-grafana/configure-grafana/configure-tracing/). ## More help diff --git a/docs/sources/tutorials/alerting-get-started-pt2/index.md b/docs/sources/tutorials/alerting-get-started-pt2/index.md index bcc77632336..3beabdf0369 100644 --- a/docs/sources/tutorials/alerting-get-started-pt2/index.md +++ b/docs/sources/tutorials/alerting-get-started-pt2/index.md @@ -10,10 +10,10 @@ labels: - cloud tags: - beginner -title: Get started with Grafana Alerting - Part 2 of 4 +title: Get started with Grafana Alerting - Part 2 weight: 50 killercoda: - title: Get started with Grafana Alerting - Part 2 of 4 + title: Get started with Grafana Alerting - Part 2 description: Learn to use alert instances and route notifications by labels to contacts, building on your alerting skills in Grafana for more advanced workflows — Part 2. backend: imageid: ubuntu @@ -21,7 +21,7 @@ killercoda: -# Get started with Grafana Alerting - Part 2 of 4 +# Get started with Grafana Alerting - Part 2 The Get started with Grafana Alerting tutorial Part 2 is a continuation of [Get started with Grafana Alerting tutorial Part 1](http://www.grafana.com/tutorials/alerting-get-started/). @@ -188,7 +188,7 @@ Create a notification policy if you want to handle metrics returned by alert rul This new child policy routes alerts that match the label `device=desktop` to the Webhook contact point. -1. **Repeat the steps above to create a second child policy** to match another alert instance. For labels use: `device=mobile`. Use the Webhook integration for the contact point. Alternatively, experiment by using a different Webhook endpoint or a [different integration](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/manage-contact-points/#list-of-supported-integrations). +1. **Repeat the steps above to create a second child policy** to match another alert instance. For labels use: `device=mobile`. Use the Webhook integration for the contact point. Alternatively, experiment by using a different Webhook endpoint or a [different integration](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/manage-contact-points/#supported-contact-point-integrations). @@ -206,7 +206,7 @@ Create a notification policy if you want to handle metrics returned by alert rul This new child policy routes alerts that match the label `device=desktop` to the Webhook contact point. -1. **Repeat the steps above to create a second child policy** to match another alert instance. For labels use: `device=mobile`. Use the Webhook integration for the contact point. Alternatively, experiment by using a different Webhook endpoint or a [different integration](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/manage-contact-points/#list-of-supported-integrations). +1. **Repeat the steps above to create a second child policy** to match another alert instance. For labels use: `device=mobile`. Use the Webhook integration for the contact point. Alternatively, experiment by using a different Webhook endpoint or a [different integration](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/manage-contact-points/#supported-contact-point-integrations). {{< /docs/ignore >}} diff --git a/docs/sources/tutorials/alerting-get-started-pt3/index.md b/docs/sources/tutorials/alerting-get-started-pt3/index.md index 7445758c22b..e2c29a3acab 100644 --- a/docs/sources/tutorials/alerting-get-started-pt3/index.md +++ b/docs/sources/tutorials/alerting-get-started-pt3/index.md @@ -10,10 +10,10 @@ labels: - cloud tags: - intermediate -title: Get started with Grafana Alerting - Part 3 of 4 +title: Get started with Grafana Alerting - Part 3 weight: 60 killercoda: - title: Get started with Grafana Alerting - Part 3 of 4 + title: Get started with Grafana Alerting - Part 3 description: Learn how to group alert notifications effectively to reduce noise and streamline communication in Grafana Alerting — Part 3. backend: imageid: ubuntu @@ -37,7 +37,7 @@ refs: -# Get started with Grafana Alerting - Part 3 of 4 +# Get started with Grafana Alerting - Part 3 The Get started with Grafana Alerting tutorial Part 3 is a continuation of [Get started with Grafana Alerting tutorial Part 2](http://www.grafana.com/tutorials/alerting-get-started-pt2/). diff --git a/docs/sources/tutorials/alerting-get-started-pt4/index.md b/docs/sources/tutorials/alerting-get-started-pt4/index.md index 4ea4477e655..1b480d375b8 100644 --- a/docs/sources/tutorials/alerting-get-started-pt4/index.md +++ b/docs/sources/tutorials/alerting-get-started-pt4/index.md @@ -420,4 +420,22 @@ To deepen your understanding of Grafana’s templating, explore the following re - [**Notification template reference**](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/template-notifications/reference/): Lists the data available for use in notification templates and explores specific functions. - [**Alert rule template reference**](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/templates/reference/): Covers the specifics of creating dynamic labels and annotations for alert rules using elements such as variables and functions. +## Learn more in [Grafana Alerting Part 5](http://www.grafana.com/tutorials/alerting-get-started-pt5/) + + + +{{< admonition type="tip" >}} + +In [Get started with Grafana Alerting - Part 5](http://www.grafana.com/tutorials/alerting-get-started-pt5/) you learn how to dynamically route alerts and link them to dashboards. + +{{< /admonition >}} + + + +{{< docs/ignore >}} + +In [Get started with Grafana Alerting - Part 5](http://www.grafana.com/tutorials/alerting-get-started-pt5/) you learn how to dynamically route alerts and link them to dashboards. + +{{< /docs/ignore >}} + diff --git a/docs/sources/tutorials/alerting-get-started-pt5/index.md b/docs/sources/tutorials/alerting-get-started-pt5/index.md new file mode 100644 index 00000000000..e2049b494ca --- /dev/null +++ b/docs/sources/tutorials/alerting-get-started-pt5/index.md @@ -0,0 +1,383 @@ +--- +Feedback Link: https://github.com/grafana/tutorials/issues/new +categories: + - alerting +description: Learn how to dynamically route alerts and link them to dashboards — Part 5. +labels: + products: + - enterprise + - oss + - cloud +tags: + - intermediate +title: Get started with Grafana Alerting - Part 5 +weight: 60 +killercoda: + title: Get started with Grafana Alerting - Part 5 + description: Learn how to dynamically route alerts and link them to dashboards — Part 5. + backend: + imageid: ubuntu +--- + +# Get started with Grafana Alerting - Part 5 + + + +The Get started with Grafana Alerting tutorial Part 5 is a continuation of [Get started with Grafana Alerting tutorial Part 4](http://www.grafana.com/tutorials/alerting-get-started-pt4/). + +In this tutorial, we focus on optimizing your alerting strategy using Grafana for monitoring system health, particularly when working with [Prometheus](https://grafana.com/docs/grafana/latest/datasources/prometheus/). Imagine you are managing a web application or a fleet of servers, tracking critical metrics such as CPU, memory, and disk usage. While monitoring is essential, managing alerts allows your team to act on issues without necessarily feeling overwhelmed by the noise. + +In this tutorial you will learn how to: + +- Leverage notification policies for **dynamic routing based on query values**: Use notification policies to route alerts based on dynamically generated labels, in a way that critical alerts reach the on-call team and less urgent ones go to a general monitoring channel. +- Set **mute timings** to suppress certain alerts during maintenance or weekends. +- **Link alerts to dashboards** to provide more context to resolve issues. + + + + + + +## Before you begin + +- **Interactive learning environment** + + - Alternatively, you can [try out this example in our interactive learning environment](https://killercoda.com/grafana-labs/course/grafana/alerting-get-started-pt5/). It’s a fully configured environment with all the dependencies already installed. + +- **Grafana OSS** + - If you opt to run a Grafana stack locally, ensure you have the following applications installed: + - Docker Compose (included in Docker for Desktop for macOS and Windows) + - Git + + + +### Set up the Grafana stack + +To observe data using the Grafana stack, download and run the following files. + +1. Clone the [tutorial environment repository](https://github.com/tonypowa/grafana-prometheus-alerting-demo.git). + + ```bash + git clone https://github.com/tonypowa/grafana-prometheus-alerting-demo.git + ``` + +1. Change to the directory where you cloned the repository: + + ```bash + cd grafana-prometheus-alerting-demo + ``` + +1. Build the Grafana stack: + + + + ``` + docker compose build + ``` + + + + {{< docs/ignore >}} + + + + ```bash + docker-compose build + ``` + + + + {{< /docs/ignore >}} + +1. Bring up the containers: + + + + ``` + docker compose up -d + ``` + + + + {{< docs/ignore >}} + + + + ```bash + docker-compose up -d + ``` + + + + {{< /docs/ignore >}} + + The first time you run `docker compose up -d`, Docker downloads all the necessary resources for the tutorial. This might take a few minutes, depending on your internet connection. + + + +{{< admonition type="note" >}} +If you already have Grafana, Loki, or Prometheus running on your system, you might see errors, because the Docker image is trying to use ports that your local installations are already using. If this is the case, stop the services, then run the command again. +{{< /admonition >}} + + + +{{< docs/ignore >}} + +NOTE: + +If you already have Grafana, Loki, or Prometheus running on your system, you might see errors, because the Docker image is trying to use ports that your local installations are already using. If this is the case, stop the services, then run the command again. + +{{< /docs/ignore >}} + + + + +## Use case: Monitoring and alerting for system health with Prometheus and Grafana + +In this use case, we focus on monitoring the system's CPU, memory, and disk usage as part of a monitoring setup. This example is based on the [Grafana Prometheus Alerting Demo](https://github.com/tonypowa/grafana-prometheus-alerting-demo), which collects and visualizes system metrics via Prometheus and Grafana. + +Your team is responsible for ensuring the health of your servers, and you want to leverage advanced alerting features in Grafana to: + +- Set who should receive an alert notification based on query value. +- Suppress alerts based on query value. +- Integrate alert rules into visualizations for better context. + +### Scenario + +In the provided demo setup, you're monitoring: + +- CPU Usage. +- Memory Consumption. + +You have a mixture of critical alerts (e.g., CPU usage over `75%`) and warning alerts (e.g., memory usage over `60%`). + +At times, you also have scheduled maintenance windows, where you might temporarily suppress certain alerts during planned downtime. + + + + +## Create a visualization to monitor metrics + +To keep track of these metrics and understand system behavior across different environments, you can set up a visualization for CPU usage and memory consumption. This will make it easier to see how the system is performing and how alerts are distributed based on the environment label, including during scheduled maintenance windows. + +The time-series visualization supports alert rules to provide more context in the form of annotations and alert rule state. Follow these steps to create a visualization to monitor the application’s metrics. + +1. Log in to Grafana: + + - Navigate to [http://localhost:3000](http://localhost:3000), where Grafana should be running. + - Username and password: `admin` + +1. Create a time series panel: + + - Navigate to **Dashboards**. + - Click **New**. + - Select **New Dashboard**. + - Click **+ Add visualization**. + - Select **Prometheus** as the data source (provided with the demo). + - Enter a title for your panel, e.g., **CPU and Memory Usage**. + +1. Add queries for metrics: + + - In the query area, copy and paste the following PromQL query: + + ** switch to **Code** mode if not already selected ** + + ```promql + flask_app_cpu_usage{environment="prod"} + ``` + + - Click **Run queries**. + + This query should display the simulated CPU usage data in the **prod** environment. + +1. Add memory usage query: + + - Click **+ Add query**. + - In the query area, paste the following PromQL query: + + ```promql + flask_app_memory_usage{environment="prod"} + ``` + + {{< figure src="/media/docs/alerting/time-series_cpu_mem_usage_metrics.png" max-width="1200px" caption="Time-series panel displaying CPU and memory usage metrics in production." >}} + + Both metrics return labels that we’ll use later to link alert instances with the appropriate routing. These labels help define how alerts are routed based on their environment or other criteria. + +1. Click **Save dashboard**. + + We have our time-series panel ready. Feel free to combine metrics with labels such as `environment = “staging”`. + + + + +## Create Notification Policies + +Notification policies route alert instances to contact points via label matchers. Since we know what labels our application returns (i.e., `environment`, `job`, `instance`), we can use these labels to match alert rules. + +1. Navigate to **Alerts & IRM > Alerting > Notification Policies**. + +1. Add a child policy: + + - In the **Default policy**, click **+ New child policy**. + - **Label**: `environment`. + - **Operator**: `=`. + - **Value**: `production`. + - This label matches alert rules where the environment label is `prod`. + +1. Choose a **contact point**: + + - If you don’t have any contact points, add a [Contact point](https://grafana.com/docs/grafana/latest/alerting/configure-notifications/manage-contact-points/#add-a-contact-point). + + For a quick test, you can use a public webhook from [webhook.site](https://webhook.site/) to capture and inspect alert notifications. If you choose this method, select **Webhook** from the drop-down menu in contact points. + +1. Enable continue matching: + + - Turn on **Continue matching subsequent sibling nodes** so the evaluation continues even after one or more labels (i.e., _environment_ labels) match. + +1. Save and repeat + + - Create another child policy by following the same steps. + - Use `environment = staging` as the label/value pair. + - Feel free to use a different contact point. + +Now that the labels are defined, we can create alert rules for CPU and memory metrics. These alert rules will use the labels from the collected and stored metrics in Prometheus. + + + + +## Create alert rules to monitor CPU and memory usage + +Follow these steps to manually create alert rules and link them to a visualization. + +## Create an alert rule for CPU usage + +1. Navigate to **Alerts & IRM > Alerting > Alert rules** from the Grafana sidebar. +1. Click **+ New alert rule** rule to create a new alert. + +### Enter alert rule name + +Make it short and descriptive, as this will appear in your alert notification. For instance, `CPU usage` . + +### Define query and alert condition + +1. Select **Prometheus** data source from the drop-down menu. +1. In the query section, enter the following query: + + ** switch to **Code** mode if not already selected ** + + ``` + flask_app_cpu_usage{} + ``` + +1. **Alert condition** section: + + - Enter 75 as the value for **WHEN QUERY IS ABOVE** to set the threshold for the alert. + - Click **Preview alert rule condition** to run the queries. + + {{< figure src="/media/docs/alerting/promql-returning-metrics.png" max-width="1200px" caption="Preview of a query returning alert instances in Grafana." >}} + + Among the labels returned for `flask_app_cpu_usage`, the environment label is particularly important, as it enables dynamic alert routing based on the environment value, ensuring the right team receives the relevant notifications. + +### Add folders and labels + +In this section we add a [templated label based on query value](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/templates/examples/#based-on-query-value) to map to the notification policies. + +1. In **Folder**, click _+ New folder_ and enter a name. For example: `App metrics` . This folder contains our alerts. +1. Click **+ Add labels**. +1. **Key** field: `environment` . +1. In the **value** field copy in the following template: + + ```go + {{- if eq $labels.environment "prod" -}} + production + {{- else if eq $labels.environment "staging" -}} + staging + {{- else -}} + development + {{- end -}} + ``` + + In this context, the template is used to route alert notifications based on the `environment` label. When a metric like CPU usage exceeds a threshold, the template checks the environment (e.g., `prod`, `staging`, or any other value). It then generates a label based on query value (e.g., _production_, _staging_, or _development_). This label is used in the alert notification policy to route alerts to the appropriate team, so that notifications are directed to the right group, making the process more efficient and avoiding unnecessary overlap. + +### Set evaluation behaviour + +1. Click + **New evaluation group**. Name it `System usage`. +1. Choose an **Evaluation interval** (how often the alert will be evaluated). Choose `1m`. Click Create. +1. Set the **pending period** to `0s` (zero seconds), so the alert rule fires the moment the condition is met (this minimizes the waiting time for the demonstration.). + +### Configure notifications + +Select who should receive a notification when an alert rule fires. + +1. Toggle the **Advance options** button. +1. Click **Preview routing**. + The preview should display which firing alerts are routed to contact points based on notification policies that match the `environment` label. + + {{< figure src="/media/docs/alerting/routing-preview-cpu-metrics.png" max-width="1200px" caption="Notification policies matched by the environment label matcher." >}} + + The environment label matcher should map to the notification policies created earlier. This makes sure that firing alert instances are routed to the appropriate contact points associated with each policy. + +### Configure notification message + +Link your dashboard panel to this alert rule to display alert annotations in your visualization whenever the alert rule triggers or resolves. + +1. Click **Link dashboard and panel**. +1. Find the panel that you created earlier. +1. Click **Confirm**. + +## Create a second alert rule for memory usage + +1. Duplicate the existing alert rule (**More > Duplicate**), or create a new alert rule for memory usage, defining a threshold condition (e.g., memory usage exceeding `60%`). +1. Query: `flask_app_memory_usage{}` +1. Link to the same visualization to obtain memory usage annotations whenever the alert rule triggers or resolves. + +Now that the CPU and memory alert rules are set up, they are linked to the notification policies through the custom label matcher we added. The value of the label dynamically changes based on the environment template, using `$labels.environment`. This ensures that the label value will be set to production, staging, or development, depending on the environment. + + + + +## Visualizing metrics and alert annotations + +Check how your dashboard looks now that both alerts have been linked to your dashboard panel. + +{{< figure src="/media/docs/alerting/time-series_cpu_with_alert.png" max-width="1200px" caption="Time series panel displaying health indicators and annotations." >}} + +After the alert rules are created, they should appear as **health indicators** (colored heart icons: red heart when the alert is in **Alerting** state, and green heart when in **Normal** state.) on the linked panel. In addition, the annotations include helpful context, such as the time the alert was triggered. + + + + +## Create mute timings + +Now that we've set up notification policies, we can demonstrate how to mute alerts for recurring periods of time. You can mute notifications for either the production or staging policies, depending on your needs. + +Mute timings are useful for suppressing alerts with certain labels during maintenance windows or weekends. + +1. Navigate to **Alerts & IRM > Alerting > Notification Policies**. + - Enter a name, e.g. `Planned downtime` or `Non-business hours`. + - Select **Sat** and **Sun**, to apply the mute timing to all Saturdays and Sundays. + - Click **Save mute timing**. +1. Add mute timing to the desired policy: + - Go to the notification policy that routes instances with the `staging` label. + - Select **More > Edit**. + - Choose the mute timing from the drop-down menu + - Click **Update policy**. + +This mute timing will apply to any alerts from the staging environment that trigger on Saturdays and Sundays. + + + + +## Conclusion + +By using notification policies, you can route alerts based on query values, directing them to the appropriate teams. Integrating alerts into dashboards provides more context, and mute timings allow you to suppress alerts during maintenance or low-priority periods. + +## Learn more + +Explore related topics covered in this tutorial: + +- Understand how alert routing works in [Get started with Grafana Alerting - Part 2](http://www.grafana.com/tutorials/alerting-get-started-pt2/). +- Learn how templating works in [Get started with Grafana Alerting - Part 4](http://www.grafana.com/tutorials/alerting-get-started-pt4/). + - More [examples on templating labels](https://grafana.com/docs/grafana/latest/alerting/alerting-rules/templates/examples/). + + diff --git a/docs/sources/tutorials/alerting-get-started/index.md b/docs/sources/tutorials/alerting-get-started/index.md index c77a4b0693f..507bc4050f7 100644 --- a/docs/sources/tutorials/alerting-get-started/index.md +++ b/docs/sources/tutorials/alerting-get-started/index.md @@ -11,10 +11,10 @@ labels: - cloud tags: - beginner -title: Get started with Grafana Alerting - Part 1 of 4 +title: Get started with Grafana Alerting - Part 1 weight: 50 killercoda: - title: Get started with Grafana Alerting - Part 1 of 4 + title: Get started with Grafana Alerting - Part 1 description: Get started with Grafana Alerting by creating your first alert rule, sending notifications to a webhook, and generating data to test it live — Part 1. backend: imageid: ubuntu @@ -22,7 +22,7 @@ killercoda: -# Get started with Grafana Alerting - Part 1 of 4 +# Get started with Grafana Alerting - Part 1 In this guide, we walk you through the process of setting up your first alert in just a few minutes. You'll witness your alert in action with real-time data, as well as sending alert notifications. diff --git a/docs/sources/tutorials/iis/index.md b/docs/sources/tutorials/iis/index.md index 20c52aaee37..18a25341c1d 100644 --- a/docs/sources/tutorials/iis/index.md +++ b/docs/sources/tutorials/iis/index.md @@ -47,7 +47,7 @@ You will also need the Application Request Routing (ARR) module for IIS for prox ## Grafana Config -The Grafana config can be set by creating a file named/editing the existing file named `custom.ini` in the `conf` subdirectory of your Grafana installation. See the [installation instructions](http://docs.grafana.org/installation/windows/#configure) for more details. +The Grafana config can be set by creating a file named/editing the existing file named `custom.ini` in the `conf` subdirectory of your Grafana installation. See the [installation instructions](/docs/grafana//installation/windows/#configure) for more details. Using the example from above, if the subpath is `grafana` (you can set this to whatever is required) and the parent site is `yourdomain.com:8080`, then you would add this to the `custom.ini` config file: diff --git a/docs/sources/upgrade-guide/_index.md b/docs/sources/upgrade-guide/_index.md index 874374740f4..28614991494 100644 --- a/docs/sources/upgrade-guide/_index.md +++ b/docs/sources/upgrade-guide/_index.md @@ -22,7 +22,7 @@ We recommend that you upgrade Grafana often to stay current with the latest fixe Because Grafana upgrades are backward compatible, the upgrade process is straightforward, and dashboards and graphs will not change. -To learn what's available in a Grafana release, refer to [What's New]({{< relref "../whatsnew" >}}). +To learn what's available in a Grafana release, refer to [What's New](../whatsnew/). Refer to any of the following upgrade guides: diff --git a/docs/sources/upgrade-guide/upgrade-v11.5/index.md b/docs/sources/upgrade-guide/upgrade-v11.5/index.md new file mode 100644 index 00000000000..633dfa3b7e0 --- /dev/null +++ b/docs/sources/upgrade-guide/upgrade-v11.5/index.md @@ -0,0 +1,22 @@ +--- +description: Guide for upgrading to Grafana v11.5 +keywords: + - grafana + - configuration + - documentation + - upgrade + - '11.5' +title: Upgrade to Grafana v11.5 +menuTitle: Upgrade to v11.5 +weight: 700 +--- + +# Upgrade to Grafana v11.5 + +{{< docs/shared lookup="upgrade/intro.md" source="grafana" version="" >}} + +{{< docs/shared lookup="back-up/back-up-grafana.md" source="grafana" version="" leveloffset="+1" >}} + +{{< docs/shared lookup="upgrade/upgrade-common-tasks.md" source="grafana" version="" >}} + +## Technical notes diff --git a/docs/sources/upgrade-guide/upgrade-v8.0/index.md b/docs/sources/upgrade-guide/upgrade-v8.0/index.md index f51f6f4c4ac..720c71960c2 100644 --- a/docs/sources/upgrade-guide/upgrade-v8.0/index.md +++ b/docs/sources/upgrade-guide/upgrade-v8.0/index.md @@ -28,7 +28,7 @@ This section describes technical changes associated with this release of Grafana ### Plugins -Grafana now requires all plugins to be signed. If a plugin is not signed Grafana will not load/start it. This is an additional security measure to make sure plugin files and binaries haven't been tampered with. All Grafana Labs authored plugins, including Enterprise plugins, are now signed. It's possible to allow unsigned plugins using a configuration setting, but is something we strongly advise against doing. For more information about this setting, refer to [allow loading unsigned plugins]({{< relref "../../setup-grafana/configure-grafana#allow_loading_unsigned_plugins" >}}). +Grafana now requires all plugins to be signed. If a plugin is not signed Grafana will not load/start it. This is an additional security measure to make sure plugin files and binaries haven't been tampered with. All Grafana Labs authored plugins, including Enterprise plugins, are now signed. It's possible to allow unsigned plugins using a configuration setting, but is something we strongly advise against doing. For more information about this setting, refer to [allow loading unsigned plugins](../../setup-grafana/configure-grafana/#allow_loading_unsigned_plugins). ### Grafana Live @@ -38,7 +38,7 @@ When WebSocket connection is established, Grafana checks the request Origin head To handle many concurrent WebSocket connections you may need to tune your OS settings or infrastructure. Grafana Live is enabled by default and supports 100 concurrent WebSocket connections max to avoid possible problems with the file descriptor OS limit. As soon as your setup meets the requirements to scale the number of persistent connections this limit can be increased. You also have an option to disable Grafana Live. -Refer to [Grafana Live configuration]({{< relref "../../setup-grafana/set-up-grafana-live" >}}) documentation for more information. +Refer to [Grafana Live configuration](../../setup-grafana/set-up-grafana-live/) documentation for more information. ### Postgres, MySQL, Microsoft SQL Server data sources @@ -65,6 +65,6 @@ ORDER BY time There are two possible workarounds to resolve this problem: 1. In Grafana v8.0.3, use an alias of the string column selected as `metric`. for example, `hostname as metric`. -2. Use the [Standard field definitions' display name]({{< relref "../../panels-visualizations/configure-standard-options#display-name" >}}) to format the alias. For the preceding example query, you would use `${__field.labels.hostname}` option. +2. Use the [Standard field definitions' display name](../../panels-visualizations/configure-standard-options/#display-name) to format the alias. For the preceding example query, you would use `${__field.labels.hostname}` option. -For more information, refer to the our relational databases documentation of [Postgres]({{< relref "../../datasources/postgres#time-series-queries" >}}), [MySQL]({{< relref "../../datasources/mysql#time-series-queries" >}}), [Microsoft SQL Server]({{< relref "../../datasources/mssql/query-editor#time-series-query-examples" >}}). +For more information, refer to the our relational databases documentation of [Postgres](../../datasources/postgres/#time-series-queries), [MySQL](../../datasources/mysql/#time-series-queries), [Microsoft SQL Server](../../datasources/mssql/query-editor/#time-series-query-examples). diff --git a/docs/sources/upgrade-guide/upgrade-v8.1/index.md b/docs/sources/upgrade-guide/upgrade-v8.1/index.md index 7ca4bf2b280..1e96e22f8a0 100644 --- a/docs/sources/upgrade-guide/upgrade-v8.1/index.md +++ b/docs/sources/upgrade-guide/upgrade-v8.1/index.md @@ -34,4 +34,4 @@ As of Grafana v8.1, we no longer support unencrypted storage of passwords and ba Since Grafana v6.2, new or updated data sources store passwords and basic auth passwords encrypted. However, unencrypted passwords and basic auth passwords were also allowed. {{% /admonition %}} -To migrate to encrypted storage, use a `grafana-cli` command to migrate all of your data sources to use encrypted storage of secrets. See [migrate data and encrypt passwords]({{< relref "../../cli#migrate-data-and-encrypt-passwords" >}}) for further instructions. +To migrate to encrypted storage, use a `grafana-cli` command to migrate all of your data sources to use encrypted storage of secrets. See [migrate data and encrypt passwords](../../cli/#migrate-data-and-encrypt-passwords) for further instructions. diff --git a/docs/sources/upgrade-guide/upgrade-v9.0/index.md b/docs/sources/upgrade-guide/upgrade-v9.0/index.md index 70f5a0c7974..9c75c1b4710 100644 --- a/docs/sources/upgrade-guide/upgrade-v9.0/index.md +++ b/docs/sources/upgrade-guide/upgrade-v9.0/index.md @@ -59,7 +59,7 @@ In the Prometheus data source, when grafana receives numeric data from Prometheu +In the InfluxDB data source, browser access mode was deprecated in grafana 8.0.0 and we are removing this feature in 9.0.0. If you are using this mode, you need to [switch to server access mode](../../datasources/influxdb/##influxql-classic-influxdb-query) on the data source configuration page or you can do this via provisioning. --> ### Transformations: Allow more complex regex expressions in rename by regex @@ -90,7 +90,7 @@ The recommendation here is to enable `envelopeEncryption` for older versions, or before upgrading to v9.0. However, the latter is probably going to be removed in one of the next releases, so we hugely encourage to move on with envelope encryption. -Find [here]({{< relref "../../setup-grafana/configure-security/configure-database-encryption" >}}) more details and some +Find [here](../../setup-grafana/configure-security/configure-database-encryption/) more details and some possible workarounds in case you end up in an undesired situation. ### A note on Grafana Enterprise licensing diff --git a/docs/sources/upgrade-guide/upgrade-v9.2/index.md b/docs/sources/upgrade-guide/upgrade-v9.2/index.md index 0215b888fa1..3a5272d3111 100644 --- a/docs/sources/upgrade-guide/upgrade-v9.2/index.md +++ b/docs/sources/upgrade-guide/upgrade-v9.2/index.md @@ -24,4 +24,4 @@ weight: 2100 ## Technical notes -Beginning in v9.2, Grafana has a [supported database versions policy]({{< relref "../../setup-grafana/installation#supported-databases" >}}). As of this release, MySQL versions from 5.7, postgres versions from v10, and SQLite 3 are supported databases. +Beginning in v9.2, Grafana has a [supported database versions policy](../../setup-grafana/installation/#supported-databases). As of this release, MySQL versions from 5.7, postgres versions from v10, and SQLite 3 are supported databases. diff --git a/docs/sources/upgrade-guide/upgrade-v9.5/index.md b/docs/sources/upgrade-guide/upgrade-v9.5/index.md index d177ca70693..26dc25a4f9e 100644 --- a/docs/sources/upgrade-guide/upgrade-v9.5/index.md +++ b/docs/sources/upgrade-guide/upgrade-v9.5/index.md @@ -28,7 +28,7 @@ weight: 1800 Beginning in v9.5, the InfluxDB data source deprecates the `database` field in provisioning files. The `dbName` field under `jsonData` must be used to store the database information. -For more information and examples, please refer to [InfluxDB Provisioning]({{< relref "../../datasources/influxdb#provision-the-data-source" >}}). +For more information and examples, please refer to [InfluxDB Provisioning](../../datasources/influxdb/#provision-the-data-source). ### Dashboard previews deprecation notice @@ -36,4 +36,4 @@ We are deprecating the dashboard previews feature and will remove it in Grafana ### Migrate your API keys to service accounts -We are upgrading Grafana [API keys](/docs/grafana//administration/service-accounts/migrate-api-keys/) to service accounts. Service accounts are a superset of API keys that include token rotation and compatibility with [Role-based access control]({{< relref "../../administration/roles-and-permissions/access-control" >}}). In a future release, we'll automatically migrate all existing API keys to service accounts. All of your existing tokens will continue to work; they will simply be migrated to service accounts. You can preempt this change by migrating your existing API keys to service accounts using Grafana's UI or API. Learn how to do this in the [API keys documentation](/docs/grafana//administration/service-accounts/migrate-api-keys/). +We are upgrading Grafana [API keys](/docs/grafana//administration/service-accounts/migrate-api-keys/) to service accounts. Service accounts are a superset of API keys that include token rotation and compatibility with [Role-based access control](../../administration/roles-and-permissions/access-control/). In a future release, we'll automatically migrate all existing API keys to service accounts. All of your existing tokens will continue to work; they will simply be migrated to service accounts. You can preempt this change by migrating your existing API keys to service accounts using Grafana's UI or API. Learn how to do this in the [API keys documentation](/docs/grafana//administration/service-accounts/migrate-api-keys/). diff --git a/docs/sources/upgrade-guide/when-to-upgrade/index.md b/docs/sources/upgrade-guide/when-to-upgrade/index.md index 052107861c4..31d6385ef9f 100644 --- a/docs/sources/upgrade-guide/when-to-upgrade/index.md +++ b/docs/sources/upgrade-guide/when-to-upgrade/index.md @@ -99,6 +99,7 @@ Here is an overview of projected version support through 2024: | 11.2 | August 2024 | May 2025 | | 11.3 | October 2024 | July 2025 | | 11.4 | December 2024 | September 2025 | +| 11.5 | January 2025 | October 2025 | {{< admonition type="note" >}} Grafana 9.5.x was the last supported minor for the 9.0 major release and is no longer supported as of July 2024. diff --git a/docs/sources/whatsnew/_index.md b/docs/sources/whatsnew/_index.md index 0de15d17301..dfe2b307d4d 100644 --- a/docs/sources/whatsnew/_index.md +++ b/docs/sources/whatsnew/_index.md @@ -69,13 +69,14 @@ weight: 1 For release highlights, deprecations, and breaking changes in Grafana releases, refer to these "What's new" pages for each version. {{% admonition type="note" %}} -For Grafana versions prior to v9.2, additional information might also be available in the archive of [release notes]({{< relref "../release-notes/" >}}). +For Grafana versions prior to v9.2, additional information might also be available in the archive of [release notes](../release-notes/). {{% /admonition %}} For a complete list of every change, with links to pull requests and related issues when available, see the [Changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). ## Grafana 11 +- [What's new in 11.5](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v11-5/) - [What's new in 11.4](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v11-4/) - [What's new in 11.3](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v11-3/) - [What's new in 11.2](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v11-2/) @@ -87,23 +88,23 @@ For a complete list of every change, with links to pull requests and related iss - [What's new in 10.4](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v10-4/) - [What's new in 10.3](https://grafana.com/docs/grafana//whatsnew/whats-new-in-v10-3/) - [What's new in 10.2](https://grafana.com/docs/grafana//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/" >}}) +- [What's new in 10.1](whats-new-in-v10-1/) +- [What's new in 10.0](whats-new-in-v10-0/) ## Grafana 9 -- [What's new in 9.5]({{< relref "./whats-new-in-v9-5" >}}) -- [What's new in 9.4]({{< relref "./whats-new-in-v9-4" >}}) -- [What's new in 9.3]({{< relref "./whats-new-in-v9-3" >}}) -- [What's new in 9.2]({{< relref "./whats-new-in-v9-2" >}}) -- [What's new in 9.1]({{< relref "./whats-new-in-v9-1" >}}) -- [What's new in 9.0]({{< relref "./whats-new-in-v9-0" >}}) +- [What's new in 9.5](whats-new-in-v9-5/) +- [What's new in 9.4](whats-new-in-v9-4/) +- [What's new in 9.3](whats-new-in-v9-3/) +- [What's new in 9.2](whats-new-in-v9-2/) +- [What's new in 9.1](whats-new-in-v9-1/) +- [What's new in 9.0](whats-new-in-v9-0/) ## Grafana 8 -- [What's new in 8.5]({{< relref "./whats-new-in-v8-5" >}}) -- [What's new in 8.4]({{< relref "./whats-new-in-v8-4" >}}) -- [What's new in 8.3]({{< relref "./whats-new-in-v8-3" >}}) -- [What's new in 8.2]({{< relref "./whats-new-in-v8-2" >}}) -- [What's new in 8.1]({{< relref "./whats-new-in-v8-1" >}}) -- [What's new in 8.0]({{< relref "./whats-new-in-v8-0" >}}) +- [What's new in 8.5](whats-new-in-v8-5/) +- [What's new in 8.4](whats-new-in-v8-4/) +- [What's new in 8.3](whats-new-in-v8-3/) +- [What's new in 8.2](whats-new-in-v8-2/) +- [What's new in 8.1](whats-new-in-v8-1/) +- [What's new in 8.0](whats-new-in-v8-0/) diff --git a/docs/sources/whatsnew/whats-new-in-v10-0.md b/docs/sources/whatsnew/whats-new-in-v10-0.md index 9d5b08c7c44..6ac989f0346 100644 --- a/docs/sources/whatsnew/whats-new-in-v10-0.md +++ b/docs/sources/whatsnew/whats-new-in-v10-0.md @@ -19,7 +19,7 @@ weight: -37 Welcome to Grafana 10.0! Read on to learn about changes to search and navigation, dashboards and visualizations, and security and authentication. -For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.0, check out our [Upgrade Guide]({{< relref "../upgrade-guide/upgrade-v10.0/index.md" >}}). +For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.0, check out our [Upgrade Guide](../../upgrade-guide/upgrade-v10.0/). -We're promoting the canvas panel out of public preview and into general availability. Over the past several months we've introduced multiple enhancements to the panel such as the ability to draw connections between elements, the ability to set the color and size of connections based on data, and the ability to add data links. We're excited to include Canvas as a first class citizen in Grafana’s core panel library. To learn more about the panel, refer to our [Canvas documentation]({{< relref "../panels-visualizations/visualizations/canvas" >}}). Also, check out our [latest blog post about canvas](https://grafana.com/blog/2023/05/11/use-canvas-panels-to-customize-visualizations-in-grafana/). +We're promoting the canvas panel out of public preview and into general availability. Over the past several months we've introduced multiple enhancements to the panel such as the ability to draw connections between elements, the ability to set the color and size of connections based on data, and the ability to add data links. We're excited to include Canvas as a first class citizen in Grafana’s core panel library. To learn more about the panel, refer to our [Canvas documentation](../../panels-visualizations/visualizations/canvas/). Also, check out our [latest blog post about canvas](https://grafana.com/blog/2023/05/11/use-canvas-panels-to-customize-visualizations-in-grafana/). {{< figure src="/media/docs/grafana/screenshot-grafana-10-0-canvas-service-graph.png" max-width="750px" caption="Canvas service graph" >}} @@ -97,7 +97,7 @@ We're promoting the canvas panel out of public preview and into general availabi _Experimental in all editions of Grafana_ -The Trends panel allows you to display trends where the x-axis is numeric and not time. This experimental panel addresses gaps that were not solved by either the Time series or XY Chart panels. For example, you can plot function graphs, rpm/torque curves, supply/demand relationships, and more. To learn more about the Trend panel, refer to the [Trend documentation]({{< relref "../panels-visualizations/visualizations/trend" >}}). +The Trends panel allows you to display trends where the x-axis is numeric and not time. This experimental panel addresses gaps that were not solved by either the Time series or XY Chart panels. For example, you can plot function graphs, rpm/torque curves, supply/demand relationships, and more. To learn more about the Trend panel, refer to the [Trend documentation](../../panels-visualizations/visualizations/trend/). {{< figure src="/media/docs/grafana/screenshot-grafana-10-0-trend-panel-new-colors.png" max-width="750px" caption="Trend engine power and torque curves" >}} @@ -120,7 +120,7 @@ Currently, the Datagrid Panel supports the following features in Grafana version - Draggable columns and rows - Series selection when pulling data from a data source -To learn more, refer to the [Datagrid documentation]({{< relref "../panels-visualizations/visualizations/datagrid/" >}}). +To learn more, refer to the [Datagrid documentation](../../panels-visualizations/visualizations/datagrid/). In subsequent releases, we’ll continue adding features to the Datagrid panel to further improve the user experience. @@ -163,7 +163,7 @@ _Generally available in all editions of Grafana._ We've implemented support for adding time regions to the Time series panel. Time regions provide a more contextualized experience, enabling you to highlight certain days of the week, such as Monday to Friday to display work weeks, right alongside your data. Time regions are also a useful way to highlight specific parts of a day like night, work hours, or whatever you want to define for each day. They allow you to quickly orient yourself in parts of the day or ignore highlighted parts of the time series. -To learn more, refer to our [time region documentation]({{< relref "../dashboards/build-dashboards/annotate-visualizations/#add-time-regions" >}}). +To learn more, refer to our [time region documentation](../../dashboards/build-dashboards/annotate-visualizations/#add-time-regions). {{< figure src="/media/docs/grafana/screenshot-grafana-10-0-time-regions.png" max-width="750px" caption="Time regions" >}} @@ -175,7 +175,7 @@ _Generally available in all editions of Grafana._ You can now filter dashboard annotations to apply annotations to all panels or selected panels, or use them to exclude selected panels. -To learn more, refer to our [documentation about adding annotation queries]({{< relref "../dashboards/build-dashboards/annotate-visualizations/#add-new-annotation-queries" >}}). +To learn more, refer to our [documentation about adding annotation queries](../../dashboards/build-dashboards/annotate-visualizations/#add-new-annotation-queries). {{< figure src="/media/docs/grafana/screenshot-grafana-10-0-annotation-filtering.png" max-width="750px" caption="Annotation filtering" >}} @@ -266,11 +266,11 @@ To learn more, refer to our [public dashboards documentation](https://grafana.co _Generally available in Grafana Enterprise, Cloud Pro, and Cloud Advanced._ You can now configure SAML using our new user interface, making the process easier and more convenient than ever before. -With the new user interface (UI), you can now configure SAML without needing to restart Grafana and you can control access to the configuration UI by using [role-based access control (RBAC)]({{< relref "../administration/roles-and-permissions/access-control/" >}}), which makes the process much faster and more efficient. +With the new user interface (UI), you can now configure SAML without needing to restart Grafana and you can control access to the configuration UI by using [role-based access control (RBAC)](../../administration/roles-and-permissions/access-control/), which makes the process much faster and more efficient. The SAML UI is available in Grafana Enterprise, Cloud Pro, and Advanced. It's user-friendly, with clear instructions and helpful prompts to guide you through the process. -For more information on how to set up SAML using the Grafana UI, refer to [Configure SAML authentication using the Grafana user interface]({{< relref "../setup-grafana/configure-security/configure-authentication/saml-ui/" >}}). +For more information on how to set up SAML using the Grafana UI, refer to [Configure SAML authentication using the Grafana user interface](../../setup-grafana/configure-security/configure-authentication/saml-ui/). ### Case-insensitive usernames and email addresses diff --git a/docs/sources/whatsnew/whats-new-in-v10-1.md b/docs/sources/whatsnew/whats-new-in-v10-1.md index 5e007c52506..145a5f4d09f 100644 --- a/docs/sources/whatsnew/whats-new-in-v10-1.md +++ b/docs/sources/whatsnew/whats-new-in-v10-1.md @@ -19,7 +19,7 @@ weight: -38 Welcome to Grafana 10.1! Read on to learn about changes to dashboards and visualizations, data sources, security and authentication and more. We're particularly excited about a set of improvements to visualizing logs from [Loki](https://grafana.com/products/cloud/logs/) and other logging data sources in Explore mode, and our Flame graph panel, used to visualize profiling data from [Pyroscope](https://grafana.com/blog/2023/03/15/pyroscope-grafana-phlare-join-for-oss-continuous-profiling/?pg=oss-phlare&plcmt=top-promo-banner) and other continuous profiling data sources. -For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.1, check out our [Upgrade Guide]({{< relref "../upgrade-guide/upgrade-v10.1/index.md" >}}). +For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v10.1, check out our [Upgrade Guide](../../upgrade-guide/upgrade-v10.1/). -You can now choose whether to set a threshold above which values in the data should be disconnected. This can be useful in cases where you have sensors that report a value at a set interval, but you want to disconnect the values when the sensor does not respond. This feature complements the existing [connect null values functionality]({{< relref "../panels-visualizations/visualizations/time-series/#connect-null-values" >}}). +You can now choose whether to set a threshold above which values in the data should be disconnected. This can be useful in cases where you have sensors that report a value at a set interval, but you want to disconnect the values when the sensor does not respond. This feature complements the existing [connect null values functionality](../../panels-visualizations/visualizations/time-series/#connect-null-values). -To learn more, refer to our [disconnect values documentation]({{< relref "../panels-visualizations/visualizations/time-series/#disconnect-values" >}}). +To learn more, refer to our [disconnect values documentation](../../panels-visualizations/visualizations/time-series/#disconnect-values). {{< figure src="/media/docs/grafana/screenshot-grafana-10-1-disconnect-values-examples.png" max-width="750px" caption="Disconnect values in Time series, Trend, and State timeline visualizations" >}} @@ -114,9 +114,9 @@ _Available in public preview in all editions of Grafana_ -You can now display network data in the Geomap visualization by using the new beta Network layer. This layer supports the same data format as the [Node graph visualization]({{< relref "../panels-visualizations/visualizations/node-graph/#data-api" >}}). +You can now display network data in the Geomap visualization by using the new beta Network layer. This layer supports the same data format as the [Node graph visualization](../../panels-visualizations/visualizations/node-graph/#data-api). -To learn more, refer to our [Geomap network layer documentation]({{< relref "../panels-visualizations/visualizations/geomap/#network-layer-beta" >}}). +To learn more, refer to our [Geomap network layer documentation](../../panels-visualizations/visualizations/geomap/#network-layer-beta). {{< figure src="/media/docs/grafana/screenshot-grafana-10-1-geomap-network-layer-v2.png" max-width="750px" caption="Geomap Network layer" >}} @@ -128,7 +128,7 @@ _Generally available in all editions of Grafana_ You can now add data links to Heatmap visualizations. This allows you to add links to other dashboards, panels, or external URLs that are relevant to the data in your heatmap. We're pleased to highlight that this feature was a community contribution. -To learn more, refer to both our [Heatmap documentation]({{< relref "../panels-visualizations/visualizations/heatmap/" >}}) and our [Configure data links documentation]({{< relref "../panels-visualizations/configure-data-links/" >}}). +To learn more, refer to both our [Heatmap documentation](../../panels-visualizations/visualizations/heatmap/) and our [Configure data links documentation](../../panels-visualizations/configure-data-links/). {{< figure src="/media/docs/grafana/screenshot-grafana-10-1-heatmap-datalinks.png" max-width="750px" caption="Heatmap datalink support" >}} @@ -140,7 +140,7 @@ _Generally available in Grafana Enterprise, Cloud Free, Cloud Pro, and Cloud Adv You can now use the resume and pause report functionality to activate draft reports that have all the required fields filled in. -To learn more, refer to our [Create and manage reports documentation]({{< relref "../dashboards/create-reports" >}}). +To learn more, refer to our [Create and manage reports documentation](../../dashboards/create-reports/). ## Data sources @@ -162,7 +162,7 @@ By default, the `step` parameter is set to the value of the `$__interval` variab _Generally available in all editions of Grafana_ -New functionality for linking of Loki log lines in Explore allows you to quickly navigate to specific log entries for precise analysis. By clicking the **Copy shortlink** button for a log line, you can generate and copy a [short URL]({{< relref "../developers/http_api/short_url/" >}}) that provides direct access to the exact log entry within an absolute time range. When you open the link, Grafana automatically scrolls to the corresponding log line and highlights it, making it easy to identify and focus on the relevant information. +New functionality for linking of Loki log lines in Explore allows you to quickly navigate to specific log entries for precise analysis. By clicking the **Copy shortlink** button for a log line, you can generate and copy a [short URL](../../developers/http_api/short_url/) that provides direct access to the exact log entry within an absolute time range. When you open the link, Grafana automatically scrolls to the corresponding log line and highlights it, making it easy to identify and focus on the relevant information. {{< figure src="/media/docs/grafana/data-sources/loki-shortlink.png" max-width="750px" caption="New Loki log line linking" >}} @@ -211,7 +211,7 @@ Currently, you can add one or more of the following filters: To only show the spans you've matched, you can enable the **Show matches only** toggle. -Learn more about span filtering in our [Tempo data source documentation]({{< relref "../datasources/tempo/#span-filters" >}}). +Learn more about span filtering in our [Tempo data source documentation](../../datasources/tempo/#span-filters). {{< figure src="/media/docs/tempo/screenshot-grafana-tempo-span-filters-v10-1.png" max-width="750px" caption="Traces span filtering" >}} @@ -322,7 +322,7 @@ Data source plugin developers can now use any plugin to visualize data in Explor _All Alerting features are generally available in all editions of Grafana_ -We’ve made a number of improvements to simplify the alert rule creation process as well as improvements to contact points and alert management. For all the details, refer to our [Alerting documentation]({{< relref "../alerting" >}}). +We’ve made a number of improvements to simplify the alert rule creation process as well as improvements to contact points and alert management. For all the details, refer to our [Alerting documentation](../../alerting/). ### Alert rules @@ -426,7 +426,7 @@ We've removed the `onlyExternalOrgRoleSync` feature toggle, and have defaulted t If you prefer to manage your users' organization roles manually, enable the `skip_org_role_sync` option in the Grafana configuration for your authentication provider. -For context on the previous work done leading up to this change, refer to the [Grafana v9.5 What's new]({{< relref "../whatsnew/whats-new-in-v9-5/#auth-lock-organization-roles-synced-from-auth-providers" >}}). +For context on the previous work done leading up to this change, refer to the [Grafana v9.5 What's new](../whats-new-in-v9-5/#auth-lock-organization-roles-synced-from-auth-providers). ### GitLab OIDC support @@ -439,7 +439,7 @@ Grafana now supports GitLab OIDC through the `GitLab` OAuth provider in addition This change also allows Grafana to reduce the access scope to only the required scopes for authentication and authorization, instead of full read API access. -To learn how to migrate your GitLab OAuth2 setup to OIDC, refer to our [GitLab authentication documentation]({{< relref "../setup-grafana/configure-security/configure-authentication/gitlab/" >}}). +To learn how to migrate your GitLab OAuth2 setup to OIDC, refer to our [GitLab authentication documentation](../../setup-grafana/configure-security/configure-authentication/gitlab/). ### Google OIDC and Team Sync support @@ -451,7 +451,7 @@ Grafana now supports Google OIDC through the `Google` OAuth provider in addition This release also adds support for Google OIDC in Team Sync. You can now easily add users to teams by using their Google groups. -To learn how to migrate your Google OAuth2 setup to OIDC and how to set up Team Sync, refer to our [Google authentication documentation]({{< relref "../setup-grafana/configure-security/configure-authentication/google/" >}}). +To learn how to migrate your Google OAuth2 setup to OIDC and how to set up Team Sync, refer to our [Google authentication documentation](../../setup-grafana/configure-security/configure-authentication/google/). ## Plugins @@ -461,7 +461,7 @@ To learn how to migrate your Google OAuth2 setup to OIDC and how to set up Team _Generally available in all editions of Grafana_ -We've made the following updates to increase awareness of the [Angular deprecation]({{< relref "../developers/angular_deprecation/" >}}) and its consequences in future releases of Grafana: +We've made the following updates to increase awareness of the [Angular deprecation](../../developers/angular_deprecation/) and its consequences in future releases of Grafana: #### UI changes @@ -471,9 +471,9 @@ We've made the following updates to increase awareness of the [Angular deprecati #### Other changes -- Angular Plugins will not be loaded if [angular_support_enabled]({{< relref "../setup-grafana/configure-grafana/#angular_support_enabled" >}}) is set to `false`. +- Angular Plugins will not be loaded if [angular_support_enabled](../../setup-grafana/configure-grafana/#angular_support_enabled) is set to `false`. -Learn more in our [Angular support deprecation documentation]({{< relref "../developers/angular_deprecation/" >}}). +Learn more in our [Angular support deprecation documentation](../../developers/angular_deprecation/). ### Deprecated provisioning of data sources with invalid UIDs diff --git a/docs/sources/whatsnew/whats-new-in-v11-5.md b/docs/sources/whatsnew/whats-new-in-v11-5.md new file mode 100644 index 00000000000..f532c4a82cb --- /dev/null +++ b/docs/sources/whatsnew/whats-new-in-v11-5.md @@ -0,0 +1,62 @@ +--- +description: Feature and improvement highlights for Grafana v11.5 +keywords: + - grafana + - new + - documentation + - '11.5' + - release notes +labels: +products: + - cloud + - enterprise + - oss +title: What's new in Grafana v11.5 +posts: + - title: Cloud Migration Assistant + items: + - docs/grafana-cloud/whats-new/2025-01-10-grafana-cloud-migration-assistant-supports-all-plugins-and-grafana-alerting.md + - title: Dashboards and visualizations + items: + - docs/grafana-cloud/whats-new/2024-10-16-redesigned-ad-hoc-filters-for-dashboards.md + - docs/grafana-cloud/whats-new/2024-11-19-new-regular-expression-option-for-extract-fields-transformation.md + - docs/grafana-cloud/whats-new/2024-09-04-sharing-drawer.md + - docs/grafana-cloud/whats-new/2024-12-16-customizable-shareable-dashboard-panel-images.md + - title: Reporting + items: + - docs/grafana-cloud/whats-new/2024-10-21-theme-options-for-reporting.md + - docs/grafana-cloud/whats-new/2024-12-02-pdf-export-improvements-in-ga.md + - title: Alerting + items: + - docs/grafana-cloud/whats-new/2025-01-22-rbac-for-alerting-notifications.md + - docs/grafana-cloud/whats-new/2025-01-22-rbac-for-notification-policies.md + - title: Data sources + items: + - docs/grafana-cloud/whats-new/2025-01-09-elasticsearch-cross-cluster-search-support.md + - docs/grafana-cloud/whats-new/2024-11-12-open-search-datasource-now-supports-private-datasource-connect.md + - docs/grafana-cloud/whats-new/2024-12-04-time-series-macro-support-in-visual-query-builder-for-sql-data-sources.md + - title: Authentication and authorization + items: + - docs/grafana-cloud/whats-new/2025-01-07-oauth-and-saml-session-handling-improvements.md + - title: Plugins + items: + - docs/grafana-cloud/whats-new/2025-01-10-plugin-frontend-sandbox.md + - title: Public dashboards + items: + - docs/grafana-cloud/whats-new/2024-09-09-public-dashboards-are-now-shared-dashboards.md +whats_new_grafana_version: 11.5 +weight: -47 +--- + +# What’s new in Grafana v11.5 + +Welcome to Grafana 11.5! +Read on to learn about new sharing, reporting, and export options, cross-cluster search for Elasticsearch, PDC support for several new data sources, and more. +The Grafana Cloud Migration Assistant is in public preview and now supports all plugins and Grafana Alerts, in addition to dashboards, folders, and data sources. +We've also made it more secure to run third-party apps and data sources, and improved user session handling for OAuth 2.0 and SAML. + +{{< youtube id="RGiktzfhRd0" >}} + +For even more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v11.5, check out our [Upgrade Guide](https://grafana.com/docs/grafana//upgrade-guide/upgrade-v11.5/). + +{{< docs/whats-new >}} diff --git a/docs/sources/whatsnew/whats-new-in-v7-0.md b/docs/sources/whatsnew/whats-new-in-v7-0.md index c1b8ce1e957..50d5ddbe753 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-0.md +++ b/docs/sources/whatsnew/whats-new-in-v7-0.md @@ -31,17 +31,17 @@ The Grafana 7.0 stable release is scheduled for the 18th of May. In the meantime The main highlights are: -- [**New Panel Editor** Redesign based on community feedback.]({{< relref "#new-panel-editor-and-unified-data-model" >}}) -- [**Explore** New tracing UI and support for visualizing Jaeger and Zipkin traces.]({{< relref "#new-tracing-ui" >}}) -- [**Enterprise** Usage insights, Presence indicator, and Auth improvements.]({{< relref "#grafana-enterprise" >}}) -- [**Transformations** Transformations and simple Math operations for all data sources.]({{< relref "#transformations" >}}) -- [**Field overrides** Automatically configure panels with data from queries.]({{< relref "#field-options-and-overrides" >}}) -- [**Table** New Table panel.]({{< relref "#table-panel" >}}) -- [**Plugins** New plugins platform.]({{< relref "#plugins-platform" >}}) -- [**Tutorials** New tutorials section.]({{< relref "#new-tutorials" >}}) -- [**Cloudwatch** Support for Cloudwatch Logs in Explore and the Logs panel.]({{< relref "#cloudwatch-logs" >}}) -- [**Breaking change** PhantomJS removed.]({{< relref "#breaking-change---phantomjs-removed" >}}) -- [**Time zones** Time zone support]({{< relref "#time-zone-support" >}}) +- [**New Panel Editor** Redesign based on community feedback.](#new-panel-editor-and-unified-data-model) +- [**Explore** New tracing UI and support for visualizing Jaeger and Zipkin traces.](#new-tracing-ui) +- [**Enterprise** Usage insights, Presence indicator, and Auth improvements.](#grafana-enterprise) +- [**Transformations** Transformations and simple Math operations for all data sources.](#transformations) +- [**Field overrides** Automatically configure panels with data from queries.](#field-options-and-overrides) +- [**Table** New Table panel.](#table-panel) +- [**Plugins** New plugins platform.](#plugins-platform) +- [**Tutorials** New tutorials section.](#new-tutorials) +- [**Cloudwatch** Support for Cloudwatch Logs in Explore and the Logs panel.](#cloudwatch-logs) +- [**Breaking change** PhantomJS removed.](#breaking-change---phantomjs-removed) +- [**Time zones** Time zone support](#time-zone-support) ## New panel editor and unified data model @@ -53,7 +53,7 @@ In previous versions of Grafana, each visualization had slightly different ways We have yet to migrate all core panels to this new architecture so in 7.0 there will be some inconsistencies in the UI between panels. This will be fixed soon in future releases as we update all the core panels and help the community update the community panel plugins. -Learn more about this feature in [Panel editor]({{< relref "../panels-visualizations/panel-editor-overview" >}}). +Learn more about this feature in [Panel editor](../../panels-visualizations/panel-editor-overview/). ## New tracing UI @@ -69,9 +69,9 @@ In the future we will add more workflows and integrations so that correlating be The data you want to visualize can come from many different places and it is usually not in exactly the right form. Users can now transform non-time series data into tables (e.g., JSON files or even simple lookup tables) in seconds without any customization or additional overhead. They can then combine non-time series data with any other data in Grafana; data from an external database or a panel that already exists in one of their current dashboards. -By chaining a simple set of point and click [transformations]({{< relref "../panels-visualizations/query-transform-data/transform-data#transformation-functions" >}}), users will be able join, pivot, filter, re-name and do calculations to get the results they need. Perfect for operations across queries or data sources missing essential data transformations. +By chaining a simple set of point and click [transformations](../../panels-visualizations/query-transform-data/transform-data/#transformation-functions), users will be able join, pivot, filter, re-name and do calculations to get the results they need. Perfect for operations across queries or data sources missing essential data transformations. -[Transformations]({{< relref "../panels-visualizations/query-transform-data/transform-data" >}}) also adds the ability to do math across queries. Lots of data sources do not support this natively, so being able to do it in Grafana is a powerful feature. +[Transformations](../../panels-visualizations/query-transform-data/transform-data/) also adds the ability to do math across queries. Lots of data sources do not support this natively, so being able to do it in Grafana is a powerful feature. For users with large dashboards or with heavy queries, being able to reuse the query result from one panel in another panel can be a huge performance gain for slow queries (e.g log or sql queries). From the data source menu in the query editor, you can choose the `--dashboard--` option and then choose the query result from another panel on the same dashboard. @@ -89,7 +89,7 @@ We are also introducing a new shared data model for both time series and table d - **Outer join:** Joins many time series/tables by a field. This can be used to outer join multiple time series on the _time_ field to show many time series in one table. - **Add field from calculation:** This is a powerful transformation that allows you perform many different types of math operations and add the result as a new field. Can be used to calculate the difference between two series or fields and add the result to a new field. Or multiply one field with another and add the result to a new field. -Learn more about this feature in [Transformations]({{< relref "../panels-visualizations/query-transform-data/transform-data#transformation-functions" >}}). +Learn more about this feature in [Transformations](../../panels-visualizations/query-transform-data/transform-data/#transformation-functions). ## Field options and overrides @@ -99,7 +99,7 @@ Up until now the overrides were available only for Graph and Table panel(via Col This feature enables even more powerful visualizations and fine grained control over how the data is displayed. -Learn more about this feature in [Field overrides]({{< relref "../panels-visualizations/configure-overrides" >}}). +Learn more about this feature in [Field overrides](../../panels-visualizations/configure-overrides/). ## Inspect panels and export data to CSV @@ -107,7 +107,7 @@ Learn more about this feature in [Field overrides]({{< relref "../panels-visuali Another new feature of Grafana 7.0 is the panel inspector. Inspect allows you to view the raw data for any Grafana panel as well as export that data to a CSV file. With Panel inspect you will also be able to perform simple raw data transformations like join, view query stats or detailed execution data. -Learn more about this feature in [Panel Inspector]({{< relref "../panels-visualizations/panel-inspector#inspect-query-request-and-response-data" >}}). +Learn more about this feature in [Panel Inspector](../../panels-visualizations/panel-inspector/#inspect-query-request-and-response-data).

@@ -153,7 +153,7 @@ Plugins can be monitored with the new metrics and health check capabilities. The With this release, we are deprecating the unofficial first version of backend plugins which will be removed in a future release. -To learn more, start with the [overview](https://grafana.com/developers/plugin-tools/key-concepts/backend-plugins/). Next, in this [tutorial](https://grafana.com/developers/plugin-tools/tutorials/build-a-data-source-backend-plugin) you'll learn how to build a backend for a data source plugin and enable it for use with [Grafana Alerting]({{< relref "../alerting" >}}). Make sure to keep an eye out for additional documentation and tutorials that will be published after the Grafana v7.0 release. +To learn more, start with the [overview](https://grafana.com/developers/plugin-tools/key-concepts/backend-plugins/). Next, in this [tutorial](https://grafana.com/developers/plugin-tools/tutorials/build-a-data-source-backend-plugin) you'll learn how to build a backend for a data source plugin and enable it for use with [Grafana Alerting](../../alerting/). Make sure to keep an eye out for additional documentation and tutorials that will be published after the Grafana v7.0 release. ## New tutorials @@ -180,27 +180,27 @@ Since then we have been working towards removing PhantomJS. In October 2019, whe As a replacement for PhantomJS we’ve developed the [Grafana Image Renderer plugin](/grafana/plugins/grafana-image-renderer) which is a plugin that runs on the backend and handles rendering panels and dashboards as PNG images using headless Chromium/Chrome. The [Grafana Image Renderer plugin](/grafana/plugins/grafana-image-renderer) can either be installed as a Grafana plugin running in its own process side-by-side with Grafana. or runs as an external HTTP service, hosted using Docker or as a standalone application. -Read more about [Image Rendering]({{< relref "../setup-grafana/image-rendering" >}}) in the documentation for further instructions. +Read more about [Image Rendering](../../setup-grafana/image-rendering/) in the documentation for further instructions. ## Query history in Explore out of beta The Query history feature lets you view and interact with the queries that you have previously run in Explore. You can add queries to the Explore query editor, write comments, create and share URL links, star your favorite queries, and much more. Starred queries are displayed in the Starred tab, so it is easier to reuse queries that you run often without typing them from scratch. -It was released as a beta feature in Grafana 6.7. The feedback has been really positive and it is now out of beta for the 7.0 release. Learn more about query history in [Explore]({{< relref "../explore" >}}). +It was released as a beta feature in Grafana 6.7. The feedback has been really positive and it is now out of beta for the 7.0 release. Learn more about query history in [Explore](../../explore/). ## Stackdriver data source supports Service Monitoring -[Service monitoring](https://cloud.google.com/service-monitoring) in Google Cloud Platform (GCP) enables you to monitor based on Service Level Objectives (SLOs) for your GCP services. The new SLO query builder in the Stackdriver data source allows you to display SLO data in Grafana. Read more about it in the [Stackdriver data source documentation]({{< relref "../datasources/google-cloud-monitoring#slo-service-level-objective-queries" >}}). +[Service monitoring](https://cloud.google.com/service-monitoring) in Google Cloud Platform (GCP) enables you to monitor based on Service Level Objectives (SLOs) for your GCP services. The new SLO query builder in the Stackdriver data source allows you to display SLO data in Grafana. Read more about it in the [Stackdriver data source documentation](../../datasources/google-cloud-monitoring/#slo-service-level-objective-queries). ## Time zone support -You can now override the [time zone]({{< relref "../dashboards/manage-dashboards#dashboard-time-settings" >}}) used to display date and time values in a dashboard. One benefit of this is that you can specify the local time zone of the service or system that you are monitoring which can be helpful when monitoring a system or service that operates across several time zones. +You can now override the [time zone](../../dashboards/manage-dashboards/#dashboard-time-settings) used to display date and time values in a dashboard. One benefit of this is that you can specify the local time zone of the service or system that you are monitoring which can be helpful when monitoring a system or service that operates across several time zones. ## Alerting and deep linking for Azure Log Analytics The Azure Monitor data source supports multiple Azure services. Log Analytics queries in the data source now have alerting support too (Azure Monitor and Application Insights already had alerting support). -A new feature is [deep linking from the graph panel to the Log Analytics query editor in the Azure Portal]({{< relref "../datasources/azure-monitor#deep-link-from-grafana-panels-to-the-log-analytics-query-editor-in-azure-portal" >}}). Click on a time series in the panel to see a context menu with a link to View in Azure Portal. Clicking that link opens the Azure Log Analytics query editor in the Azure Portal and runs the query from the Grafana panel. +A new feature is [deep linking from the graph panel to the Log Analytics query editor in the Azure Portal](../../datasources/azure-monitor/#deep-link-from-grafana-panels-to-the-log-analytics-query-editor-in-azure-portal). Click on a time series in the panel to see a context menu with a link to View in Azure Portal. Clicking that link opens the Azure Log Analytics query editor in the Azure Portal and runs the query from the Grafana panel. ## Grafana Enterprise @@ -219,17 +219,17 @@ This includes problems like: ### Usage insights and Presence indicator -This release includes a series of features that build on our new usage analytics engine. This “Grafana about Grafana” feature will help our large customers get better insight into the behavior and utilization of their users, dashboards, and data sources. The improved [dashboard search]({{< relref "../dashboards/assess-dashboard-usage#sort-dashboards-by-using-insights-data" >}}) allows you to sort dashboards by usage and errors. When a user opens a dashboard, they will see a [presence indicator]({{< relref "../dashboards/assess-dashboard-usage#presence-indicator" >}}) of who else is viewing the same dashboard. And finally [Dashboard insights]({{< relref "../dashboards/assess-dashboard-usage#dashboard-insights" >}}) allows you to view recent dashboard usage. +This release includes a series of features that build on our new usage analytics engine. This “Grafana about Grafana” feature will help our large customers get better insight into the behavior and utilization of their users, dashboards, and data sources. The improved [dashboard search](../../dashboards/assess-dashboard-usage/#sort-dashboards-by-using-insights-data) allows you to sort dashboards by usage and errors. When a user opens a dashboard, they will see a [presence indicator](../../dashboards/assess-dashboard-usage/#presence-indicator) of who else is viewing the same dashboard. And finally [Dashboard insights](../../dashboards/assess-dashboard-usage/#dashboard-insights) allows you to view recent dashboard usage. {{< figure src="/static/img/docs/v70/presence_indicator.jpg" max-width="1024px" caption="Grafana Enterprise - Presence indicator" >}} ### SAML Role and Team Sync -SAML support in Grafana Enterprise is improved by adding Role and Team Sync. Read more about how to use these features in the [SAML team sync documentation]({{< relref "../setup-grafana/configure-security/configure-authentication/saml#configure-team-sync" >}}). +SAML support in Grafana Enterprise is improved by adding Role and Team Sync. Read more about how to use these features in the [SAML team sync documentation](../../setup-grafana/configure-security/configure-authentication/saml/#configure-team-sync). ### Okta OAuth Team Sync -Okta gets its own provider which adds support for Team Sync. Read more about it in the [Okta documentation]({{< relref "../setup-grafana/configure-security/configure-authentication/okta" >}}). +Okta gets its own provider which adds support for Team Sync. Read more about it in the [Okta documentation](../../setup-grafana/configure-security/configure-authentication/okta/). ## Changelog diff --git a/docs/sources/whatsnew/whats-new-in-v7-1.md b/docs/sources/whatsnew/whats-new-in-v7-1.md index 65e9b5f8544..f6ecb1537c7 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-1.md +++ b/docs/sources/whatsnew/whats-new-in-v7-1.md @@ -25,19 +25,19 @@ This topic includes the release notes for the Grafana v7.1. For all details, rea The main highlights are: -- [**Flux and InfluxDB 2.x support in the Influx Datasource**]({{< relref "#influx-data-source" >}}) -- [**Query history search**]({{< relref "#query-history-search" >}}) -- [**Unification of Explore modes**]({{< relref "#explore-modes-unified" >}}) -- [**Elasticsearch- link to another data source from Explore**]({{< relref "#internal-links-for-elasticsearch" >}}) -- [**Merge on time transform for the new table panel**]({{< relref "#transformations" >}}) -- [**Stat panel text mode**]({{< relref "#stat-panel-text-mode" >}}) -- [**Time range picker update**]({{< relref "#time-range-picker-update" >}}) -- [**Provisioning of apps**]({{< relref "#provisioning-of-apps" >}}) -- [**Azure Monitor Datasource**]({{< relref "#azure-monitor-data-source" >}}) -- [**Deep linking for Google Cloud Monitoring (formerly named Google Stackdriver) datasource**]({{< relref "#deep-linking-for-google-cloud-monitoring-formerly-named-google-stackdriver-data-source" >}}) -- [**Grafana Enterprise features**]({{< relref "#grafana-enterprise-features" >}}) - - [**Secret management with HashiCorp Vault**]({{< relref "#support-for-hashicorp-vault" >}}) - - [**Monthly schedules in reports**]({{< relref "#support-for-monthly-schedules-in-reports" >}}) +- [**Flux and InfluxDB 2.x support in the Influx Datasource**](#influx-data-source) +- [**Query history search**](#query-history-search) +- [**Unification of Explore modes**](#explore-modes-unified) +- [**Elasticsearch- link to another data source from Explore**](#internal-links-for-elasticsearch) +- [**Merge on time transform for the new table panel**](#transformations) +- [**Stat panel text mode**](#stat-panel-text-mode) +- [**Time range picker update**](#time-range-picker-update) +- [**Provisioning of apps**](#provisioning-of-apps) +- [**Azure Monitor Datasource**](#azure-monitor-data-source) +- [**Deep linking for Google Cloud Monitoring (formerly named Google Stackdriver) datasource**](#deep-linking-for-google-cloud-monitoring-formerly-named-google-stackdriver-data-source) +- [**Grafana Enterprise features**](#grafana-enterprise-features) + - [**Secret management with HashiCorp Vault**](#support-for-hashicorp-vault) + - [**Monthly schedules in reports**](#support-for-monthly-schedules-in-reports) ## Influx data source @@ -45,7 +45,7 @@ Support for Flux and Influx v2 has been added. The InfluxData blog post, [How to ## Query history search -In Grafana v 7.1 we are introducing search functionality in Query history. You can search across queries and your comments. It is especially useful in combination with a time filter and data source filter. Read more about [Query history here]({{< relref "../explore#query-history" >}}). +In Grafana v 7.1 we are introducing search functionality in Query history. You can search across queries and your comments. It is especially useful in combination with a time filter and data source filter. Read more about [Query history here](../../explore/#query-history). {{< figure src="/static/img/docs/v71/query_history_search.gif" max-width="800px" caption="Query history search" >}} @@ -67,11 +67,11 @@ The new table panel introduced in 7.0 was missing a few features that the old ta ## Ad hoc filtering in the new table panel -[Ad hoc filtering]({{< relref "../dashboards/variables/add-template-variables#add-ad-hoc-filters" >}}), a way to automatically add filters to queries without having to define template variables is now supported in the new Table panel. +[Ad hoc filtering](../../dashboards/variables/add-template-variables/#add-ad-hoc-filters), a way to automatically add filters to queries without having to define template variables is now supported in the new Table panel. ## Stat panel text mode -The [stat panel]({{< relref "../panels-visualizations/visualizations/stat#text-mode" >}}) has a new **Text mode** option to control what text to show. +The [stat panel](../../panels-visualizations/visualizations/stat/#text-mode) has a new **Text mode** option to control what text to show. By default, the Stat panel displays: @@ -84,7 +84,7 @@ You can use the Text mode option to control what text the panel renders. If the ## Provisioning of apps -Grafana v7.1 adds support for provisioning of app plugins. This allows app plugins to be configured and enabled/disabled using configuration files. For more information about provisioning of app, refer to [provisioning plugin]({{< relref "../administration/provisioning#plugins" >}}). +Grafana v7.1 adds support for provisioning of app plugins. This allows app plugins to be configured and enabled/disabled using configuration files. For more information about provisioning of app, refer to [provisioning plugin](../../administration/provisioning/#plugins). ## Azure Monitor data source @@ -94,7 +94,7 @@ Additionally, the Raw Edit mode for Application Insights Analytics has been repl ## Deep linking for Google Cloud Monitoring (formerly named Google Stackdriver) data source -A new feature in Grafana 7.1 is [deep linking from Grafana panels to the Metrics Explorer in Google Cloud Console]({{< relref "../datasources/google-cloud-monitoring#deep-linking-from-grafana-panels-to-the-metrics-explorer-in-google-cloud-console" >}}). Click on a time series in the panel to see a context menu with a link to View in Metrics explorer in Google Cloud Console. Clicking that link opens the Metrics explorer in the Monitoring Google Cloud Console and runs the query from the Grafana panel there. +A new feature in Grafana 7.1 is [deep linking from Grafana panels to the Metrics Explorer in Google Cloud Console](../../datasources/google-cloud-monitoring/#deep-linking-from-grafana-panels-to-the-metrics-explorer-in-google-cloud-console). Click on a time series in the panel to see a context menu with a link to View in Metrics explorer in Google Cloud Console. Clicking that link opens the Metrics explorer in the Monitoring Google Cloud Console and runs the query from the Grafana panel there. ## Time range picker update @@ -108,11 +108,11 @@ General features are included in the Grafana Enterprise edition software. ### Support for HashiCorp Vault -You can now use HashiCorp Vault to get secrets for configuration and provisioning of Grafana Enterprise. For more information about HashiCorp Vault, refer to [vault]({{< relref "../setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault" >}}). +You can now use HashiCorp Vault to get secrets for configuration and provisioning of Grafana Enterprise. For more information about HashiCorp Vault, refer to [vault](../../setup-grafana/configure-security/configure-database-encryption/integrate-with-hashicorp-vault/). ### Support for monthly schedules in reports -With Grafana Enterprise 7.1, you can generate reports on a [monthly schedule]({{< relref "../dashboards/share-dashboards-panels#scheduling" >}}). +With Grafana Enterprise 7.1, you can generate reports on a [monthly schedule](../../dashboards/share-dashboards-panels/#scheduling). ## Changelog diff --git a/docs/sources/whatsnew/whats-new-in-v7-2.md b/docs/sources/whatsnew/whats-new-in-v7-2.md index 0020f4c71e1..b6b08749e53 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-2.md +++ b/docs/sources/whatsnew/whats-new-in-v7-2.md @@ -25,23 +25,23 @@ This topic includes the release notes for the Grafana v7.2. For all details, rea The main highlights are: -- [**New date formatting options added**]({{< relref "#new=date-formatting-options-added" >}}) -- [**Field options are out of beta!**]({{< relref "#field-options-are-out-of-beta" >}}) - - [**Added table column filters**]({{< relref "#added-table-column-filters" >}}) - - [**New field override selection options**]({{< relref "#new-field-override-selection-options" >}}) -- [**New transformations and enhancements**]({{< relref "#new-transformations-and-enhancements" >}}) -- [**Drag to reorder queries**]({{< relref "#drag-to-reorder-queries" >}}) -- [**Inspect queries in Explore**]({{< relref "#inspect-queries-in-explore" >}}) -- [**$__rate_interval for Prometheus**]({{< relref "#__rate_interval-for-prometheus" >}}) -- [**Toggle parsed log fields**]({{< relref "#toggle-parsed-log-fields" >}}) -- [**Sensitive alert channel settings are now encrypted**]({{< relref "#sensitive-alert-channel-settings-are-now-encrypted" >}}) -- [**Grafana Enterprise features**]({{< relref "#grafana-enterprise-features" >}}) - - [**Report time range**]({{< relref "#report-time-range" >}}) - - [**Organization-wide report settings**]({{< relref "#organization-wide-report-settings" >}}) - - [**Report grid layout**]({{< relref "#report-grid-layout" >}}) -- [**What's new in other parts of the Grafana ecosystem**]({{< relref "#whats-new-in-other-parts-of-the-grafana-ecosystem" >}}) - - [**ADX (Azure Data Explorer) plugin**]({{< relref "#adx-azure-data-explorer-plugin" >}}) - - [**X-Ray data source plugin**]({{< relref "#x-ray-data-source-plugin" >}}) +- [**New date formatting options added**](#new=date-formatting-options-added) +- [**Field options are out of beta!**](#field-options-are-out-of-beta) + - [**Added table column filters**](#added-table-column-filters) + - [**New field override selection options**](#new-field-override-selection-options) +- [**New transformations and enhancements**](#new-transformations-and-enhancements) +- [**Drag to reorder queries**](#drag-to-reorder-queries) +- [**Inspect queries in Explore**](#inspect-queries-in-explore) +- [**$\_\_rate_interval for Prometheus**](#__rate_interval-for-prometheus) +- [**Toggle parsed log fields**](#toggle-parsed-log-fields) +- [**Sensitive alert channel settings are now encrypted**](#sensitive-alert-channel-settings-are-now-encrypted) +- [**Grafana Enterprise features**](#grafana-enterprise-features) + - [**Report time range**](#report-time-range) + - [**Organization-wide report settings**](#organization-wide-report-settings) + - [**Report grid layout**](#report-grid-layout) +- [**What's new in other parts of the Grafana ecosystem**](#whats-new-in-other-parts-of-the-grafana-ecosystem) + - [**ADX (Azure Data Explorer) plugin**](#adx-azure-data-explorer-plugin) + - [**X-Ray data source plugin**](#x-ray-data-source-plugin) ## New date formatting options added @@ -51,7 +51,7 @@ This screenshot shows both a custom full date format with a 12 hour clock and am {{< figure src="/static/img/docs/v72/date_formats.png" max-width="800px" caption="Custom date time formats" >}} -Date formats are set for a Grafana instance by adjusting [server-wide settings]({{< relref "../setup-grafana/configure-grafana#date_formats" >}}) in the Grafana configuration file. We hope to add org- and user-level settings in the future. +Date formats are set for a Grafana instance by adjusting [server-wide settings](../../setup-grafana/configure-grafana/#date_formats) in the Grafana configuration file. We hope to add org- and user-level settings in the future. ``` [date_formats] @@ -66,7 +66,7 @@ interval_year = YYYY There is also experimental support to use the browser location and language to dynamically change the current date format for each user. This feature is disabled by default. -The [Configuration]({{< relref "../setup-grafana/configure-grafana#date_formats" >}}) topic has been updated as a result of this change. +The [Configuration](../../setup-grafana/configure-grafana/#date_formats) topic has been updated as a result of this change. ## Field options are out of beta! @@ -78,7 +78,7 @@ You can now dynamically apply value filters to any table column. This option can {{< figure src="/static/img/docs/v72/table_column_filters.png" max-width="800px" caption="Table column filters" >}} -[Filter table columns]({{< relref "../panels-visualizations/visualizations/table#filter-table-columns" >}}) has been added as a result of this feature. +[Filter table columns](../../panels-visualizations/visualizations/table/#filter-table-columns) has been added as a result of this feature. ### New field override selection options @@ -88,8 +88,8 @@ You can now add override rules that use a regex matcher to choose which fields t Grafana 7.2 includes the following transformation enhancements: -- A new [Group By]({{< relref "../panels-visualizations/query-transform-data/transform-data#group-by" >}}) transformation that allows you to group by multiple fields and add any number of aggregations for other fields. -- The [Labels to fields]({{< relref "../panels-visualizations/query-transform-data/transform-data#labels-to-fields" >}}) transformation now allows you to pick one label and use that as the name of the value field. +- A new [Group By](../../panels-visualizations/query-transform-data/transform-data/#group-by) transformation that allows you to group by multiple fields and add any number of aggregations for other fields. +- The [Labels to fields](../../panels-visualizations/query-transform-data/transform-data/#labels-to-fields) transformation now allows you to pick one label and use that as the name of the value field. - You can drag transformations to reorder them. Remember that transformations are processed in the order they are listed in the UI, so think before you move something! {{< figure src="/static/img/docs/v72/transformations.gif" max-width="800px" caption="Group by and reordering of transformations" >}} @@ -100,15 +100,15 @@ The up and down arrows, which were previously the only way to change query order {{< figure src="/static/img/docs/v72/drag-queries.gif" max-width="800px" caption="Drag to reorder queries" >}} -The [Queries]({{< relref "../panels-visualizations#add-a-query" >}}) topic has been updated as a result of this change. +The [Queries](../../panels-visualizations/#add-a-query) topic has been updated as a result of this change. ## Inspect queries in Explore -You can enjoy all the details query inspector gave you in dashboards now in Explore as well. You can open query inspector tab with the button next to query history. See [Query inspector in Explore]({{< relref "../explore#query-inspector" >}}) for more details. +You can enjoy all the details query inspector gave you in dashboards now in Explore as well. You can open query inspector tab with the button next to query history. See [Query inspector in Explore](../../explore/#query-inspector) for more details. ## \$\_\_rate_interval for Prometheus -You can now use the new variable `$__rate_interval` in Prometheus for rate functions mainly. `$__rate_interval` in general is one scrape interval larger than `$__interval` but is never smaller than four times the scrape interval (which is 15s by default). See the [Prometheus data source]({{< relref "../datasources/prometheus#using-__rate_interval-variable" >}}) for more details. +You can now use the new variable `$__rate_interval` in Prometheus for rate functions mainly. `$__rate_interval` in general is one scrape interval larger than `$__interval` but is never smaller than four times the scrape interval (which is 15s by default). See the [Prometheus data source](../../datasources/prometheus/#using-__rate_interval-variable) for more details. ## Toggle parsed log fields @@ -116,7 +116,7 @@ With this awesome contribution from one of our community members, you can now to {{< figure src="/static/img/docs/v72/explore-toggle-parsed-fields.gif" max-width="800px" caption="Toggling parsed fields in Explore" >}} -The [Toggle parsed fields]({{< relref "../explore#toggle-detected-fields" >}}) section has been added to [Explore]({{< relref "../explore" >}}) as a result of this feature. +The [Toggle parsed fields](../../explore/#toggle-detected-fields) section has been added to [Explore](../../explore/) as a result of this feature. ## Sensitive alert channel settings are now encrypted @@ -128,9 +128,9 @@ These features are included in the Grafana Enterprise edition software. ### Report and export dashboards in grid layout -A new layout option is available when rendering reports: the grid layout. With this option, your report uses the panel layout from your dashboard, so that what you see is what you get. Learn more about the [grid layout]({{< relref "../dashboards/share-dashboards-panels#layout-and-orientation" >}}) in the documentation. +A new layout option is available when rendering reports: the grid layout. With this option, your report uses the panel layout from your dashboard, so that what you see is what you get. Learn more about the [grid layout](../../dashboards/share-dashboards-panels/#layout-and-orientation) in the documentation. -The grid layout is also available for the [Export dashboard as PDF]({{< relref "../dashboards/share-dashboards-panels#export-dashboard-as-pdf" >}}) feature. +The grid layout is also available for the [Export dashboard as PDF](../../dashboards/share-dashboards-panels/#export-dashboard-as-pdf) feature. {{< figure src="/static/img/docs/enterprise/reports_grid_landscape_preview.png" max-width="500px" class="docs-image--no-shadow" alt="Report in grid layout" >}} @@ -138,7 +138,7 @@ The grid layout is also available for the [Export dashboard as PDF]({{< relref " You can now generate a report with a different time range from the dashboard it is based on. This means that you no longer have to apply workarounds, such as copying dashboards or carefully aligning report generation with the end of the month, to generate reports that cover the period you want. -For more information, refer to [Reports time range]({{< relref "../dashboards/share-dashboards-panels#report-time-range" >}}). +For more information, refer to [Reports time range](../../dashboards/share-dashboards-panels/#report-time-range). ### Organization-wide report settings @@ -146,7 +146,7 @@ You can now configure organization-wide report settings, such as report branding {{< figure src="/static/img/docs/enterprise/reports_settings.png" max-width="500px" class="docs-image--no-shadow" caption="Reports settings" >}} -For more information, refer to [Report settings]({{< relref "../dashboards/share-dashboards-panels#report-settings" >}}). +For more information, refer to [Report settings](../../dashboards/share-dashboards-panels/#report-settings). ## Changelog diff --git a/docs/sources/whatsnew/whats-new-in-v7-3.md b/docs/sources/whatsnew/whats-new-in-v7-3.md index ca2c0d75c66..9f2f5882475 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-3.md +++ b/docs/sources/whatsnew/whats-new-in-v7-3.md @@ -25,12 +25,12 @@ This topic includes the release notes for Grafana v7.3. For all details, read th The main highlights are: -- [**Google Cloud Monitoring:** Out of the box dashboards]({{< relref "#cloud-monitoring-out-of-the-box-dashboards" >}}) -- [**Shorten URL for dashboards and Explore**]({{< relref "#shorten-url-for-dashboards-and-explore" >}}) -- [**Table improvements and new image cell mode**]({{< relref "#table-improvements-and-new-image-cell-mode" >}}) -- [**New color scheme option**]({{< relref "#new-color-scheme-option" >}}) -- [**SigV4 Authentication for Amazon Elasticsearch Service**]({{< relref "#sigv4-authentication-for-aws-users" >}}) -- [**CSV exports for Excel**]({{< relref "#csv-exports-for-excel" >}}) +- [**Google Cloud Monitoring:** Out of the box dashboards](#cloud-monitoring-out-of-the-box-dashboards) +- [**Shorten URL for dashboards and Explore**](#shorten-url-for-dashboards-and-explore) +- [**Table improvements and new image cell mode**](#table-improvements-and-new-image-cell-mode) +- [**New color scheme option**](#new-color-scheme-option) +- [**SigV4 Authentication for Amazon Elasticsearch Service**](#sigv4-authentication-for-aws-users) +- [**CSV exports for Excel**](#csv-exports-for-excel) ## Table improvements and new image cell mode @@ -45,7 +45,7 @@ Another new feature that can be seen in the image above is the new image cell di {{< figure src="/static/img/docs/v73/color_scheme_dropdown.png" max-width="450px" caption="Color scheme" class="pull-right" >}} -A new standard field color scheme option has been added. This new option will provide a unified way for all new panels to specify how colors should be assigned. For more information, refer to [Apply color to series and fields]({{< relref "../panels-visualizations/configure-standard-options#color-scheme" >}}). +A new standard field color scheme option has been added. This new option will provide a unified way for all new panels to specify how colors should be assigned. For more information, refer to [Apply color to series and fields](../../panels-visualizations/configure-standard-options/#color-scheme). - **Single color**: Specifies a single color. Useful in an override rule. - **From thresholds**: Informs Grafana to take color from the matching threshold. @@ -64,7 +64,7 @@ Another thing to highlight is that all these new color schemes are theme aware a {{< figure src="/static/img/docs/v73/table_color_scheme_mono_light.png" max-width="900px" caption="table color monochrome scheme" >}} -As this new option is a standard field option it works in every panel. Here is another example from the [Bar Gauge]({{< relref "../panels-visualizations/visualizations/bar-gauge" >}}) panel. +As this new option is a standard field option it works in every panel. Here is another example from the [Bar Gauge](../../panels-visualizations/visualizations/bar-gauge/) panel. {{< figure src="/static/img/docs/v73/bar_gauge_gradient_color_scheme.png" max-width="900px" caption="bar gauge color scheme" >}} @@ -72,7 +72,7 @@ As this new option is a standard field option it works in every panel. Here is a In v7.0, we introduced a new table panel and inspect mode with Download CSV enabled. However, CSV export to Excel was removed. Due to a large number of inquiries and requests, this [community contribution from tomdaly](https://github.com/grafana/grafana/pull/27284) brought the feature back. -For more information, refer to [Download raw query results]({{< relref "../panels-visualizations/panel-inspector#download-raw-query-results" >}}). +For more information, refer to [Download raw query results](../../panels-visualizations/panel-inspector/#download-raw-query-results). ## Google Cloud monitoring out-of-the-box dashboards @@ -86,7 +86,7 @@ The updated Google Cloud monitoring data source is shipped with pre-configured d To import the pre-configured dashboards, go to the configuration page of your Google Cloud Monitoring data source and click on the `Dashboards` tab. Click `Import` for the dashboard you would like to use. To customize the dashboard, we recommend to save the dashboard under a different name, because otherwise the dashboard will be overwritten when a new version of the dashboard is released. -For more details, see the [Google Cloud Monitoring docs]({{< relref "../datasources/google-cloud-monitoring#out-of-the-box-dashboards" >}}) +For more details, see the [Google Cloud Monitoring docs](../../datasources/google-cloud-monitoring/#out-of-the-box-dashboards) ## Shorten URL for dashboards and Explore @@ -96,7 +96,7 @@ This is an amazing new feature that was created in cooperation with one of our c You can now configure your Elasticsearch data source to access your Amazon Elasticsearch Service domain directly from Grafana. -For more details, refer to the [Elasticsearch docs]({{< relref "../datasources/elasticsearch#aws-signature-version-4-authentication" >}}). +For more details, refer to the [Elasticsearch docs](../../datasources/elasticsearch/#aws-signature-version-4-authentication). ## Chaining pipeline aggregation in Elasticsearch @@ -132,7 +132,7 @@ Example of a login event: } ``` -For more details, see the [Auditing docs]({{< relref "../setup-grafana/configure-security/audit-grafana" >}}). +For more details, see the [Auditing docs](../../setup-grafana/configure-security/audit-grafana/). ### Data source usage insights @@ -146,11 +146,11 @@ Insights: ### SAML single logout -SAML’s single logout (SLO) capability allows users to log out from all applications associated with the current identity provider (IdP) session established via SAML SSO. For more information, refer to the [docs]({{< relref "../setup-grafana/configure-security/configure-authentication/saml#single-logout" >}}). +SAML’s single logout (SLO) capability allows users to log out from all applications associated with the current identity provider (IdP) session established via SAML SSO. For more information, refer to the [docs](../../setup-grafana/configure-security/configure-authentication/saml/#single-logout). ### SAML IdP-initiated single sign on -IdP-initiated single sign on (SSO) allows the user to log in directly from the SAML identity provider (IdP). It is disabled by default for security reasons. For more information, refer to the [docs]({{< relref "../setup-grafana/configure-security/configure-authentication/saml#idp-initiated-single-sign-on-sso" >}}). +IdP-initiated single sign on (SSO) allows the user to log in directly from the SAML identity provider (IdP). It is disabled by default for security reasons. For more information, refer to the [docs](../../setup-grafana/configure-security/configure-authentication/saml/#idp-initiated-single-sign-on-sso). ## Changelog @@ -158,11 +158,11 @@ Check out [CHANGELOG.md](https://github.com/grafana/grafana/blob/main/CHANGELOG. ## Patch release notes -- [Grafana 7.3.0 release notes]({{< relref "../release-notes/release-notes-7-3-0" >}}) -- [Grafana 7.3.1 release notes]({{< relref "../release-notes/release-notes-7-3-1" >}}) -- [Grafana 7.3.2 release notes]({{< relref "../release-notes/release-notes-7-3-2" >}}) -- [Grafana 7.3.3 release notes]({{< relref "../release-notes/release-notes-7-3-3" >}}) -- [Grafana 7.3.4 release notes]({{< relref "../release-notes/release-notes-7-3-4" >}}) -- [Grafana 7.3.5 release notes]({{< relref "../release-notes/release-notes-7-3-5" >}}) -- [Grafana 7.3.6 release notes]({{< relref "../release-notes/release-notes-7-3-6" >}}) -- [Grafana 7.3.7 release notes]({{< relref "../release-notes/release-notes-7-3-7" >}}) +- [Grafana 7.3.0 release notes](../../release-notes/release-notes-7-3-0/) +- [Grafana 7.3.1 release notes](../../release-notes/release-notes-7-3-1/) +- [Grafana 7.3.2 release notes](../../release-notes/release-notes-7-3-2/) +- [Grafana 7.3.3 release notes](../../release-notes/release-notes-7-3-3/) +- [Grafana 7.3.4 release notes](../../release-notes/release-notes-7-3-4/) +- [Grafana 7.3.5 release notes](../../release-notes/release-notes-7-3-5/) +- [Grafana 7.3.6 release notes](../../release-notes/release-notes-7-3-6/) +- [Grafana 7.3.7 release notes](../../release-notes/release-notes-7-3-7/) diff --git a/docs/sources/whatsnew/whats-new-in-v7-4.md b/docs/sources/whatsnew/whats-new-in-v7-4.md index d7143caee18..0d0b9cc4806 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-4.md +++ b/docs/sources/whatsnew/whats-new-in-v7-4.md @@ -41,11 +41,11 @@ Apart from major performance improvements, the new Time series panel implements The following documentation topics were added for this feature: -- [Time series panel]({{< relref "../panels-visualizations/visualizations/time-series" >}}) -- [Graph time series as lines]({{< relref "../panels-visualizations/visualizations/time-series#line-style" >}}) -- [Graph time series as bars]({{< relref "../panels-visualizations/visualizations/time-series#bar-alignment" >}}) -- [Graph time series as points]({{< relref "../panels-visualizations/visualizations/time-series#show-points" >}}) -- [Change axis display]({{< relref "../panels-visualizations/visualizations/time-series#axis-options" >}}) +- [Time series panel](../../panels-visualizations/visualizations/time-series/) +- [Graph time series as lines](../../panels-visualizations/visualizations/time-series/#line-style) +- [Graph time series as bars](../../panels-visualizations/visualizations/time-series/#bar-alignment) +- [Graph time series as points](../../panels-visualizations/visualizations/time-series/#show-points) +- [Change axis display](../../panels-visualizations/visualizations/time-series/#axis-options) ### Node graph panel visualization (Beta) @@ -55,7 +55,7 @@ All the information and stats shown in the Node graph beta are driven by the dat For more details about how to use the X-Ray service map feature, see the [X-Ray plugin documentation](/grafana/plugins/grafana-x-ray-datasource). -For more information, refer to [Node graph panel]({{< relref "../panels-visualizations/visualizations/node-graph" >}}). +For more information, refer to [Node graph panel](../../panels-visualizations/visualizations/node-graph/). ### New transformations @@ -65,7 +65,7 @@ The following transformations were added in Grafana 7.4. The _Sort by_ transformation allows you to sort data before sending it to the visualization. -For more information, refer to [Sort by]({{< relref "../panels-visualizations/query-transform-data/transform-data#sort-by" >}}). +For more information, refer to [Sort by](../../panels-visualizations/query-transform-data/transform-data/#sort-by). #### Filter data by value transform @@ -73,13 +73,13 @@ The new _Filter data by value_ transformation allows you to filter your data dir This transformation is very useful if your data source does not natively filter by values. You might also use this to narrow values to display if you are using a shared query. -For more information, refer to [Filter data by value]({{< relref "../panels-visualizations/query-transform-data/transform-data#filter-data-by-value" >}}). +For more information, refer to [Filter data by value](../../panels-visualizations/query-transform-data/transform-data/#filter-data-by-value). ### New override option On the Overrides tab, you can now set properties for fields returned by a specific query. -For more information, refer to [About field overrides]({{< relref "../panels-visualizations/configure-overrides" >}}). +For more information, refer to [About field overrides](../../panels-visualizations/configure-overrides/). ### Exemplar support @@ -89,7 +89,7 @@ Grafana graphs now support Prometheus _exemplars_. They are displayed as diamond {{< figure src="/static/img/docs/v74/exemplars.png" max-width="900px" caption="Exemplar example" >}} -For more information, refer to [Exemplars]({{< relref "../fundamentals/exemplars" >}}). +For more information, refer to [Exemplars](../../fundamentals/exemplars/). ### Trace to logs @@ -97,20 +97,20 @@ You can now navigate from a span in a trace view directly to logs relevant for t The following topics were updated as a result of this feature: -- [Explore]({{< relref "../explore/trace-integration" >}}) -- [Jaeger]({{< relref "../datasources/jaeger#configure-trace-to-logs" >}}) -- [Tempo]({{< relref "../datasources/tempo#configure-trace-to-logs" >}}) -- [Zipkin]({{< relref "../datasources/zipkin#configure-trace-to-logs" >}}) +- [Explore](../../explore/trace-integration/) +- [Jaeger](../../datasources/jaeger/#configure-trace-to-logs) +- [Tempo](../../datasources/tempo/#configure-trace-to-logs) +- [Zipkin](../../datasources/zipkin/#configure-trace-to-logs) ### Server-side expressions _Server-side expressions_ is an experimental feature that allows you to manipulate data returned from backend data source queries. Expressions allow you to manipulate data with math and other operations when the data source is a backend data source or a **--Mixed--** data source. -The main use case is for [multi-dimensional]({{< relref "../fundamentals/timeseries-dimensions" >}}) data sources used with the upcoming next generation alerting, but expressions can be used with backend data sources and visualization as well. +The main use case is for [multi-dimensional](../../fundamentals/timeseries-dimensions/) data sources used with the upcoming next generation alerting, but expressions can be used with backend data sources and visualization as well. > **Note:** Queries built with this feature might break with minor version upgrades until Grafana 8 is released. This feature does not work with the current Grafana Alerting. -For more information, refer to [Write expression queries]({{< relref "../panels-visualizations/query-transform-data/expression-queries" >}}). [About queries]({{< relref "../panels-visualizations/query-transform-data#about-queries" >}}) was also updated as a result of this feature. +For more information, refer to [Write expression queries](../../panels-visualizations/query-transform-data/expression-queries/). [About queries](../../panels-visualizations/query-transform-data/#about-queries) was also updated as a result of this feature. ### Alert notification query label interpolation @@ -126,13 +126,13 @@ CSP support is disabled by default, to enable it you must set `content_security_ You can lock down what can be done in the frontend code. Lock down what can be loaded, what JavaScript is executed. Not compatible with some plugins. -[content_security_policy]({{< relref "../setup-grafana/configure-grafana#content_security_policy" >}}) and [content_security_policy_template]({{< relref "../setup-grafana/configure-grafana#content_security_policy_template" >}}) were added to [Configuration]({{< relref "../setup-grafana/configure-grafana" >}}) as a result of this change. +[content_security_policy](../../setup-grafana/configure-grafana/#content_security_policy) and [content_security_policy_template](../../setup-grafana/configure-grafana/#content_security_policy_template) were added to [Configuration](../../setup-grafana/configure-grafana/) as a result of this change. ### Hide users in UI You can now use the `hidden_users` configuration setting to hide specific users in the UI. For example, this feature can be used to hide users that are used for automation purposes. -[Configuration]({{< relref "../setup-grafana/configure-grafana#hidden_users" >}}) has been updated for this feature. +[Configuration](../../setup-grafana/configure-grafana/#hidden_users) has been updated for this feature. ### Elasticsearch data source updates @@ -145,13 +145,13 @@ Grafana 7.4 includes the following enhancements > **Note:** We have deprecated browser access mode. It will be removed in a future release. -For more information, refer to the [Elasticsearch docs]({{< relref "../datasources/elasticsearch" >}}). +For more information, refer to the [Elasticsearch docs](../../datasources/elasticsearch/). ### Azure Monitor updates The Azure Monitor query type was renamed to Metrics and Azure Logs Analytics was renamed to Logs to match the service names in Azure and align the concepts with the rest of Grafana. -[Azure Monitor]({{< relref "../datasources/azure-monitor" >}}) was updated to reflect this change. +[Azure Monitor](../../datasources/azure-monitor/) was updated to reflect this change. ### MQL support added for Google Cloud Monitoring @@ -161,7 +161,7 @@ Unlike the visual query builder, MQL allows you to control the time range and pe MQL uses a set of operations and functions. Operations are linked together using the common pipe mechanism, where the output of one operation becomes the input to the next. Linking operations makes it possible to build up complex queries incrementally. -Once query type Metrics is selected in the Cloud Monitoring query editor, you can toggle between the editor modes for visual query builder and MQL. For more information, refer to the [Google Cloud Monitoring docs]({{< relref "../datasources/google-cloud-monitoring#import-pre-configured-dashboards" >}}). +Once query type Metrics is selected in the Cloud Monitoring query editor, you can toggle between the editor modes for visual query builder and MQL. For more information, refer to the [Google Cloud Monitoring docs](../../datasources/google-cloud-monitoring/#import-pre-configured-dashboards). Many thanks to [mtanda](https://github.com/mtanda) this contribution! @@ -173,13 +173,13 @@ Google Cloud Monitoring data source ships with pre-configured dashboards for som If you want to customize a dashboard, we recommend that you save it under a different name. Otherwise the dashboard will be overwritten when a new version of the dashboard is released. -For more information, refer to the [Google Cloud Monitoring docs]({{< relref "../datasources/google-cloud-monitoring#import-pre-configured-dashboards" >}}). +For more information, refer to the [Google Cloud Monitoring docs](../../datasources/google-cloud-monitoring/#import-pre-configured-dashboards). ### Query Editor Help The feature previously referred to as DataSource Start Pages or Cheat Sheets has been renamed to Query Editor Help, and is now supported in panel query editors (depending on the data source), as well as in Explore. -[Queries]({{< relref "../panels-visualizations/query-transform-data#manage-queries" >}}) was updated as a result of this feature. +[Queries](../../panels-visualizations/query-transform-data/#manage-queries) was updated as a result of this feature. For more information on adding a query editor help component to your plugin, refer to [Add a query editor help component](https://grafana.com/developers/plugin-tools/how-to-guides/data-source-plugins/add-query-editor-help). @@ -187,7 +187,7 @@ For more information on adding a query editor help component to your plugin, ref The variables list has an additional column indicating whether variables are referenced in queries and panel names or not. The dependencies graph provides an easy way to check variable dependencies. You can click on a variable name within the graph to make updates to the variable as needed. -For more information, refer to [Inspect variables and their dependencies]({{< relref "../dashboards/variables/inspect-variable" >}}). +For more information, refer to [Inspect variables and their dependencies](../../dashboards/variables/inspect-variable/). ## Grafana Enterprise features @@ -195,39 +195,39 @@ These features are included in the Grafana Enterprise edition. ### Licensing changes -When determining a user’s role for billing purposes, a user who has the ability to edit and save dashboards is considered an Editor. This includes any user who is an Editor or Admin at the Org level, and who has granted Admin or Edit permissions via [Dashboard permissions]({{< relref "../administration/user-management/manage-dashboard-permissions" >}}). +When determining a user’s role for billing purposes, a user who has the ability to edit and save dashboards is considered an Editor. This includes any user who is an Editor or Admin at the Org level, and who has granted Admin or Edit permissions via [Dashboard permissions](../../administration/user-management/manage-dashboard-permissions/). After the number of Viewers or Editors has reached its license limit, only Admins will see a banner in Grafana indicating that the license limit has been reached. Previously, all users saw the banner. Grafana Enterprise license tokens update automatically on a daily basis, which means you no longer need to manually update your license, and the process for adding additional users to a license is smoother than it was before. -Refer to [Licensing restrictions]({{< relref "../administration/enterprise-licensing#license-restrictions" >}}) for more information. +Refer to [Licensing restrictions](../../administration/enterprise-licensing/#license-restrictions) for more information. ### Export usage insights to Loki You can now export usage insights logs to Loki and query them from Grafana. Usage insights logs include dashboard visits, data source views, queries and errors, and more. -For more information, refer to [Export logs of usage insights]({{< relref "../setup-grafana/configure-security/export-logs" >}}). +For more information, refer to [Export logs of usage insights](../../setup-grafana/configure-security/export-logs/). ### New audit log events -New log out events are logged based on when a token expires or is revoked, as well as [SAML Single Logout]({{< relref "../setup-grafana/configure-security/configure-authentication/saml#single-logout" >}}). A `tokenId` field was added to all audit logs to help understand which session was logged out of. +New log out events are logged based on when a token expires or is revoked, as well as [SAML Single Logout](../../setup-grafana/configure-security/configure-authentication/saml/#single-logout). A `tokenId` field was added to all audit logs to help understand which session was logged out of. Also, a counter for audit log writing actions with status (success / failure) and logger (loki / file / console) labels was added. -[Auditing]({{< relref "../setup-grafana/configure-security/audit-grafana" >}}) was updated to reflect these changes. +[Auditing](../../setup-grafana/configure-security/audit-grafana/) was updated to reflect these changes. ### Reports support Unicode You can now select a font, other than the default, for Unicode-based scripts. As a result, an automatically generated PDF of a dashboard, which contains for example Chinese or Cyrillic text, can display them. Because the size of a report increases as additional fonts are added, this feature is not on by default. -[Reporting]({{< relref "../dashboards/share-dashboards-panels#rendering-configuration" >}}) was updated as a result of this change. +[Reporting](../../dashboards/share-dashboards-panels/#rendering-configuration) was updated as a result of this change. ### Request security Request security introduces ways to limit requests from the Grafana server, and it targets requests that are generated by users. -For more information, refer to [Request security]({{< relref "../setup-grafana/configure-security/configure-request-security" >}}). +For more information, refer to [Request security](../../setup-grafana/configure-security/configure-request-security/). ## Breaking changes diff --git a/docs/sources/whatsnew/whats-new-in-v7-5.md b/docs/sources/whatsnew/whats-new-in-v7-5.md index 6f842b4baf6..daf27ad217e 100644 --- a/docs/sources/whatsnew/whats-new-in-v7-5.md +++ b/docs/sources/whatsnew/whats-new-in-v7-5.md @@ -33,7 +33,7 @@ Grafana 7.5 adds a beta version of the next-generation pie chart panel. ![Pie chart panel](/static/img/docs/pie-chart-panel/pie-chart-panel-7-5.png) -For more information, refer to [Pie chart panel]({{< relref "../panels-visualizations/visualizations/pie-chart" >}}). +For more information, refer to [Pie chart panel](../../panels-visualizations/visualizations/pie-chart/). ### Alerting for Loki @@ -41,7 +41,7 @@ Grafana 7.5 comes with alerting support for Loki. With LogQL you can wrap a log With alerting support for Loki, you can now create alerts on Loki metrics queries. -[Alerting]({{< relref "../alerting" >}}) was updated as a result of this change. +[Alerting](../../alerting/) was updated as a result of this change. ![Loki alerting](/static/img/docs/alerting/alerting-for-loki-7-5.png) @@ -55,7 +55,7 @@ For new Prometheus data sources, we have changed the default HTTP method to POST > **Note:** This is not going to affect provisioned data sources or already created data sources. -[Prometheus data source]({{< relref "../datasources/prometheus" >}}) was updated as a result of this change. +[Prometheus data source](../../datasources/prometheus/) was updated as a result of this change. ### Word highlighting for Elasticsearch @@ -67,7 +67,7 @@ When searching for text in Elasticsearch logs, matching words in the log line re In Grafana 7.5, we changed how data for the trace view is sent from the data source. The required data frame has a clear format, which is more aligned with how data is generally represented in Grafana. This makes it easier for third-party developers to implement data sources leveraging the trace view. -For more information, refer to [trace data API docs]({{< relref "../explore/trace-integration#data-api" >}}). +For more information, refer to [trace data API docs](../../explore/trace-integration/#data-api). ### Paste in SSL certs for Postgres data source @@ -77,7 +77,7 @@ Instead of the file path, users can now paste the SSL certification content in t > **Note:** It remains as limitation for the Grafana Cloud, as users may not have access to the server configuration. -[Postgres data source]({{< relref "../datasources/postgres" >}}) and [Provisioning]({{< relref "../administration/provisioning" >}}) were updated as a result of this change. +[Postgres data source](../../datasources/postgres/) and [Provisioning](../../administration/provisioning/) were updated as a result of this change. ### Deprecation notice for some Azure Monitor queries @@ -85,16 +85,16 @@ In the upcoming Grafana 8.0 release, Application Insights and Insights Analytics Grafana 7.5 includes a deprecation notice for these queries, and some documentation to help users prepare for the upcoming changes. -For more information, refer to [Deprecating Application Insights and Insights Analytics]({{< relref "../datasources/azure-monitor#application-insights-and-insights-analytics--removed-" >}}). +For more information, refer to [Deprecating Application Insights and Insights Analytics](../../datasources/azure-monitor/#application-insights-and-insights-analytics--removed-). ### Cloudwatch data source enhancements - Support for region eu-south-1 has been added to the CloudWatch data source. New metrics have also been added to the namespaces AWS/Timestream, AWS/RDS (RDS Proxy metrics), AWS/NetworkFirewall, AWS/GroundStation, and AWS/DDoSProtection. Many thanks to [relvira](https://github.com/relvira), [ilyastoli](https://github.com/ilyastoli), and [rubycut](https://github.com/rubycut) for contributing! -- Added a page limit to the List Metrics API call to improve speed and reduce memory consumption. You can change this limit by entering a higher value in [list_metrics_page_limit]({{< relref "../setup-grafana/configure-grafana#list-metrics-page-limit" >}}) in the Grafana configuration file. -- You can now enable or disable authentication providers and assume a role other than default by changing the [allowed_auth_providers]({{< relref "../setup-grafana/configure-grafana#allowed_auth_providers" >}}) and [assume_role_enabled]({{< relref "../setup-grafana/configure-grafana#assume_role_enabled" >}}) options in the Grafana configuration file. By default, the allowed authentication providers are _AWS SDK Default_, _Access and secret key_, and _Credentials File_, and role is _Assume role (ARN)_. +- Added a page limit to the List Metrics API call to improve speed and reduce memory consumption. You can change this limit by entering a higher value in [list_metrics_page_limit](../../setup-grafana/configure-grafana/#list-metrics-page-limit) in the Grafana configuration file. +- You can now enable or disable authentication providers and assume a role other than default by changing the [allowed_auth_providers](../../setup-grafana/configure-grafana/#allowed_auth_providers) and [assume_role_enabled](../../setup-grafana/configure-grafana/#assume_role_enabled) options in the Grafana configuration file. By default, the allowed authentication providers are _AWS SDK Default_, _Access and secret key_, and _Credentials File_, and role is _Assume role (ARN)_. - You can now specify a custom endpoint in the CloudWatch data source configuration page. This field is optional, and if it is left empty, then the default endpoint for CloudWatch is used. By specifying a regional endpoint, you can reduce request latency. - [AWS Cloudwatch data source]({{< relref "../datasources/aws-cloudwatch" >}}) was updated as a result of this change. + [AWS Cloudwatch data source](../../datasources/aws-cloudwatch/) was updated as a result of this change. ### Increased API limit for CloudMonitoring Services @@ -109,7 +109,7 @@ server: http_listen_port: 3101 ``` -[Azure Monitor data source]({{< relref "../datasources/azure-monitor" >}}) was updated as a result of this change. +[Azure Monitor data source](../../datasources/azure-monitor/) was updated as a result of this change. ## Enterprise features @@ -127,7 +127,7 @@ Query caching advantages: Caching currently works for all backend data sources. You can enable the cache globally or per data source, and you can configure the cache duration per data source. The cache is currently in-memory. -For more information, refer to [Query caching]({{< relref "../administration/data-source-management#query-and-resource-caching" >}}). +For more information, refer to [Query caching](../../administration/data-source-management/#query-and-resource-caching). ### Use template variable in reports @@ -135,7 +135,7 @@ If you have created dashboards with template variables, then you can choose whic Enable this feature in configuration settings using the `templateVariables` flag. -For more information, refer to [Reporting]({{< relref "../dashboards/share-dashboards-panels#choose-template-variables" >}}). +For more information, refer to [Reporting](../../dashboards/share-dashboards-panels/#choose-template-variables). ### Active user limits @@ -157,7 +157,7 @@ Each Grafana Enterprise user will be limited to three concurrent user sessions. A new session is created when you sign in to Grafana from a different device or a different browser. Multiple windows and tabs in the same browser are all part of the same session, so having many Grafana tabs open will not cause any issues. -For more information on Grafana Enterprise licensing and restrictions, refer to [License restrictions]({{< relref "../administration/enterprise-licensing#license-restrictions" >}}). +For more information on Grafana Enterprise licensing and restrictions, refer to [License restrictions](../../administration/enterprise-licensing/#license-restrictions). ## Breaking changes diff --git a/docs/sources/whatsnew/whats-new-in-v8-0.md b/docs/sources/whatsnew/whats-new-in-v8-0.md index c63d3f40f6f..0d41ace7f4c 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-0.md +++ b/docs/sources/whatsnew/whats-new-in-v8-0.md @@ -29,9 +29,9 @@ These features are included in the Grafana open source edition. ### Grafana v8.0 alerts -The new alerts in Grafana 8.0 are an opt-in feature that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible data sources in one UI and API. You can create and edit alerting rules for Grafana managed alerts, Mimir alerts, and Loki alerts as well as see alerting information from prometheus-compatible data sources in a single, searchable view. For more information, on how to create and edit alerts and notifications, refer to [Grafana Alerting]({{< relref "../alerting" >}}). +The new alerts in Grafana 8.0 are an opt-in feature that centralizes alerting information for Grafana managed alerts and alerts from Prometheus-compatible data sources in one UI and API. You can create and edit alerting rules for Grafana managed alerts, Mimir alerts, and Loki alerts as well as see alerting information from prometheus-compatible data sources in a single, searchable view. For more information, on how to create and edit alerts and notifications, refer to [Grafana Alerting](../../alerting/). -As part of the new alert changes, we have introduced a new data source, Alertmanager, which includes built-in support for Prometheus Alertmanager. It is presently in alpha and it not accessible unless alpha plugins are enabled in Grafana settings. For more information, refer to [Alertmanager data source]({{< relref "../datasources/alertmanager" >}}). +As part of the new alert changes, we have introduced a new data source, Alertmanager, which includes built-in support for Prometheus Alertmanager. It is presently in alpha and it not accessible unless alpha plugins are enabled in Grafana settings. For more information, refer to [Alertmanager data source](../../datasources/alertmanager/). > **Note:** Out of the box, Grafana still supports old Grafana alerts. They are legacy alerts at this time, and will be deprecated in a future release. @@ -39,7 +39,7 @@ To learn more about the differences between new alerts and the legacy alerts, re ### Library panels -Library panels allow users to build panels that can be used in multiple dashboards. Any updates made to that shared panel will then automatically be applied to all the dashboards that have that panel. For instructions on how to create, add, unlink and manage library panels, refer to [Library panels]({{< relref "../dashboards/build-dashboards/manage-library-panels" >}}). +Library panels allow users to build panels that can be used in multiple dashboards. Any updates made to that shared panel will then automatically be applied to all the dashboards that have that panel. For instructions on how to create, add, unlink and manage library panels, refer to [Library panels](../../dashboards/build-dashboards/manage-library-panels/). ### Real-time streaming @@ -49,11 +49,11 @@ In addition to data source integration, events can be sent to dashboards by post These metrics will be broadcast to all dashboards connected to that stream endpoint. -For more information about real-time streaming, refer to [Grafana Live documentation]({{< relref "../setup-grafana/set-up-grafana-live" >}}). +For more information about real-time streaming, refer to [Grafana Live documentation](../../setup-grafana/set-up-grafana-live/). ### Prometheus metrics browser -The Prometheus metrics browser allows you to quickly find metrics and select relevant labels to build basic queries. If supported by your Prometheus instance, each metric will show its HELP and TYPE as a tooltip. For more information, refer to [Metrics browser documentation]({{< relref "../datasources/prometheus#metrics-browser" >}}). +The Prometheus metrics browser allows you to quickly find metrics and select relevant labels to build basic queries. If supported by your Prometheus instance, each metric will show its HELP and TYPE as a tooltip. For more information, refer to [Metrics browser documentation](../../datasources/prometheus/#metrics-browser). ### Bar chart visualization (beta) @@ -63,7 +63,7 @@ The Bar chart panel is a new visualization that supports categorical data. It on To use it with time series you first have to add a **Reduce** transform. -For more information, refer to [Bar chart visualization]({{< relref "../panels-visualizations/visualizations/bar-chart" >}}). +For more information, refer to [Bar chart visualization](../../panels-visualizations/visualizations/bar-chart/). ### State timeline visualization (beta) @@ -77,11 +77,11 @@ Example with string values: With time series data and thresholds: {{< figure src="/static/img/docs/v8/state_timeline_time_series.png" max-width="800px" caption="state timeline with time series" >}} -For more information, refer to [State timeline visualization]({{< relref "../panels-visualizations/visualizations/state-timeline" >}}). +For more information, refer to [State timeline visualization](../../panels-visualizations/visualizations/state-timeline/). ### Status history visualization (beta) -A sister panel to the state timeline is the new Status history panel visualization. It can display periodic states in a grid view. It supports both numerical, string, or boolean states. You can assign colors using value mappings, thresholds, or gradient color. For more information, refer to [Status history]({{< relref "../panels-visualizations/visualizations/status-history" >}}). +A sister panel to the state timeline is the new Status history panel visualization. It can display periodic states in a grid view. It supports both numerical, string, or boolean states. You can assign colors using value mappings, thresholds, or gradient color. For more information, refer to [Status history](../../panels-visualizations/visualizations/status-history/). schemes. ![Status grid visualization](/static/img/docs/status-grid/status-grid-8-0.png) @@ -92,20 +92,20 @@ This hidden feature of the old Graph panel is now a standalone visualization. It {{< figure src="/static/img/docs/histogram/histogram-8-0.png" max-width="1025px" caption="Histogram example" >}} -For more information, refer to [Histogram]({{< relref "../panels-visualizations/visualizations/histogram" >}}) +For more information, refer to [Histogram](../../panels-visualizations/visualizations/histogram/) ### Time series visualization updates The Time series is out of beta! We are removing the `Beta` tag and graduating the Time series visualization to a stable state. - **Time series** is now the default visualization option, replacing the **Graph (old)**. -- The Time series panel now supports stacking. For more information, refer to [Graph stacked time series]({{< relref "../panels-visualizations/visualizations/time-series#stack-series" >}}). +- The Time series panel now supports stacking. For more information, refer to [Graph stacked time series](../../panels-visualizations/visualizations/time-series/#stack-series). - You can now add alerts in the Time series panel, just like the old Graph panel. -- Updated [connect null values]({{< relref "../panels-visualizations/visualizations/time-series#connect-null-values" >}}) options. +- Updated [connect null values](../../panels-visualizations/visualizations/time-series/#connect-null-values) options. - We added support for a shared crosshair and a tooltip that’s now smarter when it comes to data display in the tooltip. - Various performance improvements. -[Time series panel]({{< relref "../panels-visualizations/visualizations/time-series" >}}) topics have been updated as a result of these changes. +[Time series panel](../../panels-visualizations/visualizations/time-series/) topics have been updated as a result of these changes. ### Node graph visualization updates @@ -113,7 +113,7 @@ You can now expand the node graph for the displayed trace when using the Trace t We also added a grid view and the ability to explore hidden nodes. -[Tracing in Explore]({{< relref "../explore/trace-integration" >}}) and [Node graph]({{< relref "../panels-visualizations/visualizations/node-graph" >}}) were updated as a result of these changes. +[Tracing in Explore](../../explore/trace-integration/) and [Node graph](../../panels-visualizations/visualizations/node-graph/) were updated as a result of these changes. ### Pie chart visualization updates @@ -125,10 +125,10 @@ Lots of panel editor improvements, heavily informed by user research and communi - All options are now shown in a single pane. - You can now search panel options. -- The Value mappings feature has been completely redesigned. For more information, refer to [Configure value mappings]({{< relref "../panels-visualizations/configure-value-mappings" >}}). +- The Value mappings feature has been completely redesigned. For more information, refer to [Configure value mappings](../../panels-visualizations/configure-value-mappings/). - New **Table view** option is always available. -The [Panels]({{< relref "../panels-visualizations" >}}) section has been updated to reflect these changes. +The [Panels](../../panels-visualizations/) section has been updated to reflect these changes. ### Look and feel update @@ -140,19 +140,19 @@ Under the hood, the new theme architecture enables us to bring more sophisticate When you inspect a panel, you can now download log results as a text (.txt) file. -[Download log results]({{< relref "../panels-visualizations/panel-inspector" >}}) was added as a result of this feature. +[Download log results](../../panels-visualizations/panel-inspector/) was added as a result of this feature. ### Inspector in Explore The new Explore inspector helps you understand and troubleshoot your queries. You can inspect the raw data, export that data to a comma-separated values (CSV) file, export log results in text format, and view query requests. -[Inspector in Explore]({{< relref "../explore/explore-inspector" >}}) was added as a result of this feature. +[Inspector in Explore](../../explore/explore-inspector/) was added as a result of this feature. ### Explore log improvements Log navigation in Explore has been significantly improved. We added pagination to logs, so you can click through older or newer logs as needed. -[Logs in Explore]({{< relref "../explore/logs-integration" >}}) was updated as a result of these changes. +[Logs in Explore](../../explore/logs-integration/) was updated as a result of these changes. ![Navigate logs in Explore](/static/img/docs/explore/navigate-logs-8-0.png) @@ -160,7 +160,7 @@ Log navigation in Explore has been significantly improved. We added pagination t You can now use the Plugin catalog app to easily manage your plugins from within Grafana. Install, update, and uninstall plugins without requiring a server restart. -[Plugin catalog]({{< relref "../administration/plugin-management#plugin-catalog" >}}) was added as a result of this feature. +[Plugin catalog](../../administration/plugin-management/#plugin-catalog) was added as a result of this feature. ### Performance improvements @@ -191,13 +191,13 @@ The Azure Monitor data source now supports Managed Identity for users hosting Gr Also, in addition to querying Log Analytics Workspaces, you can now query the logs for any individual [supported resource](https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/metrics-supported), or for all resources in a subscription or resource group. -> **Note:** In Grafana 7.5 we started the deprecation for separate Application Insights queries, in favor of querying Application Insights resources through Metrics and Logs. In Grafana 8.0 new Application Insights and Insights Analytics queries cannot be made, and existing queries have been made read-only. For more details, refer to the [Deprecating Application Insights]({{< relref "../datasources/azure-monitor#application-insights-and-insights-analytics--removed-" >}}). +> **Note:** In Grafana 7.5 we started the deprecation for separate Application Insights queries, in favor of querying Application Insights resources through Metrics and Logs. In Grafana 8.0 new Application Insights and Insights Analytics queries cannot be made, and existing queries have been made read-only. For more details, refer to the [Deprecating Application Insights](../../datasources/azure-monitor/#application-insights-and-insights-analytics--removed-). -[Azure Monitor data source]({{< relref "../datasources/azure-monitor" >}}) was updated as a result of these changes. +[Azure Monitor data source](../../datasources/azure-monitor/) was updated as a result of these changes. #### Elasticsearch data source -[Elasticsearch data source]({{< relref "../datasources/elasticsearch" >}}) and [Provisioning]({{< relref "../administration/provisioning" >}}) were updated as a result of these changes. +[Elasticsearch data source](../../datasources/elasticsearch/) and [Provisioning](../../administration/provisioning/) were updated as a result of these changes. ##### Use semver strings to identify Elasticsearch version @@ -233,11 +233,11 @@ In a prior release, Cloud Monitoring added _preprocessing_ support in their quer Whenever a metric is selected in the query editor, a suitable preprocessing option is automatically selected for you. To avoid breaking changes, preprocessing is not enabled by default on existing queries. If you want to use preprocessing for existing queries, you have to manually select one in the query editor. -[Google Cloud Monitoring data source]({{< relref "../datasources/google-cloud-monitoring#pre-processing" >}}) was updated as a result of this change. +[Google Cloud Monitoring data source](../../datasources/google-cloud-monitoring/#pre-processing) was updated as a result of this change. #### Graphite data source -[Graphite data source]({{< relref "../datasources/graphite" >}}) was updated as a result of these changes. +[Graphite data source](../../datasources/graphite/) was updated as a result of these changes. ##### Variable metric names expand @@ -253,7 +253,7 @@ Graphite queries are now automatically transformed to Loki queries according to You can now use more parameters to find traces. -[Jaeger data source]({{< relref "../datasources/jaeger" >}}) was updated as a result of this change. +[Jaeger data source](../../datasources/jaeger/) was updated as a result of this change. ### Authentication updates @@ -267,11 +267,11 @@ JWT is a new authentication option in Grafana. You can now configure Grafana to accept a JWT token provided in the HTTP header. -[JWT authentication]({{< relref "../setup-grafana/configure-security/configure-authentication/jwt" >}}) was added and [Configuration]({{< relref "../setup-grafana/configure-grafana#authjwt" >}}) was updated as a result of this feature. +[JWT authentication](../../setup-grafana/configure-security/configure-authentication/jwt/) was added and [Configuration](../../setup-grafana/configure-grafana/#authjwt) was updated as a result of this feature. #### OAuth -[Generic OAuth authentication]({{< relref "../setup-grafana/configure-security/configure-authentication/generic-oauth" >}}) has been updated as a result of these changes. +[Generic OAuth authentication](../../setup-grafana/configure-security/configure-authentication/generic-oauth/) has been updated as a result of these changes. ##### Added OAuth support for empty scopes @@ -298,7 +298,7 @@ These features are included in the Grafana Enterprise edition. You can now add or remove detailed permissions from Viewer, Editor, and Admin org roles, to grant users just the right amount of access within Grafana. Available permissions include the ability to view and manage Users, Reports, and the Access Control API itself. Grafana will support more and more permissions over the coming months. -[Role-based access control docs]({{< relref "../administration/roles-and-permissions/access-control" >}}) were added as a result of this feature. +[Role-based access control docs](../../administration/roles-and-permissions/access-control/) were added as a result of this feature. ### Data source query caching @@ -308,7 +308,7 @@ This results in faster average load times for dashboards and fewer duplicate que You can enable caching per data source, and time-to-live (TTL) can be configured globally and per data source. Query caching can be set up with Redis, Memcached, or a simple in-memory cache. -For more information, refer to the [Data source query caching docs]({{< relref "../administration/data-source-management#query-and-resource-caching" >}}). +For more information, refer to the [Data source query caching docs](../../administration/data-source-management/#query-and-resource-caching). ### Reporting updates @@ -316,13 +316,13 @@ When creating a report, you can now choose to export Table panels as .csv files You can also link back to the dashboard directly from the email, for users who want to see the data live in Grafana. This release also includes some improvements to the Reports list view. -For more information, refer to [Reporting docs]({{< relref "../dashboards/share-dashboards-panels#reporting" >}}). +For more information, refer to [Reporting docs](../../dashboards/share-dashboards-panels/#reporting). ### License restrictions clarification in the docs The Grafana Enterprise documentation has been updated to describe more specifically how licensed roles are counted, how they can be updated, and where you can see details about dashboard and folder permissions that affect users' licensed roles. -For more information, refer to [License restrictions docs]({{< relref "../administration/enterprise-licensing#license-restrictions" >}}). +For more information, refer to [License restrictions docs](../../administration/enterprise-licensing/#license-restrictions). ## Breaking changes diff --git a/docs/sources/whatsnew/whats-new-in-v8-1.md b/docs/sources/whatsnew/whats-new-in-v8-1.md index d42b7b0b366..ca2a4dfe46f 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-1.md +++ b/docs/sources/whatsnew/whats-new-in-v8-1.md @@ -35,7 +35,7 @@ These features are included in the Grafana open source edition. Grafana 8.1 introduces the foundation for our new map panel. This new panel leverages [OpenLayers](https://openlayers.org/) and gives us a flexible solution for extending the way we use the new Geomap panel moving forward. The new Geomap panel includes multiple base layer styles (map layer options), as well as a more open data layer. The data layer can use coordinates and geo-hashed data in addition to a lookup table. -The Geomap panel is also able to share views across multiple Geomap panels on the same dashboard, making it straightforward to visualize and explore multiple types of geospatial data using the same map zoom and focus settings. For more information, refer to [Geomap panel]({{< relref "../panels-visualizations/visualizations/geomap" >}}). +The Geomap panel is also able to share views across multiple Geomap panels on the same dashboard, making it straightforward to visualize and explore multiple types of geospatial data using the same map zoom and focus settings. For more information, refer to [Geomap panel](../../panels-visualizations/visualizations/geomap/). {{< figure src="/static/img/docs/geomap-panel/geomap_with_heatmap.png" max-width="850px" caption="Geomap panel: Heatmap" >}} ## Annotation panel @@ -54,9 +54,9 @@ Color scheme **From thresholds**: Color scheme: **Green-Yellow-Red (by value)** {{< figure src="/static/img/docs/time-series-panel/gradient_mode_scheme_line.png" max-width="1200px" caption="Color scheme: Green-Yellow-Red" >}} -For more on how to configure Graphs with by value color schemes read [Graph and color schemes]({{< relref "../panels-visualizations/visualizations/time-series" >}}). +For more on how to configure Graphs with by value color schemes read [Graph and color schemes](../../panels-visualizations/visualizations/time-series/). -You can also create annotations in the new Time series panel bringing it closer to parity with the legacy Graph panel. To learn more, refer to the [time series panel]({{< relref "../panels-visualizations/visualizations/time-series" >}}). +You can also create annotations in the new Time series panel bringing it closer to parity with the legacy Graph panel. To learn more, refer to the [time series panel](../../panels-visualizations/visualizations/time-series/). ### Transformations improvements @@ -64,7 +64,7 @@ Grafana 8.1 includes some significant enhancements to transformations, including #### Config from query (Beta) -This transformation enables panel config (Threshold, Min, Max, etc.) to be derived from query results. For more information, refer to [Config from query results]({{< relref "../panels-visualizations/query-transform-data/transform-data#config-from-query-results" >}}). +This transformation enables panel config (Threshold, Min, Max, etc.) to be derived from query results. For more information, refer to [Config from query results](../../panels-visualizations/query-transform-data/transform-data/#config-from-query-results). #### Rows to fields (Beta) @@ -86,7 +86,7 @@ Output: As you can see each row in the source data becomes a separate field. Each field now also has a max config option set. Options like **Min**, **Max**, **Unit** and **Thresholds** are all part of field configuration and if set like this will be used by the visualization instead of any options manually configured in the panel editor options pane. -For more on how to use this transformation, refer to [Rows to fields transform]({{< relref "../panels-visualizations/query-transform-data/transform-data#rows-to-fields" >}}). +For more on how to use this transformation, refer to [Rows to fields transform](../../panels-visualizations/query-transform-data/transform-data/#rows-to-fields). #### Contextual & Inline Help @@ -102,7 +102,7 @@ We have added timezone support. As a result, you can now specify the time zone u ### Trace to logs improvements -We changed the default behavior from creating a 1-hour span Loki query to the only query at the exact time the trace span started for the duration of it. For more fine grained control over this, you can shift this time in the tracing data source settings. Also, it is now possible to shift the start time and end time of the Loki query by the set amount. For more information, refer to [Trace to logs]({{< relref "../datasources/tempo#trace-to-logs" >}}). +We changed the default behavior from creating a 1-hour span Loki query to the only query at the exact time the trace span started for the duration of it. For more fine grained control over this, you can shift this time in the tracing data source settings. Also, it is now possible to shift the start time and end time of the Loki query by the set amount. For more information, refer to [Trace to logs](../../datasources/tempo/#trace-to-logs). ### Prettify JSON for Logs in Explore @@ -114,7 +114,7 @@ And here is the prettified JSON log. {{< figure src="/static/img/docs/panels/pretty-json/prettified-json.png" max-width="1200px" caption="Prettified JSON" >}} -For more on how to prettify JSON logs, refer to [Visualization]({{< relref "../panels-visualizations/visualizations" >}}) and [Display]({{< relref "../panels-visualizations/visualizations/logs" >}}) options. +For more on how to prettify JSON logs, refer to [Visualization](../../panels-visualizations/visualizations/) and [Display](../../panels-visualizations/visualizations/logs/) options. ### Plugin catalog - Updated UX and extended features @@ -122,7 +122,7 @@ We’ve made some changes to the plugins UI to help make it easier to discover a #### Documentation updates -New panel summaries and preview on the top level [Visualizations]({{< relref "../panels-visualizations/visualizations" >}}) page to help users pick or learn about specific visualizations more easily. +New panel summaries and preview on the top level [Visualizations](../../panels-visualizations/visualizations/) page to help users pick or learn about specific visualizations more easily. ### Upcoming changes to the Select component @@ -140,7 +140,7 @@ We’d love as much feedback as possible about this change, because we are consi ### High availability setup support for Grafana Live -We have added an experimental HA setup support for Grafana Live with Redis. This resolves the limitation when clients were connected to different Grafana instances and those instances had no shared state. For additional information, refer to [Configure Grafana Live HA setup]({{< relref "../setup-grafana/set-up-grafana-live#configure-grafana-live-ha-setup" >}}). +We have added an experimental HA setup support for Grafana Live with Redis. This resolves the limitation when clients were connected to different Grafana instances and those instances had no shared state. For additional information, refer to [Configure Grafana Live HA setup](../../setup-grafana/set-up-grafana-live/#configure-grafana-live-ha-setup). ## Enterprise features @@ -150,15 +150,15 @@ These features are included in the Grafana Enterprise edition. Role-based access control remains in beta. You can now grant or revoke permissions for Viewers, Editors, or Admins to use Explore mode, configure LDAP or SAML settings, or view the admin/stats page. These new permissions enhance the existing permissions that can be customized, namely permissions to access Users, Orgs, LDAP settings, and Reports in Grafana. -Fine grained access control allows you to customize roles and permissions in Grafana beyond the built-in Viewer, Editor, and Admin roles. As of 8.1, you can modify some of the permissions for any of these built-in roles. This is helpful if you’d like users to have more or fewer access permissions than a given role allows for by default. For an overview of role-based access control and a complete list of available permissions, refer to the [Fine grained access control]({{< relref "../administration/roles-and-permissions/access-control" >}}) documentation. +Fine grained access control allows you to customize roles and permissions in Grafana beyond the built-in Viewer, Editor, and Admin roles. As of 8.1, you can modify some of the permissions for any of these built-in roles. This is helpful if you’d like users to have more or fewer access permissions than a given role allows for by default. For an overview of role-based access control and a complete list of available permissions, refer to the [Fine grained access control](../../administration/roles-and-permissions/access-control/) documentation. ### New and improved reporting scheduler -We’ve enhanced the scheduler for Reports to be more flexible, so you can send reports at just the right time. When scheduling a report, you can now choose to send a report at custom intervals such as every 4 hours or every 2 weeks. You can also send a report for a limited time period by providing a start and end date, or send a report only on weekdays or on the last day of each month. This change accompanies some other recent improvements to Reporting, like the ability to choose template variables for reports and an improved UX for authoring reports. To learn more, refer to the [reporting]({{< relref "../dashboards/share-dashboards-panels#reporting" >}}) documentation. +We’ve enhanced the scheduler for Reports to be more flexible, so you can send reports at just the right time. When scheduling a report, you can now choose to send a report at custom intervals such as every 4 hours or every 2 weeks. You can also send a report for a limited time period by providing a start and end date, or send a report only on weekdays or on the last day of each month. This change accompanies some other recent improvements to Reporting, like the ability to choose template variables for reports and an improved UX for authoring reports. To learn more, refer to the [reporting](../../dashboards/share-dashboards-panels/#reporting) documentation. ### Encrypt data in the query cache -Query caching was released in Grafana 8.0 and allows you to temporarily store the results of data source queries in a cache, so that Grafana reads repeated queries from there instead of from the data source itself. This reduces load on data sources, improves dashboard load times, and can save money for data sources that charge per query. To learn more about query caching see its [overview]({{< relref "../administration/data-source-management#query-and-resource-caching" >}}) page. To find out how to turn on encryption, refer to the [caching configuration]({{< relref "../setup-grafana/configure-grafana/enterprise-configuration#caching" >}}) documentation. +Query caching was released in Grafana 8.0 and allows you to temporarily store the results of data source queries in a cache, so that Grafana reads repeated queries from there instead of from the data source itself. This reduces load on data sources, improves dashboard load times, and can save money for data sources that charge per query. To learn more about query caching see its [overview](../../administration/data-source-management/#query-and-resource-caching) page. To find out how to turn on encryption, refer to the [caching configuration](../../setup-grafana/configure-grafana/enterprise-configuration/#caching) documentation. You can now encrypt the query data cached by Grafana. This improves the security of query data, especially when your cache (like Redis) is shared with other services. @@ -166,7 +166,7 @@ You can now encrypt the query data cached by Grafana. This improves the security You can now customize Grafana’s loading logo, which displays while Grafana is loading in a user’s browser. White labeling in Grafana Enterprise allows you to customize the look and feel of Grafana to match your product’s or company’s brand. This makes Grafana a more integrated part of your observability stack and keep Grafana consistent with other visualizations displayed in public. -To find out how you can configure it along with other Grafana UI elements, like the corner logo and application footer, refer to the [White labeling]({{< relref "../setup-grafana/configure-grafana/configure-custom-branding" >}}) topic of the Grafana Enterprise docs. +To find out how you can configure it along with other Grafana UI elements, like the corner logo and application footer, refer to the [White labeling](../../setup-grafana/configure-grafana/configure-custom-branding/) topic of the Grafana Enterprise docs. ### Oauth2 - Team Sync to Group Mapping diff --git a/docs/sources/whatsnew/whats-new-in-v8-4.md b/docs/sources/whatsnew/whats-new-in-v8-4.md index 0827828511f..343599564cb 100644 --- a/docs/sources/whatsnew/whats-new-in-v8-4.md +++ b/docs/sources/whatsnew/whats-new-in-v8-4.md @@ -130,13 +130,13 @@ Enable role-based access control by adding the term `accesscontrol` to the list #### Assign SAML users different roles in different Organizations -You can use Grafana's SAML integration to map organizations in your SAML service to [Organizations]({{< relref "../setup-grafana/configure-security/configure-authentication/saml#configure-organization-mapping" >}}) in Grafana so that users who authenticate using SAML have the right permissions. Previously, you could only choose a single role (Viewer, Editor, or Admin) for users, which would apply to all of their Organizations. Now, you can map a given SAML user or org to different roles in different Organizations, so that, for example, they can be a Viewer in one Organization and an Admin in another. +You can use Grafana's SAML integration to map organizations in your SAML service to [Organizations](../../setup-grafana/configure-security/configure-authentication/saml/#configure-organization-mapping) in Grafana so that users who authenticate using SAML have the right permissions. Previously, you could only choose a single role (Viewer, Editor, or Admin) for users, which would apply to all of their Organizations. Now, you can map a given SAML user or org to different roles in different Organizations, so that, for example, they can be a Viewer in one Organization and an Admin in another. Additionally, you can now grant multiple SAML organizations access to Grafana, using the `allowed_organizations` attribute. Previously, you could only map one. {{< figure src="/static/img/docs/enterprise/8-4-SAML-auth.png" max-width="1200px" caption="Assign SAML users role" >}} -Learn more in our [SAML docs]({{< relref "../setup-grafana/configure-security/configure-authentication/saml" >}}). +Learn more in our [SAML docs](../../setup-grafana/configure-security/configure-authentication/saml/). ### Performance improvements diff --git a/docs/sources/whatsnew/whats-new-in-v9-0.md b/docs/sources/whatsnew/whats-new-in-v9-0.md index 9d9cc1818da..3391f04dcb9 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-0.md +++ b/docs/sources/whatsnew/whats-new-in-v9-0.md @@ -102,7 +102,7 @@ Grafana Alerting now provides the ability to capture an image for Grafana manage ## Envelope encryption is generally available and enabled by default -Grafana now uses envelope encryption to encrypt secrets in the database. Envelope encryption adds a layer of indirection to the encryption process. Instead of encrypting all secrets in the database with a single key, Grafana uses a set of keys called data encryption keys (DEKs) to encrypt them. These data encryption keys are themselves encrypted with a single key encryption key (KEK). This allows you to rotate your KEK and quickly re-encrypt your DEKs in case a key is compromised. In Grafana Enterprise, you can also store your KEK in an external key management service (KMS) like AWS KMS or Azure Key Vault, for extra security. Learn more about envelope encryption in the [database encryption documentation]({{< relref "../setup-grafana/configure-security/configure-database-encryption#envelope-encryption" >}}). +Grafana now uses envelope encryption to encrypt secrets in the database. Envelope encryption adds a layer of indirection to the encryption process. Instead of encrypting all secrets in the database with a single key, Grafana uses a set of keys called data encryption keys (DEKs) to encrypt them. These data encryption keys are themselves encrypted with a single key encryption key (KEK). This allows you to rotate your KEK and quickly re-encrypt your DEKs in case a key is compromised. In Grafana Enterprise, you can also store your KEK in an external key management service (KMS) like AWS KMS or Azure Key Vault, for extra security. Learn more about envelope encryption in the [database encryption documentation](../../setup-grafana/configure-security/configure-database-encryption/#envelope-encryption). {{< figure src="/static/img/docs/enterprise/dashboards/envelope-encryption.png" max-width="750px" caption="Envelope encryption" >}} @@ -177,7 +177,7 @@ Reporting is all about convenience - getting info to eyeballs as quickly as poss ## Breaking changes -This is a partial list of notable breaking changes. For the complete list, see our [Release Notes]({{< relref "../release-notes/release-notes-9-0-0" >}}). +This is a partial list of notable breaking changes. For the complete list, see our [Release Notes](../../release-notes/release-notes-9-0-0/). ### Role-based access control: changes for general release @@ -212,7 +212,7 @@ In the Prometheus data source, when grafana receives numeric data from Prometheu +In the InfluxDB data source, browser access mode was deprecated in grafana 8.0.0 and we are removing this feature in 9.0.0. If you are using this mode, you need to [switch to server access mode](../../datasources/influxdb/##influxql-classic-influxdb-query) on the data source configuration page or you can do this via provisioning. --> ### Transformations: Allow more complex regex expressions in rename by regex @@ -251,7 +251,7 @@ Therefore, any secret created or updated in Grafana v9.0 won't be decryptable by We strongly recommend that you enable `envelopeEncryption` for older versions to deploy envelope encryption. You can alternatively configure the `disableEnvelopeEncryption` feature toggle before upgrading to v9.0; however, this feature toggle might be removed in a future Grafana release. -For more details, and workarounds for potential issues, refer to the [documentation]({{< relref "../setup-grafana/configure-security/configure-database-encryption" >}}). +For more details, and workarounds for potential issues, refer to the [documentation](../../setup-grafana/configure-security/configure-database-encryption/). ## A note on Grafana Enterprise licensing diff --git a/docs/sources/whatsnew/whats-new-in-v9-1.md b/docs/sources/whatsnew/whats-new-in-v9-1.md index 7a6aeb9f44a..839d36623a3 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-1.md +++ b/docs/sources/whatsnew/whats-new-in-v9-1.md @@ -36,11 +36,11 @@ Service accounts are an evolution in machine access within Grafana. You can create multiple API tokens per service account with independent expiration dates, and temporarily disable a service account without deleting it. These benefits make service accounts a more flexible way for Terraform and other apps to authenticate with Grafana. -Service accounts also work with [role-based access control]({{< relref "../administration/roles-and-permissions/access-control" >}}) in [Grafana Enterprise]({{< relref "../introduction/grafana-enterprise" >}}). +Service accounts also work with [role-based access control](../../administration/roles-and-permissions/access-control/) in [Grafana Enterprise](../../introduction/grafana-enterprise/). You can improve security by granting service accounts specific roles to limit the functions they can perform. Service accounts have been in beta since Grafana v8.5. During that time, we've improved the UI and migration path from API keys, made it possible to add service accounts to teams, and inherit team permissions. -To learn more about service accounts, see the [documentation]({{< relref "../administration/service-accounts" >}}). +To learn more about service accounts, see the [documentation](../../administration/service-accounts/). {{< figure src="/static/img/docs/service-accounts/add-service-account-token-9-1.png" max-width="750px" caption="Adding a service account token" >}} @@ -56,9 +56,9 @@ To see JWT URL embedding in action, see the [sample project](https://github.com/ #### Organization role mapping for GitHub OAuth2 authentication -You can now use GitHub OAuth2 to map users or teams to specific [Grafana organization roles]({{< relref "../administration/roles-and-permissions#organization-roles" >}}) by using `role_attribute_path` configuration option. +You can now use GitHub OAuth2 to map users or teams to specific [Grafana organization roles](../../administration/roles-and-permissions/#organization-roles) by using `role_attribute_path` configuration option. Grafana will use [JMESPath](https://jmespath.org/examples.html) for path lookup and role mapping. -For more information, see the [documentation]({{< relref "../setup-grafana/configure-security/configure-authentication/github#map-roles" >}}). +For more information, see the [documentation](../../setup-grafana/configure-security/configure-authentication/github/#map-roles). Grafana Cloud users can access this feature by [opening a support ticket in the Cloud Portal](/profile/org#support). @@ -75,13 +75,13 @@ This feature will be rolled out to Grafana Cloud users over the course of severa Panel title search uses our updated dashboard search approach. Previously, Grafana used SQL database queries to find dashboards by title. With the feature toggle enabled, Grafana can build an in-memory index of all dashboards. -To learn more about search in Grafana, see the [documentation]({{< relref "../dashboards/use-dashboards#dashboard-search" >}}). +To learn more about search in Grafana, see the [documentation](../../dashboards/use-dashboards/#dashboard-search). {{< figure src="/static/img/docs/dashboards/panel-title-search-9-1.png" max-width="750px" caption="Searching for a panel title" >}} #### Starred dashboards in the navigation bar -As part of the upcoming improvements to Grafana's navigation, you can now directly access your [starred dashboards]({{< relref "../dashboards/use-dashboards" >}}) from the navigation bar. +As part of the upcoming improvements to Grafana's navigation, you can now directly access your [starred dashboards](../../dashboards/use-dashboards/) from the navigation bar. {{< figure src="/static/img/docs/dashboards/starred-dashboards-9-1.png" max-width="750px" caption="Accessing your starred dashboards" >}} @@ -90,15 +90,15 @@ As part of the upcoming improvements to Grafana's navigation, you can now direct #### Heatmap improvements The beta heatmap announced in version 9.0 is now used throughout Grafana. -Its performance is improved, and it now supports [exemplars]({{< relref "../fundamentals/exemplars" >}}). -To learn more about the heatmap panel, see the [documentation]({{< relref "../panels-visualizations/visualizations/heatmap" >}}). +Its performance is improved, and it now supports [exemplars](../../fundamentals/exemplars/). +To learn more about the heatmap panel, see the [documentation](../../panels-visualizations/visualizations/heatmap/). {{< figure src="/static/img/docs/panels/heatmap-panel-9-1.png" max-width="750px" caption="A heatmap panel" >}} #### Geomap -You can now measure both distances and areas on Geomap visualizations by using the panel's new [measure tools]({{< relref "../panels-visualizations/visualizations/geomap#show-measure-tools" >}}). -To learn more about the Geomap panel, see the [documentation]({{< relref "../panels-visualizations/visualizations/geomap" >}}). +You can now measure both distances and areas on Geomap visualizations by using the panel's new [measure tools](../../panels-visualizations/visualizations/geomap/#show-measure-tools). +To learn more about the Geomap panel, see the [documentation](../../panels-visualizations/visualizations/geomap/). {{< figure src="/static/img/docs/geomap-panel/geomap-map-controls-measure-area-9-1-0.png" max-width="750px" caption="Geomap panel measuring tool - area" >}} @@ -135,7 +135,7 @@ We also embedded several links directly into the table. These links direct you to a Prometheus query to further investigate the data. We also provide a link from the table directly to Tempo search, making it easier for you to investigate your APM metrics. -To learn more about the APM table, see the [documentation]({{< relref "../datasources/tempo#apm-table" >}}). +To learn more about the APM table, see the [documentation](../../datasources/tempo/#apm-table). {{< figure src="/static/img/docs/panels/apm-table-9-1.png" max-width="750px" caption="An APM table in the Explore view" >}} @@ -172,7 +172,7 @@ Provisioning for Grafana Alerting currently supports these resources: - Text templates For more information, see the -[provisioning documentation]({{< relref "../administration/provisioning" >}}). +[provisioning documentation](../../administration/provisioning/). ## Grafana Enterprise @@ -188,7 +188,7 @@ Reporting is better in a few specific ways in Grafana version 9.1: For example, you can share last month's numbers as compared to the numbers for this month. The dashboard uses the same template variables if you attach the dashboard to a report twice. -To learn more about reporting, see the [documentation]({{< relref "../dashboards/share-dashboards-panels#reporting" >}}). +To learn more about reporting, see the [documentation](../../dashboards/share-dashboards-panels/#reporting). {{< figure src="/static/img/docs/enterprise/reporting-draft-9-1.png" max-width="750px" caption="Saving a report as a draft" >}} @@ -215,17 +215,17 @@ In v9.1, you can determine which users, teams, and roles can access app plugins > This definition is planned for a future release. You can also control who can view, edit, or administer dashboard and data source usage insights, as well as data source query caching configuration. -For more details, see the [RBAC documentation]({{< relref "../administration/roles-and-permissions/access-control" >}}). +For more details, see the [RBAC documentation](../../administration/roles-and-permissions/access-control/). {{< figure src="/static/img/docs/enterprise/rbac-app-plugins-9-1.png" max-width="750px" caption="Configuring role-based-access to app plugins" >}} #### Rotate your database encryption keys using Grafana's API -In Grafana version 9.0, we [revamped]({{< relref "./whats-new-in-v9-0#envelope-encryption-is-generally-available-and-enabled-by-default" >}}) the method Grafana uses to encrypt secrets, like data source credentials, so that you can rotate encryption keys and integrate with a key management system like Hashicorp Vault, AWS Key Management Service, or Azure Key Vault. +In Grafana version 9.0, we [revamped](../whats-new-in-v9-0/#envelope-encryption-is-generally-available-and-enabled-by-default) the method Grafana uses to encrypt secrets, like data source credentials, so that you can rotate encryption keys and integrate with a key management system like Hashicorp Vault, AWS Key Management Service, or Azure Key Vault. Now, you can rotate keys and re-encrypt secrets via API. This makes it easier to configure Grafana to be secure while deploying it. -To learn more, see our guide to [configuring database encryption]({{< relref "../setup-grafana/configure-security/configure-database-encryption#configure-database-encryption" >}}). +To learn more, see our guide to [configuring database encryption](../../setup-grafana/configure-security/configure-database-encryption/#configure-database-encryption). #### Audit all actions in Grafana using verbose logging @@ -233,7 +233,7 @@ Auditing logs helps you manage and mitigate activity and meet compliance require By default, Grafana emits an audit log with every action that changes something (like a user creating or updating a dashboard or updating another user's permissions). If you want to record all actions on the Grafana server, including GETs and page views, you can now turn on `verbose mode`. This results in more logs, but it can be useful to debug specific issues or make sure you catch everything happening in Grafana for security or compliance reasons. -To learn more, see the [configuration documentation]({{< relref "../setup-grafana/configure-grafana/enterprise-configuration#verbose" >}}). +To learn more, see the [configuration documentation](../../setup-grafana/configure-grafana/enterprise-configuration/#verbose). {{< figure src="/static/img/docs/enterprise/verbose-audit-logs-9-1.png" max-width="750px" caption="Verbose audit logging output" >}} @@ -242,7 +242,7 @@ To learn more, see the [configuration documentation]({{< relref "../setup-grafan When you synchronize users from a SAML, LDAP, or OAuth provider, some user settings, such as name and email address, are synchronized from your identity provider. Previously, you could edit those settings in the Grafana UI, but they would revert back. To make user management clearer, you can now see which settings are synchronized from your identity provider, but you cannot edit those settings. -To learn more about authentication, see the [documentation]({{< relref "../setup-grafana/configure-security/configure-authentication" >}}). +To learn more about authentication, see the [documentation](../../setup-grafana/configure-security/configure-authentication/). {{< figure src="/static/img/docs/enterprise/oauth-synced-user-9-1.png" max-width="750px" caption="Non-interactive view of a user synced via OAuth" >}} diff --git a/docs/sources/whatsnew/whats-new-in-v9-2.md b/docs/sources/whatsnew/whats-new-in-v9-2.md index deb8c3f836d..ae19c749c10 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-2.md +++ b/docs/sources/whatsnew/whats-new-in-v9-2.md @@ -45,7 +45,7 @@ Canvas visualizations are extensible form-built panels that allow you to explici For example, you can place image layers and then overlay text that's updated by Grafana data sources, and display icons that can change color conditionally based on data. -We've planned additional features and design elements for future releases to make Canvas panels even more powerful tools for creating custom, interactive, data-driven visualizations. To learn more about the Canvas panel, see the [documentation]({{< relref "../panels-visualizations/visualizations/canvas" >}}). +We've planned additional features and design elements for future releases to make Canvas panels even more powerful tools for creating custom, interactive, data-driven visualizations. To learn more about the Canvas panel, see the [documentation](../../panels-visualizations/visualizations/canvas/). {{< video-embed src="/static/img/docs/canvas-panel/canvas-beta-overview-9-2-0.mp4" max-width="750px" caption="Canvas panel beta overview" >}} @@ -145,8 +145,8 @@ For details on using this functionality, see [GitHub pull request #55313](https: ## Transformations: INNER JOINs -[Transformations]({{< relref "../panels-visualizations/query-transform-data/transform-data" >}}) allow you to shape raw data from data sources, like metrics series or GitHub issues, into a format that's appropriate for the chosen visualization. -We have extended the [Join transformation]({{< relref "../panels-visualizations/query-transform-data/transform-data#join-by-field" >}}) to support INNER JOINs in addition to OUTER JOINs. These work similarly to SQL JOINs. +[Transformations](../../panels-visualizations/query-transform-data/transform-data/) allow you to shape raw data from data sources, like metrics series or GitHub issues, into a format that's appropriate for the chosen visualization. +We have extended the [Join transformation](../../panels-visualizations/query-transform-data/transform-data/#join-by-field) to support INNER JOINs in addition to OUTER JOINs. These work similarly to SQL JOINs. {{< figure src="/static/img/docs/transformations/transform-outer-join-9-2.png" max-width="750px" caption="Query builder groupings for Google Cloud monitoring" >}} @@ -225,14 +225,14 @@ For more information, see the [authentication configuration documentation](/docs ## Match parameter support in prometheus labels API -Prometheus users running Prometheus v2.24 and higher can use the [labels endpoint](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values) instead of the [series endpoint](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers) for the [`label_values` function]({{< relref "../datasources/prometheus#query-variable" >}}). +Prometheus users running Prometheus v2.24 and higher can use the [labels endpoint](https://prometheus.io/docs/prometheus/latest/querying/api/#querying-label-values) instead of the [series endpoint](https://prometheus.io/docs/prometheus/latest/querying/api/#finding-series-by-label-matchers) for the [`label_values` function](../../datasources/prometheus/#query-variable). This decreases load times for templated high-cardinality Prometheus instances. -If you want to benefit from this endpoint you must first configure the Prometheus type and version in any Prometheus data sources' [configuration]({{< relref "../datasources/prometheus" >}}). +If you want to benefit from this endpoint you must first configure the Prometheus type and version in any Prometheus data sources' [configuration](../../datasources/prometheus/). ## New Prometheus streaming parser -In Grafana v9.2, you can enable the `prometheusStreamingJSONParser` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}}) to use a better-performing, memory-efficient streaming JSON client for Prometheus. +In Grafana v9.2, you can enable the `prometheusStreamingJSONParser` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles) to use a better-performing, memory-efficient streaming JSON client for Prometheus. We'll make this client the default in Grafana v9.3. When Prometheus returns `NaN` values, this new client doesn't change them, neither to the value `null` nor to `0` as in recent Grafana versions. diff --git a/docs/sources/whatsnew/whats-new-in-v9-3.md b/docs/sources/whatsnew/whats-new-in-v9-3.md index 929381d679b..91981f5cf41 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-3.md +++ b/docs/sources/whatsnew/whats-new-in-v9-3.md @@ -45,7 +45,7 @@ We have added four new languages to Grafana: Spanish, French, German, and Simpli With millions of users across the globe, Grafana has a global footprint. In order to make it accessible to a wider audience, we have taken the first steps in localizing key workflows. You can now set Grafana’s language for the navigation, viewing dashboards, and some settings. This will cover the main activities a Viewer performs within Grafana. -Read more about configuring the [default language for your organization]({{< relref "../administration/organization-preferences" >}}) and [updating your profile]({{< relref "../administration/user-management/user-preferences" >}}) in our documentation. +Read more about configuring the [default language for your organization](../../administration/organization-preferences/) and [updating your profile](../../administration/user-management/user-preferences/) in our documentation. {{< figure src="/static/img/docs/internationalization/internationalization-9-3.png" max-width="750px" caption="Grafana available in Spanish, French, German, and Simplified Chinese" >}} @@ -53,7 +53,7 @@ Read more about configuring the [default language for your organization]({{< rel Generally available in all editions of Grafana -We have added a new alpha layer type in Geomap called photo layer. This layer enables you to render a photo at each data point. To learn more about the photo layer and the geomap panel, refer to [Photos layer]({{< relref "../panels-visualizations/visualizations/geomap#photos-layer-alpha" >}}). +We have added a new alpha layer type in Geomap called photo layer. This layer enables you to render a photo at each data point. To learn more about the photo layer and the geomap panel, refer to [Photos layer](../../panels-visualizations/visualizations/geomap/#photos-layer-alpha). {{< figure src="/static/img/docs/geomap-panel/geomap-photos-9-3-0.png" max-width="750px" caption="Geomap panel photos layer" >}} @@ -63,7 +63,7 @@ Available in **beta** in all editions of Grafana Canvas is a new panel that combines the power of Grafana with the flexibility of custom elements. Canvas visualizations are extensible form-built panels that allow you to explicitly place elements within static and dynamic layouts. This empowers you to design custom visualizations and overlay data in ways that aren’t possible with standard Grafana panels, all within Grafana’s UI. If you’ve used popular UI and web design tools, then designing Canvas panels will feel very familiar. -In Grafana v9.3, we have added icon value mapping support to the Canvas panel. This enables you to dynamically set which icon to display based on your data. To learn more about the Canvas panel, refer to [Canvas]({{< relref "../panels-visualizations/visualizations/canvas" >}}). +In Grafana v9.3, we have added icon value mapping support to the Canvas panel. This enables you to dynamically set which icon to display based on your data. To learn more about the Canvas panel, refer to [Canvas](../../panels-visualizations/visualizations/canvas/). {{< video-embed src="/static/img/docs/canvas-panel/canvas-icon-value-mapping-support-9-3-0.mp4" max-width="750px" caption="Canvas panel icon value mapping support" >}} @@ -85,7 +85,7 @@ Available in **experimental** in Grafana Open Source, Enterprise, and Cloud Adva Annotations are now supported in public dashboards, with the exception of query annotations. They are turned off by default, but can be turned on in your public dashboard settings. -Note that because Public Dashboards is an experimental feature, you need to enable it in Grafana using the `publicDashboards` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}}), or open a support ticket requesting public dashboards if you are a Cloud Advanced customer. +Note that because Public Dashboards is an experimental feature, you need to enable it in Grafana using the `publicDashboards` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles), or open a support ticket requesting public dashboards if you are a Cloud Advanced customer. To learn more about public dashboards, refer to [Public dashboards](https://grafana.com/docs/grafana//dashboards/share-dashboards-panels/shared-dashboards/). @@ -135,7 +135,7 @@ Generally available in Grafana Enterprise, Cloud Pro, and Cloud Advanced. Because dashboards appear on a screen and reports are PDFs, it can be challenging to render data just the way you want to. Sometimes the report doesn't show enough columns in a table, or the titles appear too small. Now you can adjust the scale of your report to zoom in and make each text field and panel larger or zoom out to show more data. -The zoom feature is located in the **Format Report** section of your reporting configuration. To learn more about reporting, refer to [Create and manage reports]({{< relref "../dashboards/create-reports" >}}). +The zoom feature is located in the **Format Report** section of your reporting configuration. To learn more about reporting, refer to [Create and manage reports](../../dashboards/create-reports/). {{< figure src="/static/img/docs/enterprise/reports/report-zoom.png" max-width="750px" caption="Report zoom feature with PDF documents at three different zoom levels" >}} @@ -151,7 +151,7 @@ As part of our efforts to improve the security of Grafana, we are introducing a Because this feature introduces a breaking change, it is behind the `accessTokenExpirationCheck` feature toggle and is disabled by default. Enabling this functionality without configuring refresh tokens for the specific OAuth provider will sign users out after their access token has expired, and they would need to sign in again every time. -Complete documentation on how to configure obtaining a refresh token can be found on the [authentication configuration page]({{< relref "../setup-grafana/configure-security/configure-authentication" >}}), in the instructions for your Oauth identity provider. +Complete documentation on how to configure obtaining a refresh token can be found on the [authentication configuration page](../../setup-grafana/configure-security/configure-authentication/), in the instructions for your Oauth identity provider. ### Resolve user conflicts in Grafana's CLI @@ -181,8 +181,7 @@ If you use an LDAP directory to authenticate to Grafana but prefer to assign org or via API, you can now skip user organization role synchronization with your LDAP directory. -Use the `skip_org_role_sync` [LDAP authentication configuration option]({{< relref -"../setup-grafana/configure-security/configure-authentication/ldap#disable-org-role-synchronization" >}}) +Use the `skip_org_role_sync` [LDAP authentication configuration option](../../setup-grafana/configure-security/configure-authentication/ldap/#disable-org-role-synchronization) when configuring LDAP authentication to prevent the synchronization between your LDAP groups and organization roles and make user roles editable manually. @@ -193,8 +192,7 @@ Generally available in all editions of Grafana If you use Azure AD OAuth2 authentication and use `SecurityEnabled` groups that you don't want Azure to embed in the authentication token, you can configure Grafana to use Microsoft's Graph API instead. -Use the [`force_use_graph_api` configuration option]({{< relref -"../setup-grafana/configure-security/configure-authentication/azuread#force-fetching-groups-from-microsoft-graph-api" >}}) +Use the [`force_use_graph_api` configuration option](../../setup-grafana/configure-security/configure-authentication/azuread/#force-fetching-groups-from-microsoft-graph-api) when configuring Azure AD authentication to force Grafana to fetch groups using Graph API. ### RBAC: List token's permissions @@ -202,23 +200,22 @@ when configuring Azure AD authentication to force Grafana to fetch groups using Generally available in Grafana Enterprise and Cloud Advanced We added a new endpoint to help users diagnose permissions-related issues with user and token authorization. -[This endpoint]({{< relref "../developers/http_api/access_control#list-your-permissions" >}}) allows users to get the +[This endpoint](../../developers/http_api/access_control/#list-your-permissions) allows users to get the full list of RBAC permissions associated with their token. -For more details, refer to [Debug the permissions of a service account token]({{< relref -"../administration/service-accounts#debug-the-permissions-of-a-service-account-token" >}}). +For more details, refer to [Debug the permissions of a service account token](../../administration/service-accounts/#debug-the-permissions-of-a-service-account-token). ### RBAC with Terraform: Extended support for provisioning permissions Generally available in Grafana Enterprise and Cloud Advanced -All Grafana users can now use the latest release of [Terraform's Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) (version 1.31.1+) to provision [user and team access to service accounts]({{< relref "../administration/service-accounts#manage-users-and-teams-permissions-for-a-service-account-in-grafana" >}}). +All Grafana users can now use the latest release of [Terraform's Grafana provider](https://registry.terraform.io/providers/grafana/grafana/latest/docs) (version 1.31.1+) to provision [user and team access to service accounts](../../administration/service-accounts/#manage-users-and-teams-permissions-for-a-service-account-in-grafana). This allows full management of service accounts through Terraform - from creating a service account and allowing users to access it to assigning roles to the service account and generating service account tokens. -Grafana Enterprise and Cloud Pro and Advanced users can now provision [access to data sources]({{< relref "../administration/data-source-management#data-source-permissions" >}}) for Grafana's `Viewer`, `Editor`, and `Admin` basic roles, as well as assign `Edit` permission. +Grafana Enterprise and Cloud Pro and Advanced users can now provision [access to data sources](../../administration/data-source-management/#data-source-permissions) for Grafana's `Viewer`, `Editor`, and `Admin` basic roles, as well as assign `Edit` permission. -We have also added [documentation on provisioning RBAC roles and role assignments]({{< relref "../administration/roles-and-permissions/access-control/rbac-terraform-provisioning" >}}) to guide our Grafana Enterprise and Cloud Pro and Advanced users through this process. +We have also added [documentation on provisioning RBAC roles and role assignments](../../administration/roles-and-permissions/access-control/rbac-terraform-provisioning/) to guide our Grafana Enterprise and Cloud Pro and Advanced users through this process. Finally, we have fixed several access control related bugs to ensure a smoother provisioning experience. diff --git a/docs/sources/whatsnew/whats-new-in-v9-4.md b/docs/sources/whatsnew/whats-new-in-v9-4.md index 4f6e9fb5e59..62717c01fd2 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-4.md +++ b/docs/sources/whatsnew/whats-new-in-v9-4.md @@ -31,17 +31,17 @@ The command palette has been updated to provide a more efficient way to navigate To launch the command palette, use the keyboard shortcut `cmd + K` on Mac or `ctrl + K` on Linux/Windows. -To learn more about the command palette, refer to [Search]({{< relref "../search" >}}). +To learn more about the command palette, refer to [Search](../../search/). {{< figure src="/media/docs/grafana/screenshot-grafana-94-command-palette.png" max-width="750px" caption="Grafana command palette" >}} ### New navigation -_Generally available on Grafana Cloud, and available to preview using the `topnav` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}}) in all editions of Grafana._ +_Generally available on Grafana Cloud, and available to preview using the `topnav` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles) in all editions of Grafana._ The navigation in Grafana has been updated with a new design and an improved structure to make it easier for you to access the data you need. With this update, you'll be able to quickly navigate between features, giving you full visibility into the health of your systems. -The new navigation is gradually rolling out to all users on Grafana Cloud. If you’re using Grafana Open Source and Enterprise, you can enable this feature using the `topnav` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}}). +The new navigation is gradually rolling out to all users on Grafana Cloud. If you’re using Grafana Open Source and Enterprise, you can enable this feature using the `topnav` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles). > **Note:** The Grafana documentation has not yet been updated to reflect changes to the navigation. @@ -51,11 +51,11 @@ The new navigation is gradually rolling out to all users on Grafana Cloud. If yo ## Dashboards and visualizations -We've made the following changes to dashboards and visualizations. Learn more about dashboards in our [dashboards documentation]({{< relref "../dashboards" >}}). +We've made the following changes to dashboards and visualizations. Learn more about dashboards in our [dashboards documentation](../../dashboards/). ### Dashboard panel redesign -_Available to preview using the `newPanelChromeUI` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}}) in all editions of Grafana_. +_Available to preview using the `newPanelChromeUI` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles) in all editions of Grafana_. Dashboard panels contain a lot of information, some of which is difficult to discover or access from the dashboard. With our redesigned panels, we've improved accessibility and made it easier to understand the status of a panel by adding and moving key elements. @@ -69,7 +69,7 @@ However, we have more planned: we’re going to make even more improvements to t ### New data source connection page in Dashboards and Explore -_Available to preview using the `datasourceOnboarding` [feature toggle]({{< relref "../setup-grafana/configure-grafana#feature_toggles" >}})._ +_Available to preview using the `datasourceOnboarding` [feature toggle](../../setup-grafana/configure-grafana/#feature_toggles)._ When you start your journey to create a dashboard or explore your data, but you don't have a data source connected yet, you’ll be shown a page that guides you to set up a first connection. @@ -85,7 +85,7 @@ We've updated the **Details** section of a log line. Previously some of the inte {{< figure src="/static/img/logs/log-details-whats-new-9-4.png" max-width="750px" caption="Log details redesign with interactions" >}} -Learn more about viewing logs in our [Logs panel documentation]({{< relref "../panels-visualizations/visualizations/logs" >}}). +Learn more about viewing logs in our [Logs panel documentation](../../panels-visualizations/visualizations/logs/). ### Loki datasource query validation @@ -95,7 +95,7 @@ We added support to validate queries and visually display errors as a query is b {{< figure src="/media/docs/grafana/logs-loki-query-validation-whats-new-9-4.png" max-width="750px" caption="Loki query validation" >}} -Learn more about viewing logs in our [Logs panel documentation]({{< relref "../panels-visualizations/visualizations/logs" >}}). +Learn more about viewing logs in our [Logs panel documentation](../../panels-visualizations/visualizations/logs/). ### Loki logs sample in Explore @@ -111,7 +111,7 @@ _Available in **beta** in all editions of Grafana_ Canvas is a new panel that combines the power of Grafana with the flexibility of custom elements. Canvas visualizations are extensible form-built panels that allow you to explicitly place elements within static and dynamic layouts. This empowers you to design custom visualizations and overlay data in ways that aren’t possible with standard Grafana panels, all within Grafana’s UI. If you’ve used popular UI and web design tools, then designing Canvas panels will feel very familiar. -In Grafana v9.4, we have added the ability to create connections (arrows). Connections enable you to connect elements together to create more complex visualizations. We also added support for data links and a brand new server element. To learn more about the Canvas panel, refer to [Canvas]({{< relref "../panels-visualizations/visualizations/canvas" >}}). +In Grafana v9.4, we have added the ability to create connections (arrows). Connections enable you to connect elements together to create more complex visualizations. We also added support for data links and a brand new server element. To learn more about the Canvas panel, refer to [Canvas](../../panels-visualizations/visualizations/canvas/). {{< video-embed src="/media/docs/grafana/canvas-connections-9-4-0.mp4" max-width="750px" caption="Canvas panel connections" >}} @@ -127,7 +127,7 @@ We have added a configuration option that enables you to require an expiration d This change will not affect existing tokens. However, newly created tokens will require an expiration date that doesn't exceed the configuration option `token_expiration_day_limit`. This option is disabled by default. -Learn more about service accounts in our [Service account documentation]({{< relref "../administration/service-accounts" >}}). +Learn more about service accounts in our [Service account documentation](../../administration/service-accounts/). ### OAuth providers setting for skip org role sync @@ -135,7 +135,7 @@ While Grafana integrates with many different auth providers, we have received re This option enables you to skip synchronization from your configured OAuth provider specifically in the auth provider section under `skip_org_role_sync`. Previously users could only do this for certain providers using the `oauth_skip_org_role_sync_update` option, but this would include all of the configured providers. -Learn more about Oauth in our [Oauth configuration guide]({{< relref "../setup-grafana/configure-security/configure-authentication/generic-oauth" >}}). +Learn more about Oauth in our [Oauth configuration guide](../../setup-grafana/configure-security/configure-authentication/generic-oauth/). ### RBAC support for Grafana OnCall plugin @@ -146,7 +146,7 @@ Before RBAC support in Grafana OnCall, it was only possible to allow your organi For example, you can assign a Viewer basic role to a user in your organization (users must still have a basic role assigned) and also assign them the new Grafana OnCall RBAC role of **Schedules Editor**. This assignment enables the user to view everything in Grafana OnCall, and edit OnCall schedules. -Learn more about role-based access control in our [RBAC docs]({{< relref "../administration/roles-and-permissions/access-control" >}}). +Learn more about role-based access control in our [RBAC docs](../../administration/roles-and-permissions/access-control/). ### SAML auto login @@ -154,13 +154,13 @@ We've added auto-login support for SAML authentication, which you can turn on wi have a unified configuration style among all authentication providers. Instead of using `oauth_auto_login`, use the new `auto_login` option to enable automatic login for specific OAuth providers. -Learn more about SAML setup in our [SAML configuration guide]({{< relref "../setup-grafana/configure-security/configure-authentication/saml" >}}). +Learn more about SAML setup in our [SAML configuration guide](../../setup-grafana/configure-security/configure-authentication/saml/). ## Auditing and Usage Insights: Support for Loki multi-tenancy _This feature is available for Enterprise customers_ -This feature adds support to push analytics events and auditing logs to Loki with multi-tenancy mode, by specifying a tenant id. Learn more about [auditing]({{< relref "../setup-grafana/configure-security/audit-grafana" >}}) and [usage insights]({{< relref "../setup-grafana/configure-security/export-logs" >}}) in our docs. +This feature adds support to push analytics events and auditing logs to Loki with multi-tenancy mode, by specifying a tenant id. Learn more about [auditing](../../setup-grafana/configure-security/audit-grafana/) and [usage insights](../../setup-grafana/configure-security/export-logs/) in our docs. ## Reporting: Zoom in and out on your dashboard in a report PDF @@ -173,11 +173,11 @@ You can modify the scale factor for each report in the report editor when you sh {{< figure src="/media/docs/grafana/FormatReportShare9.4.png" max-width="750px" caption="Scale factor feature in Share functionality" >}} -Learn more about reporting in our [documentation]({{< relref "../dashboards/create-reports" >}}) +Learn more about reporting in our [documentation](../../dashboards/create-reports/) ## Alerting -We've made major improvements to Grafana Alerts, from new contact points and search options to improved workflows between Alerting and OnCall. For all the details, refer to our [Alerting documentation]({{< relref "../alerting" >}}). +We've made major improvements to Grafana Alerts, from new contact points and search options to improved workflows between Alerting and OnCall. For all the details, refer to our [Alerting documentation](../../alerting/). ### Alerting: alert rules @@ -271,7 +271,7 @@ Grafana Alerting is now compatible with AWS Aurora, but does not provide technic ## Enterprise Datasources -We've made improvements to all [Enterprise Datasources]({{< relref "../introduction/grafana-enterprise#enterprise-data-sources" >}}), fixing small bugs, and updating libraries. We've also added many new features and support for additional APIs. Refer to each datasource's documentation and the change log for additional information. +We've made improvements to all [Enterprise Datasources](../../introduction/grafana-enterprise/#enterprise-data-sources), fixing small bugs, and updating libraries. We've also added many new features and support for additional APIs. Refer to each datasource's documentation and the change log for additional information. ### DataDog Datasource diff --git a/docs/sources/whatsnew/whats-new-in-v9-5.md b/docs/sources/whatsnew/whats-new-in-v9-5.md index 36751d91b5a..c2c2ff159ae 100644 --- a/docs/sources/whatsnew/whats-new-in-v9-5.md +++ b/docs/sources/whatsnew/whats-new-in-v9-5.md @@ -19,7 +19,7 @@ weight: -36 Welcome to Grafana 9.5! We're excited to share some major updates to Grafana's navigation, tons of usability improvements to Alerting, and some promising experiments to help you query your Prometheus metrics. Also, read on to learn about our continued migration from API keys to service accounts, as well as deprecation of plugins that use Angular and a field in the InfluxDB data source. -For more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v9.5, check out our [Upgrade Guide]({{< relref "../upgrade-guide/upgrade-v9.5/index.md" >}}). +For more detail about all the changes in this release, refer to the [changelog](https://github.com/grafana/grafana/blob/main/CHANGELOG.md). For the specific steps we recommend when you upgrade to v9.5, check out our [Upgrade Guide](../../upgrade-guide/upgrade-v9.5/). [[end]] - [[range $asset := .Assets.JSFiles]] - + [[if .Settings.FeatureToggles.assetSriChecks ]] + [[range $asset := .Assets.JSFiles]] + + [[end]] + [[else]] + [[range $asset := .Assets.JSFiles]] + + [[end]] [[end]]