merge main
This commit is contained in:
@@ -6,18 +6,20 @@ const jsxA11yPlugin = require('eslint-plugin-jsx-a11y');
|
||||
const lodashPlugin = require('eslint-plugin-lodash');
|
||||
const barrelPlugin = require('eslint-plugin-no-barrel-files');
|
||||
const reactPlugin = require('eslint-plugin-react');
|
||||
const hooksPlugin = require('eslint-plugin-react-hooks');
|
||||
const testingLibraryPlugin = require('eslint-plugin-testing-library');
|
||||
|
||||
const grafanaConfig = require('@grafana/eslint-config/flat');
|
||||
const grafanaPlugin = require('@grafana/eslint-plugin');
|
||||
const grafanaI18nPlugin = require('@grafana/i18n/eslint-plugin');
|
||||
|
||||
// Include the Grafana config and remove the rules,
|
||||
// Include the base Grafana configs and remove the rules,
|
||||
// as we just want to pull in all of the necessary configuration but not run the rules
|
||||
// (this should only be concerned with checking rules that we want to improve,
|
||||
// so there's no need to try and run the rules that will be linted properly anyway)
|
||||
const { rules, ...baseConfig } = grafanaConfig.find((config) => config?.name === '@grafana/eslint-config/flat');
|
||||
const mappedBaseConfigs = grafanaConfig.map((config) => {
|
||||
const { rules, ...baseConfig } = config;
|
||||
return baseConfig;
|
||||
});
|
||||
|
||||
/**
|
||||
* @type {Array<import('eslint').Linter.Config>}
|
||||
@@ -50,22 +52,13 @@ module.exports = [
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'react/jsx-runtime',
|
||||
// @ts-ignore - not sure why but flat config is typed as a maybe?
|
||||
...reactPlugin.configs.flat['jsx-runtime'],
|
||||
},
|
||||
// FIXME: Remove once eslint-config-grafana is updated to include correct plugin
|
||||
{
|
||||
name: 'react-hooks-plugin',
|
||||
plugins: {
|
||||
'react-hooks': hooksPlugin,
|
||||
},
|
||||
name: 'react/jsx-runtime-rules',
|
||||
rules: reactPlugin.configs.flat['jsx-runtime'].rules,
|
||||
},
|
||||
...mappedBaseConfigs,
|
||||
{
|
||||
files: ['**/*.{ts,tsx,js}'],
|
||||
...baseConfig,
|
||||
plugins: {
|
||||
...baseConfig.plugins,
|
||||
'@emotion': emotionPlugin,
|
||||
lodash: lodashPlugin,
|
||||
jest: jestPlugin,
|
||||
@@ -85,6 +78,7 @@ module.exports = [
|
||||
{
|
||||
files: ['**/*.{js,jsx,ts,tsx}'],
|
||||
rules: {
|
||||
'react-hooks/rules-of-hooks': 'error',
|
||||
'@typescript-eslint/no-explicit-any': 'error',
|
||||
'@grafana/no-aria-label-selectors': 'error',
|
||||
'no-restricted-imports': [
|
||||
|
||||
+172
-8
@@ -548,6 +548,16 @@ exports[`better eslint`] = {
|
||||
"packages/grafana-runtime/src/utils/queryResponse.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"packages/grafana-runtime/src/utils/useFavoriteDatasources.ts:5381": [
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "0"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "1"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "2"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "3"],
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "4"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "5"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "6"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "7"]
|
||||
],
|
||||
"packages/grafana-runtime/src/utils/userStorage.tsx:5381": [
|
||||
[0, 0, 0, "Direct usage of localStorage is not allowed. import store from @grafana/data instead", "0"],
|
||||
[0, 0, 0, "Direct usage of localStorage is not allowed. import store from @grafana/data instead", "1"],
|
||||
@@ -596,6 +606,20 @@ exports[`better eslint`] = {
|
||||
[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/Combobox/Combobox.story.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "2"],
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "3"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "4"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/MultiCombobox.story.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "2"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "3"],
|
||||
[0, 0, 0, "React Hook \\"useArgs\\" is called in function \\"render\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "4"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Combobox/MultiCombobox.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@@ -616,6 +640,33 @@ exports[`better eslint`] = {
|
||||
[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/ElementSelectionContext/ElementSelectionContext.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "0"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "1"],
|
||||
[0, 0, 0, "React Hook \\"useContext\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "2"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/Form.story.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "2"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "3"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "4"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "5"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "6"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "7"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"renderForm\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "8"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/InlineField.story.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"basic: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"error: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"grow: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "2"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"multiple: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "3"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"multiple: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "4"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"multiple: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "5"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"withCombobox: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "6"],
|
||||
[0, 0, 0, "React Hook \\"useId\\" is called in function \\"withTooltip: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "7"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" is called in function \\"withCombobox: StoryFn<typeof InlineField>\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "8"]
|
||||
],
|
||||
"packages/grafana-ui/src/components/Forms/Legacy/Input/Input.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
@@ -864,7 +915,10 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/api/clients/folder/v1beta1/hooks.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useGetDisplayMappingQuery\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "1"],
|
||||
[0, 0, 0, "React Hook \\"useGetFolderParentsQuery\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "2"],
|
||||
[0, 0, 0, "React Hook \\"useGetFolderQuery\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "3"]
|
||||
],
|
||||
"public/app/core/TableModel.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
@@ -1274,6 +1328,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/receivers/TemplatePreview.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called in function \\"getPreviewResults\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/receivers/form/ChannelOptions.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"],
|
||||
@@ -1403,6 +1460,9 @@ exports[`better eslint`] = {
|
||||
"public/app/features/alerting/unified/components/rule-editor/rule-types/RuleType.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/rule-viewer/RuleViewer.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called in function \\"createMetadata\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/alerting/unified/components/rules/Filter/RulesFilter.v1.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -1554,6 +1614,18 @@ exports[`better eslint`] = {
|
||||
"public/app/features/browse-dashboards/components/NewFolderForm.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/commandPalette/actions/recentScopesActions.ts:5381": [
|
||||
[0, 0, 0, "React Hook \\"useScopesServices\\" is called in function \\"getRecentScopesActions\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/commandPalette/actions/scopeActions.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useGlobalScopesSearch\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useRegisterActions\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "1"],
|
||||
[0, 0, 0, "React Hook \\"useScopeTreeActions\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "2"],
|
||||
[0, 0, 0, "React Hook \\"useScopesRow\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "3"]
|
||||
],
|
||||
"public/app/features/commandPalette/actions/scopesUtils.ts:5381": [
|
||||
[0, 0, 0, "React Hook \\"useObservable\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"]
|
||||
],
|
||||
"public/app/features/connections/components/ConnectionsRedirectNotice/index.ts:5381": [
|
||||
[0, 0, 0, "Do not use export all (\`export * from ...\`)", "0"]
|
||||
],
|
||||
@@ -1633,9 +1705,23 @@ exports[`better eslint`] = {
|
||||
"public/app/features/dashboard-scene/edit-pane/DashboardEditPaneRenderer.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/edit-pane/DashboardEditPaneSplitter.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "1"],
|
||||
[0, 0, 0, "React Hook \\"useSceneObjectState\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "2"],
|
||||
[0, 0, 0, "React Hook \\"useSnappingSplitter\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "3"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/edit-pane/DashboardEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useLayoutCategory\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/edit-pane/DashboardOutline.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/edit-pane/VizPanelEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/inspect/HelpWizard/HelpWizard.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -1645,7 +1731,8 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/inspect/InspectJsonTab.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/pages/DashboardScenePage.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
@@ -1662,7 +1749,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/panel-edit/PanelOptionsPane.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"],
|
||||
[0, 0, 0, "React Hook \\"useToggle\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "2"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/panel-edit/PanelVizTypePicker.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
@@ -1673,6 +1762,9 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "2"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "3"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/saving/SaveDashboardDrawer.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useIsProvisionedNG\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/saving/SaveDashboardForm.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
@@ -1712,21 +1804,39 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "10"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridItemEditor.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useConditionalRenderingEditor\\" is called in function \\"getOptions\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-auto-grid/AutoGridLayoutManagerEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "2"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "3"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-default/DashboardGridItemEditor.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useConditionalRenderingEditor\\" is called in function \\"getDashboardGridItemOptions\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-default/SceneGridRowEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-default/row-actions/RowOptionsForm.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-rows/RowItem.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useEditOptions\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-rows/RowItemEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useConditionalRenderingEditor\\" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-tabs/TabItem.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useEditOptions\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/scene/layout-tabs/TabItemEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useConditionalRenderingEditor\\" cannot be called inside a callback. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/serialization/angularMigration.test.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
@@ -1751,6 +1861,15 @@ exports[`better eslint`] = {
|
||||
"public/app/features/dashboard-scene/serialization/transformToV1TypesUtils.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/GeneralSettingsEditView.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useDashboardEditPageNav\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/JsonModelEditView.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useDashboardEditPageNav\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useSaveDashboard\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"],
|
||||
[0, 0, 0, "React Hook \\"useState\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "2"],
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "3"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/annotations/AnnotationSettingsEdit.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"],
|
||||
@@ -1772,11 +1891,19 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "8"],
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "9"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/variables/LocalVariableEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "0"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/variables/VariableEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useLocalVariableOptions\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "2"],
|
||||
[0, 0, 0, "React Hook \\"useVariableSelectionOptionsCategory\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "3"],
|
||||
[0, 0, 0, "React Hook \\"useVariableTypeCategory\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "4"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/variables/VariableSetEditableElement.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" cannot be called in a class component. React Hooks must be called in a React function component or a custom React Hook function.", "1"]
|
||||
],
|
||||
"public/app/features/dashboard-scene/settings/variables/components/AdHocVariableForm.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
@@ -2231,6 +2358,10 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"],
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "1"]
|
||||
],
|
||||
"public/app/features/datasources/components/EditDataSource.test.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called in function \\"component\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"],
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called in function \\"component\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "1"]
|
||||
],
|
||||
"public/app/features/datasources/components/picker/DataSourceCard.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
@@ -2311,9 +2442,16 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/features/explore/TraceView/components/TracePageHeader/TracePageHeader.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"],
|
||||
[0, 0, 0, "React Hook \\"usePluginLinks\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "1"]
|
||||
],
|
||||
"public/app/features/explore/TraceView/components/TracePageHeader/index.tsx:5381": [
|
||||
[0, 0, 0, "Do not re-export imported variable (\`./TracePageHeader\`)", "0"]
|
||||
],
|
||||
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanDetail/SpanDetailLinkButtons.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"usePluginLinks\\" is called in function \\"getSpanDetailLinkButtons\\" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word \\"use\\".", "0"]
|
||||
],
|
||||
"public/app/features/explore/TraceView/components/TraceTimelineViewer/SpanLinks.tsx:5381": [
|
||||
[0, 0, 0, "Using localeCompare() can cause performance issues when sorting large datasets. Consider using Intl.Collator for better performance when sorting arrays, or add an eslint-disable comment if sorting a small, known dataset.", "0"]
|
||||
],
|
||||
@@ -2424,6 +2562,19 @@ exports[`better eslint`] = {
|
||||
"public/app/features/live/centrifuge/channel.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
],
|
||||
"public/app/features/logs/components/panel/LogLineDetailsFields.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "1"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "2"],
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "3"],
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "4"],
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "5"]
|
||||
],
|
||||
"public/app/features/logs/components/panel/LogList.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "0"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "1"],
|
||||
[0, 0, 0, "React Hook \\"useCallback\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "2"]
|
||||
],
|
||||
"public/app/features/logs/logsFrame.ts:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
@@ -2615,14 +2766,24 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "1"]
|
||||
],
|
||||
"public/app/features/provisioning/GettingStarted/Sidebar.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/GettingStarted/SidebarItem.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Card components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Job/JobContent.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useEffect\\" is called conditionally. React Hooks must be called in the exact same order in every component render. Did you accidentally call a React Hook after an early return?", "0"]
|
||||
],
|
||||
"public/app/features/provisioning/Job/RecentJobs.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useMemo\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "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"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "2"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "3"]
|
||||
[0, 0, 0, "React Hook \\"usePluginComponents\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "3"],
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "4"]
|
||||
],
|
||||
"public/app/features/query/components/QueryEditorRowHeader.tsx:5381": [
|
||||
[0, 0, 0, "Use data-testid for E2E selectors instead of aria-label", "0"]
|
||||
@@ -2793,6 +2954,9 @@ exports[`better eslint`] = {
|
||||
"public/app/features/transformers/editors/GroupToNestedTableTransformerEditor.tsx:5381": [
|
||||
[0, 0, 0, "Add noMargin prop to Field components to remove built-in margins. Use layout components like Stack or Grid with the gap prop instead for consistent spacing.", "0"]
|
||||
],
|
||||
"public/app/features/transformers/editors/OrganizeFieldsTransformerEditor.tsx:5381": [
|
||||
[0, 0, 0, "React Hook \\"useStyles2\\" is called conditionally. React Hooks must be called in the exact same order in every component render.", "0"]
|
||||
],
|
||||
"public/app/features/transformers/editors/ReduceTransformerEditor.tsx:5381": [
|
||||
[0, 0, 0, "Do not use any type assertions.", "0"]
|
||||
],
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
|
||||
# Ignore everything
|
||||
*
|
||||
|
||||
# But not these files:
|
||||
!.gitignore
|
||||
!*.mod
|
||||
!*.sum
|
||||
!README.md
|
||||
!Variables.mk
|
||||
!variables.env
|
||||
|
||||
*tmp.mod
|
||||
@@ -1,14 +0,0 @@
|
||||
# Project Development Dependencies.
|
||||
|
||||
This is directory which stores Go modules with pinned buildable package that is used within this repository, managed by https://github.com/bwplotka/bingo.
|
||||
|
||||
- Run `bingo get` to install all tools having each own module file in this directory.
|
||||
- Run `bingo get <tool>` to install <tool> that have own module file in this directory.
|
||||
- For Makefile: Make sure to put `include .bingo/Variables.mk` in your Makefile, then use $(<upper case tool name>) variable where <tool> is the .bingo/<tool>.mod.
|
||||
- For shell: Run `source .bingo/variables.env` to source all environment variable for each tool.
|
||||
- For go: Import `.bingo/variables.go` to for variable names.
|
||||
- See https://github.com/bwplotka/bingo or -h on how to add, remove or change binaries dependencies.
|
||||
|
||||
## Requirements
|
||||
|
||||
- Go 1.14+
|
||||
@@ -1,25 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
BINGO_DIR := $(dir $(lastword $(MAKEFILE_LIST)))
|
||||
GOPATH ?= $(shell go env GOPATH)
|
||||
GOBIN ?= $(firstword $(subst :, ,${GOPATH}))/bin
|
||||
GO ?= $(shell which go)
|
||||
|
||||
# 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 drone variable:
|
||||
#
|
||||
# In your main Makefile (for non array binaries):
|
||||
#
|
||||
#include .bingo/Variables.mk # Assuming -dir was set to .bingo .
|
||||
#
|
||||
#command: $(DRONE)
|
||||
# @echo "Running drone"
|
||||
# @$(DRONE) <flags/args..>
|
||||
#
|
||||
DRONE := $(GOBIN)/drone-v1.5.0
|
||||
$(DRONE): $(BINGO_DIR)/drone.mod
|
||||
@# Install binary/ries using Go 1.14+ build command. This is using bwplotka/bingo-controlled, separate go module with pinned dependencies.
|
||||
@echo "(re)installing $(GOBIN)/drone-v1.5.0"
|
||||
@cd $(BINGO_DIR) && GOWORK=off CGO_ENABLED=0 $(GO) build -mod=mod -modfile=drone.mod -o=$(GOBIN)/drone-v1.5.0 "github.com/drone/drone-cli/drone"
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
module _ // Auto generated by https://github.com/bwplotka/bingo. DO NOT EDIT
|
||||
|
||||
go 1.17
|
||||
|
||||
replace github.com/docker/docker => github.com/docker/engine v17.12.0-ce-rc1.0.20200309214505-aa6a9891b09c+incompatible
|
||||
|
||||
require github.com/drone/drone-cli v1.5.0 // drone CGO_ENABLED=0
|
||||
-1010
File diff suppressed because it is too large
Load Diff
@@ -1 +0,0 @@
|
||||
module _ // Fake go.mod auto-created by 'bingo' for go -moddir compatibility with non-Go projects. Commit this file, together with other .mod files.
|
||||
@@ -1,12 +0,0 @@
|
||||
# Auto generated binary variables helper managed by https://github.com/bwplotka/bingo v0.9. DO NOT EDIT.
|
||||
# All tools are designed to be build inside $GOBIN.
|
||||
# Those variables will work only until 'bingo get' was invoked, or if tools were installed via Makefile's Variables.mk.
|
||||
GOBIN=${GOBIN:=$(go env GOBIN)}
|
||||
|
||||
if [ -z "$GOBIN" ]; then
|
||||
GOBIN="$(go env GOPATH)/bin"
|
||||
fi
|
||||
|
||||
|
||||
DRONE="${GOBIN}/drone-v1.5.0"
|
||||
|
||||
@@ -58,7 +58,6 @@
|
||||
/go.sum @grafana/grafana-backend-group
|
||||
/go.work @grafana/grafana-app-platform-squad
|
||||
/go.work.sum @grafana/grafana-app-platform-squad
|
||||
/.bingo/ @grafana/grafana-backend-group
|
||||
/.citools @grafana/grafana-developer-enablement-squad
|
||||
/pkg/README.md @grafana/grafana-backend-group
|
||||
/pkg/ruleguard.rules.go @grafana/grafana-backend-group
|
||||
|
||||
@@ -98,7 +98,6 @@ runs:
|
||||
- 'proto/**'
|
||||
- '**/Makefile'
|
||||
- 'scripts/**'
|
||||
- '!scripts/drone/**'
|
||||
- '!**.md'
|
||||
- '.github/actions/change-detection/**'
|
||||
- '**.cue'
|
||||
@@ -123,7 +122,6 @@ runs:
|
||||
- 'scripts/**'
|
||||
- '!**.md'
|
||||
- '.citools/**'
|
||||
- '.bingo/**'
|
||||
- '.github/actions/change-detection/**'
|
||||
- '${{ inputs.self }}'
|
||||
docs:
|
||||
|
||||
@@ -71,16 +71,6 @@
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/build-packaging"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
"scripts/*.star",
|
||||
".drone.star",
|
||||
".drone.yml"
|
||||
],
|
||||
"action": "updateLabel",
|
||||
"addLabel": "type/ci"
|
||||
},
|
||||
{
|
||||
"type": "changedfiles",
|
||||
"matches": [
|
||||
|
||||
@@ -13,7 +13,7 @@ permissions: {}
|
||||
jobs:
|
||||
backport:
|
||||
# Only run this job if the triggering workflow was not skipped (and on grafana repo)
|
||||
if: github.repository == 'grafana/grafana' && github.event.workflow_run.conclusion == 'success'
|
||||
if: github.event.workflow_run.head_repository.fork == false && github.repository == 'grafana/grafana' && github.event.workflow_run.conclusion == 'success'
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
|
||||
@@ -23,7 +23,28 @@ permissions:
|
||||
security-events: write
|
||||
|
||||
jobs:
|
||||
detect-changes:
|
||||
name: Detect whether code changed
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
outputs:
|
||||
javascript: ${{ steps.detect-changes.outputs.frontend }}
|
||||
go: ${{ steps.detect-changes.outputs.backend }}
|
||||
actions: 'true'
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: true # required to get more history in the changed-files action
|
||||
fetch-depth: 2
|
||||
- name: Detect changes
|
||||
id: detect-changes
|
||||
uses: ./.github/actions/change-detection
|
||||
with:
|
||||
self: .github/workflows/codeql-analysis.yml
|
||||
|
||||
analyze:
|
||||
needs: detect-changes
|
||||
name: Analyze
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true # doesn't block PRs from being merged if this fails
|
||||
@@ -41,6 +62,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
if: needs.detect-changes.outputs[matrix.language] == 'true'
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
# We must fetch at least the immediate parents so that if this is
|
||||
@@ -48,7 +70,7 @@ jobs:
|
||||
fetch-depth: 2
|
||||
persist-credentials: false
|
||||
|
||||
- if: matrix.language == 'go'
|
||||
- if: matrix.language == 'go' && needs.detect-changes.outputs.go == 'true'
|
||||
name: Set go version
|
||||
uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5
|
||||
with:
|
||||
@@ -56,6 +78,7 @@ jobs:
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
if: needs.detect-changes.outputs[matrix.language] == 'true'
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
@@ -64,7 +87,7 @@ jobs:
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
# queries: ./path/to/local/query, your-org/your-repo/queries@main
|
||||
|
||||
- if: matrix.language == 'go'
|
||||
- if: matrix.language == 'go' && needs.detect-changes.outputs.go == 'true'
|
||||
name: Build go files
|
||||
run: |
|
||||
go mod verify
|
||||
|
||||
@@ -10,7 +10,7 @@ on:
|
||||
schedule:
|
||||
# Every weeknight at midnight
|
||||
# "Scheduled workflows will only run on the default branch." (docs.github.com)
|
||||
- cron: "0 0 * * 1-5"
|
||||
- cron: '0 0 * * 1-5'
|
||||
push:
|
||||
branches:
|
||||
- release-*.*.*
|
||||
@@ -108,7 +108,7 @@ jobs:
|
||||
github-token: ${{ steps.generate_token.outputs.token }}
|
||||
script: |
|
||||
const {REF, VERSION, BUILD_ID, BUCKET, GRAFANA_COMMIT, SOURCE_EVENT} = process.env;
|
||||
|
||||
|
||||
await github.rest.actions.createWorkflowDispatch({
|
||||
owner: 'grafana',
|
||||
repo: 'grafana-enterprise',
|
||||
@@ -166,7 +166,7 @@ jobs:
|
||||
artifacts: targz:grafana:darwin/arm64
|
||||
verify: true
|
||||
steps:
|
||||
- uses: grafana/shared-workflows/actions/dockerhub-login@main
|
||||
- uses: grafana/shared-workflows/actions/dockerhub-login@dockerhub-login/v1.0.2
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
persist-credentials: false
|
||||
@@ -209,3 +209,60 @@ jobs:
|
||||
run-id: ${{ github.run_id }}
|
||||
bucket-path: ${{ needs.setup.outputs.version }}_${{ github.run_id }}
|
||||
environment: prod
|
||||
publish-dockerhub:
|
||||
if: github.ref_name == 'main'
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
runs-on: ubuntu-x64-small
|
||||
needs:
|
||||
- setup
|
||||
- build
|
||||
steps:
|
||||
- uses: grafana/shared-workflows/actions/dockerhub-login@dockerhub-login/v1.0.2
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-list-linux-amd64
|
||||
path: .
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-list-linux-arm64
|
||||
path: .
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-list-linux-armv7
|
||||
path: .
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-linux-amd64
|
||||
path: dist
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-linux-arm64
|
||||
path: dist
|
||||
- uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093
|
||||
with:
|
||||
name: artifacts-linux-armv7
|
||||
path: dist
|
||||
- name: Push to Docker Hub
|
||||
env:
|
||||
VERSION: ${{ needs.setup.outputs.version }}
|
||||
run: |
|
||||
# grep can use a wildcard but then it includes the filename as part of the result and that gets complicated.
|
||||
# It's easier to use cat to combine the artifact lists
|
||||
cat artifacts-*.txt > artifacts.txt
|
||||
grep 'grafana_.*docker.tar.gz$' artifacts.txt | xargs -I % docker load -i % | sed 's/Loaded image: //g' | tee docker_images
|
||||
while read -r line; do
|
||||
# This tag will be `grafana/grafana-image-tags:...`
|
||||
docker push "$line"
|
||||
done < docker_images
|
||||
|
||||
docker manifest create grafana/grafana:main "grafana/grafana-image-tags:${VERSION}-amd64" "grafana/grafana-image-tags:${VERSION}-arm64" "grafana/grafana-image-tags:${VERSION}-armv7"
|
||||
docker manifest create grafana/grafana:main-ubuntu "grafana/grafana-image-tags:${VERSION}-ubuntu-amd64" "grafana/grafana-image-tags:${VERSION}-ubuntu-arm64" "grafana/grafana-image-tags:${VERSION}-ubuntu-armv7"
|
||||
docker manifest create "grafana/grafana-dev:${VERSION}" "grafana/grafana-image-tags:${VERSION}-amd64" "grafana/grafana-image-tags:${VERSION}-arm64" "grafana/grafana-image-tags:${VERSION}-armv7"
|
||||
docker manifest create "grafana/grafana-dev:${VERSION}-ubuntu" "grafana/grafana-image-tags:${VERSION}-ubuntu-amd64" "grafana/grafana-image-tags:${VERSION}-ubuntu-arm64" "grafana/grafana-image-tags:${VERSION}-ubuntu-armv7"
|
||||
|
||||
docker manifest push grafana/grafana:main
|
||||
docker manifest push grafana/grafana:main-ubuntu
|
||||
docker manifest push "grafana/grafana-dev:${VERSION}"
|
||||
docker manifest push "grafana/grafana-dev:${VERSION}-ubuntu"
|
||||
|
||||
@@ -62,7 +62,6 @@ ARG COMMIT_SHA=""
|
||||
ARG BUILD_BRANCH=""
|
||||
ARG GO_BUILD_TAGS="oss"
|
||||
ARG WIRE_TAGS="oss"
|
||||
ARG BINGO="true"
|
||||
|
||||
RUN if grep -i -q alpine /etc/issue; then \
|
||||
apk add --no-cache \
|
||||
@@ -76,7 +75,6 @@ RUN if grep -i -q alpine /etc/issue; then \
|
||||
WORKDIR /tmp/grafana
|
||||
|
||||
COPY go.* ./
|
||||
COPY .bingo .bingo
|
||||
COPY .citools .citools
|
||||
|
||||
# Copy go dependencies first
|
||||
@@ -109,10 +107,6 @@ COPY pkg/codegen pkg/codegen
|
||||
COPY pkg/plugins/codegen pkg/plugins/codegen
|
||||
|
||||
RUN go mod download
|
||||
RUN if [[ "$BINGO" = "true" ]]; then \
|
||||
go install github.com/bwplotka/bingo@latest && \
|
||||
bingo get -v; \
|
||||
fi
|
||||
|
||||
COPY embed.go Makefile build.go package.json ./
|
||||
COPY cue.mod cue.mod
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
WIRE_TAGS = "oss"
|
||||
|
||||
-include local/Makefile
|
||||
include .bingo/Variables.mk
|
||||
include .citools/Variables.mk
|
||||
|
||||
GO = go
|
||||
@@ -200,7 +199,7 @@ gen-enterprise-go: ## Generate Wire graph (Enterprise)
|
||||
$(GO) run ./pkg/build/wire/cmd/wire/main.go gen -tags "enterprise" -gen_tags "(enterprise || pro)" -output_file_prefix="enterprise_" ./pkg/server
|
||||
endif
|
||||
gen-go: gen-enterprise-go ## Generate Wire graph
|
||||
@echo "generatng Wire graph"
|
||||
@echo "generating Wire graph"
|
||||
$(GO) run ./pkg/build/wire/cmd/wire/main.go gen -tags "oss" -gen_tags "(!enterprise && !pro)" ./pkg/server
|
||||
|
||||
.PHONY: fix-cue
|
||||
@@ -421,7 +420,6 @@ build-docker-full: ## Build Docker image for development.
|
||||
tar -ch . | \
|
||||
docker buildx build - \
|
||||
--platform $(PLATFORM) \
|
||||
--build-arg BINGO=false \
|
||||
--build-arg NODE_ENV=$(DOCKER_JS_NODE_ENV_FLAG) \
|
||||
--build-arg JS_NODE_ENV=$(DOCKER_JS_NODE_ENV_FLAG) \
|
||||
--build-arg JS_YARN_INSTALL_FLAG=$(DOCKER_JS_YARN_INSTALL_FLAG) \
|
||||
@@ -439,7 +437,6 @@ build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
|
||||
tar -ch . | \
|
||||
docker buildx build - \
|
||||
--platform $(PLATFORM) \
|
||||
--build-arg BINGO=false \
|
||||
--build-arg NODE_ENV=$(DOCKER_JS_NODE_ENV_FLAG) \
|
||||
--build-arg JS_NODE_ENV=$(DOCKER_JS_NODE_ENV_FLAG) \
|
||||
--build-arg JS_YARN_INSTALL_FLAG=$(DOCKER_JS_YARN_INSTALL_FLAG) \
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
MIN_VERSION = 14
|
||||
MIN_VERSION = 13
|
||||
LATEST_VERSION = 41
|
||||
)
|
||||
|
||||
@@ -38,6 +38,7 @@ type PanelPluginInfoProvider interface {
|
||||
|
||||
func GetMigrations(dsInfoProvider DataSourceInfoProvider, panelProvider PanelPluginInfoProvider) map[int]SchemaVersionMigrationFunc {
|
||||
return map[int]SchemaVersionMigrationFunc{
|
||||
14: V14,
|
||||
15: V15,
|
||||
16: V16,
|
||||
17: V17,
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
package schemaversion
|
||||
|
||||
// V14 migrates the sharedCrosshair boolean property to graphTooltip integer property.
|
||||
// This migration converts the old boolean shared crosshair setting to the new integer-based
|
||||
// graph tooltip setting for consistency with updated dashboard tooltip behavior.
|
||||
|
||||
// Example before migration:
|
||||
// {
|
||||
// "schemaVersion": 13,
|
||||
// "title": "My Dashboard",
|
||||
// "sharedCrosshair": true,
|
||||
// "panels": [...]
|
||||
// }
|
||||
|
||||
// Example after migration:
|
||||
// {
|
||||
// "schemaVersion": 14,
|
||||
// "title": "My Dashboard",
|
||||
// "graphTooltip": 1,
|
||||
// "panels": [...]
|
||||
// }
|
||||
|
||||
func V14(dashboard map[string]interface{}) error {
|
||||
// Convert sharedCrosshair boolean to graphTooltip integer
|
||||
sharedCrosshair := GetBoolValue(dashboard, "sharedCrosshair")
|
||||
|
||||
if sharedCrosshair {
|
||||
dashboard["graphTooltip"] = 1
|
||||
} else {
|
||||
dashboard["graphTooltip"] = 0
|
||||
}
|
||||
|
||||
// Remove the old sharedCrosshair property
|
||||
delete(dashboard, "sharedCrosshair")
|
||||
|
||||
dashboard["schemaVersion"] = 14
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
package schemaversion_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/apps/dashboard/pkg/migration/schemaversion"
|
||||
)
|
||||
|
||||
func TestV14(t *testing.T) {
|
||||
tests := []migrationTestCase{
|
||||
{
|
||||
name: "v14 migration converts sharedCrosshair true to graphTooltip 1",
|
||||
input: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 13,
|
||||
"sharedCrosshair": true,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "graph",
|
||||
"title": "CPU Usage",
|
||||
"id": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 14,
|
||||
"graphTooltip": 1,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "graph",
|
||||
"title": "CPU Usage",
|
||||
"id": 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v14 migration converts sharedCrosshair false to graphTooltip 0",
|
||||
input: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 13,
|
||||
"sharedCrosshair": false,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "singlestat",
|
||||
"title": "Memory Usage",
|
||||
"id": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 14,
|
||||
"graphTooltip": 0,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "singlestat",
|
||||
"title": "Memory Usage",
|
||||
"id": 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "v14 migration handles missing sharedCrosshair (defaults to false/0)",
|
||||
input: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 13,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "table",
|
||||
"title": "Server Stats",
|
||||
"id": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: map[string]interface{}{
|
||||
"title": "V14 Migration Test Dashboard",
|
||||
"schemaVersion": 14,
|
||||
"graphTooltip": 0,
|
||||
"panels": []interface{}{
|
||||
map[string]interface{}{
|
||||
"type": "table",
|
||||
"title": "Server Stats",
|
||||
"id": 3,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
runMigrationTests(t, tests, schemaversion.V14)
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"title": "V14 Shared Crosshair Migration Test Dashboard",
|
||||
"schemaVersion": 13,
|
||||
"sharedCrosshair": true,
|
||||
"panels": [
|
||||
{
|
||||
"type": "graph",
|
||||
"title": "CPU Usage Over Time",
|
||||
"id": 1,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "cpu_usage",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"yAxes": [
|
||||
{
|
||||
"show": true,
|
||||
"min": null,
|
||||
"max": null
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "graph",
|
||||
"title": "Memory Usage",
|
||||
"id": 2,
|
||||
"targets": [
|
||||
{
|
||||
"expr": "memory_usage",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"yAxes": [
|
||||
{
|
||||
"show": true,
|
||||
"min": 0,
|
||||
"max": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"name": "server",
|
||||
"type": "query",
|
||||
"datasource": "prometheus",
|
||||
"query": "label_values(server)",
|
||||
"refresh": 1,
|
||||
"options": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": ["5s", "10s", "30s", "1m", "5m", "15m", "30m", "1h", "2h", "1d"]
|
||||
},
|
||||
"annotations": {
|
||||
"list": []
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"annotations": {
|
||||
"list": []
|
||||
},
|
||||
"graphTooltip": 1,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"id": 1,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"expr": "cpu_usage",
|
||||
"refId": "A"
|
||||
}
|
||||
],
|
||||
"title": "CPU Usage Over Time",
|
||||
"type": "graph",
|
||||
"yAxes": [
|
||||
{
|
||||
"max": null,
|
||||
"min": null,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"id": 2,
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
"apiVersion": "v1",
|
||||
"type": "prometheus",
|
||||
"uid": "default-ds-uid"
|
||||
},
|
||||
"expr": "memory_usage",
|
||||
"refId": "B"
|
||||
}
|
||||
],
|
||||
"title": "Memory Usage",
|
||||
"type": "graph",
|
||||
"yAxes": [
|
||||
{
|
||||
"max": 100,
|
||||
"min": 0,
|
||||
"show": true
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"refresh": "",
|
||||
"schemaVersion": 41,
|
||||
"templating": {
|
||||
"list": [
|
||||
{
|
||||
"datasource": {
|
||||
"uid": "prometheus"
|
||||
},
|
||||
"name": "server",
|
||||
"options": [],
|
||||
"query": "label_values(server)",
|
||||
"refresh": 1,
|
||||
"type": "query"
|
||||
}
|
||||
]
|
||||
},
|
||||
"time": {
|
||||
"from": "now-1h",
|
||||
"to": "now"
|
||||
},
|
||||
"timepicker": {
|
||||
"refresh_intervals": [
|
||||
"5s",
|
||||
"10s",
|
||||
"30s",
|
||||
"1m",
|
||||
"5m",
|
||||
"15m",
|
||||
"30m",
|
||||
"1h",
|
||||
"2h",
|
||||
"1d"
|
||||
]
|
||||
},
|
||||
"title": "V14 Shared Crosshair Migration Test Dashboard"
|
||||
}
|
||||
+1
-1
@@ -138,7 +138,7 @@ require (
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/google/wire v0.6.0 // indirect
|
||||
github.com/gorilla/mux v1.8.1 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1 // indirect
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0 // indirect
|
||||
github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 // indirect
|
||||
github.com/grafana/dataplane/sdata v0.0.9 // indirect
|
||||
github.com/grafana/dskit v0.0.0-20250611075409-46f51e1ce914 // indirect
|
||||
|
||||
+2
-2
@@ -673,8 +673,8 @@ github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2z
|
||||
github.com/gorilla/mux v1.7.1/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
|
||||
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1 h1:nn19bwMFBGWOvUTxZsdewOfRiXERhKHp0jEira8uQA8=
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1/go.mod h1:VKxaR93Gff0ZlO2sPcdPVob1a/UzArFEW5zx3Bpyhls=
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0 h1:CC+ShIgoLTBsAulRfJH9xF++Us6Y3va3VFbeDeJym2M=
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0/go.mod h1:VKxaR93Gff0ZlO2sPcdPVob1a/UzArFEW5zx3Bpyhls=
|
||||
github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 h1:vVPT0i5Y1vI6qzecYStV2yk7cHKrC3Pc7AgvwT5KydQ=
|
||||
github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43/go.mod h1:1fWkOiL+m32NBgRHZtlZGz2ji868tPZACYbqP3nBRJI=
|
||||
github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 h1:NlkGMnVi/oUn6Cr90QbJYpQJ4FnjyAIG9Ex5GtTZIzw=
|
||||
|
||||
@@ -3,7 +3,6 @@ module github.com/grafana/grafana/apps/provisioning
|
||||
go 1.24.6
|
||||
|
||||
require (
|
||||
github.com/grafana/grafana-app-sdk v0.40.3
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2
|
||||
k8s.io/apimachinery v0.33.3
|
||||
k8s.io/client-go v0.33.3
|
||||
@@ -12,48 +11,31 @@ require (
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||
github.com/getkin/kin-openapi v0.132.0 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-test/deep v1.1.1 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/gnostic-models v0.6.9 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/grafana/grafana-app-sdk/logging v0.40.2 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
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-20250309154309-f31be36b4037 // indirect
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
|
||||
github.com/onsi/gomega v1.36.2 // indirect
|
||||
github.com/perimeterx/marshmallow v1.1.5 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus/client_golang v1.23.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.2 // indirect
|
||||
github.com/prometheus/common v0.65.0 // indirect
|
||||
github.com/prometheus/procfs v0.16.1 // indirect
|
||||
github.com/stretchr/objx v0.5.2 // indirect
|
||||
github.com/stretchr/testify v1.10.0 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
go.opentelemetry.io/otel v1.37.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.37.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.2 // indirect
|
||||
golang.org/x/net v0.43.0 // indirect
|
||||
golang.org/x/oauth2 v0.30.0 // indirect
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
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=
|
||||
@@ -10,8 +6,6 @@ github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtz
|
||||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
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.132.0 h1:3ISeLMsQzcb5v26yeJrBcdTCEQTag36ZjaGk7MIRUwk=
|
||||
github.com/getkin/kin-openapi v0.132.0/go.mod h1:3OlG51PCYNsPByuiMB0t4fjnNlIDnaEDsjiKUV8nL58=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ=
|
||||
@@ -22,8 +16,6 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/go-test/deep v1.1.1 h1:0r/53hagsehfO4bzD2Pgr/+RgHqhmf+k1Bpse2cTu1U=
|
||||
github.com/go-test/deep v1.1.1/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
||||
@@ -36,31 +28,18 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
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.40.3 h1:JFo7uAfbAJUfZ9neD7/4sODKm1xgu9zhckclH/N4DYU=
|
||||
github.com/grafana/grafana-app-sdk v0.40.3/go.mod h1:j0KzHo3Sa6kd+lnwSScBNoV9Vobkg/YY9HtEjxpyPrk=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.40.2 h1:HQ1+y9Od92iMbWWB54QxiYpNtCvYGUVpyxvxZ7ywB1k=
|
||||
github.com/grafana/grafana-app-sdk/logging v0.40.2/go.mod h1:otUD9XpJD7A5sCLb8mcs9hIXGdeV6lnhzVwe747g4RU=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2 h1:X0cnaFdR+iz+sDSuoZmkryFSjOirchHe2MdKSRwBWgM=
|
||||
github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250804150913-990f1c69ecc2/go.mod h1:RRvSjHH12/PnQaXraMO65jUhVu8n59mzvhfIMBETnV4=
|
||||
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/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=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -68,33 +47,17 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9M+97sNutRR1RKhG96O6jWumTTnw=
|
||||
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/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037 h1:G7ERwszslrBzRxj//JalHPu/3yz+De2J+4aLtSRlHiY=
|
||||
github.com/oasdiff/yaml v0.0.0-20250309154309-f31be36b4037/go.mod h1:2bpvgLBZEtENV5scfDFEtB/5+1M4hkQhDQrccEJ/qGw=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90 h1:bQx3WeLcUWy+RletIKwUIt4x3t8n2SxavmoclizMb8c=
|
||||
github.com/oasdiff/yaml3 v0.0.0-20250309153720-d2182401db90/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
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=
|
||||
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 v1.23.0 h1:ust4zpdl9r4trLY/gSjlm07PuiBq2ynaXXlptpfy8Uc=
|
||||
github.com/prometheus/client_golang v1.23.0/go.mod h1:i/o0R9ByOnHX0McrTMTyhYvKE4haaf2mW08I+jGAjEE=
|
||||
github.com/prometheus/client_model v0.6.2 h1:oBsgwpGs7iVziMvrGhE53c/GrLUsZdHnqNwqPLxwZyk=
|
||||
github.com/prometheus/client_model v0.6.2/go.mod h1:y3m2F6Gdpfy6Ut/GBsUqTWZqCUvMVzSfMLjcu6wAwpE=
|
||||
github.com/prometheus/common v0.65.0 h1:QDwzd+G1twt//Kwj/Ww6E9FQq1iVMmODnILtW1t2VzE=
|
||||
github.com/prometheus/common v0.65.0/go.mod h1:0gZns+BLRQ3V6NdaerOhMbwwRbNh9hkGINtQAsP5GS8=
|
||||
github.com/prometheus/procfs v0.16.1 h1:hZ15bTNuirocR6u0JZ6BAHHmwS1p8B4P6MRqxtzMyRg=
|
||||
github.com/prometheus/procfs v0.16.1/go.mod h1:teAbpZRB1iIAJYREa1LsoWUXykVXA1KlTmWl8x/U+Is=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
|
||||
@@ -105,16 +68,10 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
go.opentelemetry.io/otel v1.37.0 h1:9zhNfelUvx0KBfu/gb+ZgeAfAgtWrfHJZcAqFC228wQ=
|
||||
go.opentelemetry.io/otel v1.37.0/go.mod h1:ehE/umFRLnuLa/vSccNq9oS1ErUlkkK71gMcN34UG8I=
|
||||
go.opentelemetry.io/otel/trace v1.37.0 h1:HLdcFNbRQBE2imdSEgm/kwqmQj1Or1l/7bW6mxVK7z4=
|
||||
go.opentelemetry.io/otel/trace v1.37.0/go.mod h1:TlgrlQ+PtQO5XFerSPUYG0JSgGyryXewPGyayAWSBS0=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.yaml.in/yaml/v2 v2.4.2 h1:DzmwEr2rDGHl7lsFgAHxmNz/1NlQ7xLIrlN2h5d1eGI=
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package v0alpha1
|
||||
|
||||
import "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
const (
|
||||
// APIGroup is the API group used by all kinds in this package
|
||||
APIGroup = "provisioning.grafana.app"
|
||||
// APIVersion is the API version used by all kinds in this package
|
||||
APIVersion = "v0alpha1"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is a schema.GroupVersion consisting of the Group and Version constants for this package
|
||||
GroupVersion = schema.GroupVersion{
|
||||
Group: APIGroup,
|
||||
Version: APIVersion,
|
||||
}
|
||||
)
|
||||
@@ -1,28 +0,0 @@
|
||||
//
|
||||
// Code generated by grafana-app-sdk. DO NOT EDIT.
|
||||
//
|
||||
|
||||
package v0alpha1
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
|
||||
"github.com/grafana/grafana-app-sdk/resource"
|
||||
)
|
||||
|
||||
// RepositoryJSONCodec is an implementation of resource.Codec for kubernetes JSON encoding
|
||||
type RepositoryJSONCodec struct{}
|
||||
|
||||
// Read reads JSON-encoded bytes from `reader` and unmarshals them into `into`
|
||||
func (*RepositoryJSONCodec) 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 (*RepositoryJSONCodec) Write(writer io.Writer, from resource.Object) error {
|
||||
return json.NewEncoder(writer).Encode(from)
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Codec = &RepositoryJSONCodec{}
|
||||
@@ -1,31 +0,0 @@
|
||||
// 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 RepositoryMetadata 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"`
|
||||
}
|
||||
|
||||
// NewRepositoryMetadata creates a new RepositoryMetadata object.
|
||||
func NewRepositoryMetadata() *RepositoryMetadata {
|
||||
return &RepositoryMetadata{
|
||||
Finalizers: []string{},
|
||||
Labels: map[string]string{},
|
||||
}
|
||||
}
|
||||
@@ -1,319 +0,0 @@
|
||||
//
|
||||
// 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 Repository struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata" yaml:"metadata"`
|
||||
|
||||
// Spec is the spec of the Repository
|
||||
Spec RepositorySpec `json:"spec" yaml:"spec"`
|
||||
|
||||
Status RepositoryStatus `json:"status" yaml:"status"`
|
||||
}
|
||||
|
||||
func (o *Repository) GetSpec() any {
|
||||
return o.Spec
|
||||
}
|
||||
|
||||
func (o *Repository) SetSpec(spec any) error {
|
||||
cast, ok := spec.(RepositorySpec)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set spec type %#v, not of type Spec", spec)
|
||||
}
|
||||
o.Spec = cast
|
||||
return nil
|
||||
}
|
||||
|
||||
func (o *Repository) GetSubresources() map[string]any {
|
||||
return map[string]any{
|
||||
"status": o.Status,
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Repository) GetSubresource(name string) (any, bool) {
|
||||
switch name {
|
||||
case "status":
|
||||
return o.Status, true
|
||||
default:
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Repository) SetSubresource(name string, value any) error {
|
||||
switch name {
|
||||
case "status":
|
||||
cast, ok := value.(RepositoryStatus)
|
||||
if !ok {
|
||||
return fmt.Errorf("cannot set status type %#v, not of type RepositoryStatus", value)
|
||||
}
|
||||
o.Status = cast
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("subresource '%s' does not exist", name)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *Repository) 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 *Repository) 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 *Repository) 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 *Repository) 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 *Repository) GetCreatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/createdBy"]
|
||||
}
|
||||
|
||||
func (o *Repository) SetCreatedBy(createdBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/createdBy"] = createdBy
|
||||
}
|
||||
|
||||
func (o *Repository) 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 *Repository) 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 *Repository) GetUpdatedBy() string {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
return o.ObjectMeta.Annotations["grafana.com/updatedBy"]
|
||||
}
|
||||
|
||||
func (o *Repository) SetUpdatedBy(updatedBy string) {
|
||||
if o.ObjectMeta.Annotations == nil {
|
||||
o.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
|
||||
o.ObjectMeta.Annotations["grafana.com/updatedBy"] = updatedBy
|
||||
}
|
||||
|
||||
func (o *Repository) Copy() resource.Object {
|
||||
return resource.CopyObject(o)
|
||||
}
|
||||
|
||||
func (o *Repository) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
func (o *Repository) DeepCopy() *Repository {
|
||||
cpy := &Repository{}
|
||||
o.DeepCopyInto(cpy)
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *Repository) DeepCopyInto(dst *Repository) {
|
||||
dst.TypeMeta.APIVersion = o.TypeMeta.APIVersion
|
||||
dst.TypeMeta.Kind = o.TypeMeta.Kind
|
||||
o.ObjectMeta.DeepCopyInto(&dst.ObjectMeta)
|
||||
o.Spec.DeepCopyInto(&dst.Spec)
|
||||
o.Status.DeepCopyInto(&dst.Status)
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.Object = &Repository{}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryList struct {
|
||||
metav1.TypeMeta `json:",inline" yaml:",inline"`
|
||||
metav1.ListMeta `json:"metadata" yaml:"metadata"`
|
||||
Items []Repository `json:"items" yaml:"items"`
|
||||
}
|
||||
|
||||
func (o *RepositoryList) DeepCopyObject() runtime.Object {
|
||||
return o.Copy()
|
||||
}
|
||||
|
||||
func (o *RepositoryList) Copy() resource.ListObject {
|
||||
cpy := &RepositoryList{
|
||||
TypeMeta: o.TypeMeta,
|
||||
Items: make([]Repository, len(o.Items)),
|
||||
}
|
||||
o.ListMeta.DeepCopyInto(&cpy.ListMeta)
|
||||
for i := 0; i < len(o.Items); i++ {
|
||||
if item, ok := o.Items[i].Copy().(*Repository); ok {
|
||||
cpy.Items[i] = *item
|
||||
}
|
||||
}
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *RepositoryList) 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 *RepositoryList) SetItems(items []resource.Object) {
|
||||
o.Items = make([]Repository, len(items))
|
||||
for i := 0; i < len(items); i++ {
|
||||
o.Items[i] = *items[i].(*Repository)
|
||||
}
|
||||
}
|
||||
|
||||
func (o *RepositoryList) DeepCopy() *RepositoryList {
|
||||
cpy := &RepositoryList{}
|
||||
o.DeepCopyInto(cpy)
|
||||
return cpy
|
||||
}
|
||||
|
||||
func (o *RepositoryList) DeepCopyInto(dst *RepositoryList) {
|
||||
resource.CopyObjectInto(dst, o)
|
||||
}
|
||||
|
||||
// Interface compliance compile-time check
|
||||
var _ resource.ListObject = &RepositoryList{}
|
||||
|
||||
// Copy methods for all subresource types
|
||||
|
||||
// DeepCopy creates a full deep copy of Spec
|
||||
func (s *RepositorySpec) DeepCopy() *RepositorySpec {
|
||||
cpy := &RepositorySpec{}
|
||||
s.DeepCopyInto(cpy)
|
||||
return cpy
|
||||
}
|
||||
|
||||
// DeepCopyInto deep copies Spec into another Spec object
|
||||
func (s *RepositorySpec) DeepCopyInto(dst *RepositorySpec) {
|
||||
resource.CopyObjectInto(dst, s)
|
||||
}
|
||||
|
||||
// DeepCopy creates a full deep copy of RepositoryStatus
|
||||
func (s *RepositoryStatus) DeepCopy() *RepositoryStatus {
|
||||
cpy := &RepositoryStatus{}
|
||||
s.DeepCopyInto(cpy)
|
||||
return cpy
|
||||
}
|
||||
|
||||
// DeepCopyInto deep copies RepositoryStatus into another RepositoryStatus object
|
||||
func (s *RepositoryStatus) DeepCopyInto(dst *RepositoryStatus) {
|
||||
resource.CopyObjectInto(dst, s)
|
||||
}
|
||||
@@ -1,34 +0,0 @@
|
||||
//
|
||||
// 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 (
|
||||
schemaRepository = resource.NewSimpleSchema("provisioning.grafana.app", "v0alpha1", &Repository{}, &RepositoryList{}, resource.WithKind("Repository"),
|
||||
resource.WithPlural("repositories"), resource.WithScope(resource.NamespacedScope))
|
||||
kindRepository = resource.Kind{
|
||||
Schema: schemaRepository,
|
||||
Codecs: map[resource.KindEncoding]resource.Codec{
|
||||
resource.KindEncodingJSON: &RepositoryJSONCodec{},
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Kind returns a resource.Kind for this Schema with a JSON codec
|
||||
func RepositoryKind() resource.Kind {
|
||||
return kindRepository
|
||||
}
|
||||
|
||||
// Schema returns a resource.SimpleSchema representation of Repository
|
||||
func RepositorySchema() *resource.SimpleSchema {
|
||||
return schemaRepository
|
||||
}
|
||||
|
||||
// Interface compliance checks
|
||||
var _ resource.Schema = kindRepository
|
||||
@@ -1,169 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySyncOptions struct {
|
||||
// Enabled must be saved as true before any sync job will run
|
||||
Enabled bool `json:"enabled"`
|
||||
// Where values should be saved
|
||||
Target RepositorySyncOptionsTarget `json:"target"`
|
||||
// When non-zero, the sync will run periodically
|
||||
IntervalSeconds *int64 `json:"intervalSeconds,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositorySyncOptions creates a new RepositorySyncOptions object.
|
||||
func NewRepositorySyncOptions() *RepositorySyncOptions {
|
||||
return &RepositorySyncOptions{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryLocalRepositoryConfig struct {
|
||||
// Path to the local repository
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// NewRepositoryLocalRepositoryConfig creates a new RepositoryLocalRepositoryConfig object.
|
||||
func NewRepositoryLocalRepositoryConfig() *RepositoryLocalRepositoryConfig {
|
||||
return &RepositoryLocalRepositoryConfig{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryGitHubRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://github.com/example/test`).
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token *string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
EncryptedToken []string `json:"encryptedToken,omitempty"`
|
||||
// Whether we should show dashboard previews for pull requests.
|
||||
// By default, this is false (i.e. we will not create previews).
|
||||
GenerateDashboardPreviews *bool `json:"generateDashboardPreviews,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryGitHubRepositoryConfig creates a new RepositoryGitHubRepositoryConfig object.
|
||||
func NewRepositoryGitHubRepositoryConfig() *RepositoryGitHubRepositoryConfig {
|
||||
return &RepositoryGitHubRepositoryConfig{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryGitRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://github.com/example/test.git`).
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token *string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
EncryptedToken []string `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryGitRepositoryConfig creates a new RepositoryGitRepositoryConfig object.
|
||||
func NewRepositoryGitRepositoryConfig() *RepositoryGitRepositoryConfig {
|
||||
return &RepositoryGitRepositoryConfig{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryBitbucketRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://bitbucket.org/example/test`).
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token *string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
EncryptedToken []string `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryBitbucketRepositoryConfig creates a new RepositoryBitbucketRepositoryConfig object.
|
||||
func NewRepositoryBitbucketRepositoryConfig() *RepositoryBitbucketRepositoryConfig {
|
||||
return &RepositoryBitbucketRepositoryConfig{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryGitLabRepositoryConfig struct {
|
||||
// The repository URL (e.g. `https://gitlab.com/example/test`).
|
||||
Url *string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token *string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
EncryptedToken []string `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryGitLabRepositoryConfig creates a new RepositoryGitLabRepositoryConfig object.
|
||||
func NewRepositoryGitLabRepositoryConfig() *RepositoryGitLabRepositoryConfig {
|
||||
return &RepositoryGitLabRepositoryConfig{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySpec struct {
|
||||
// The repository display name (shown in the UI)
|
||||
Title string `json:"title"`
|
||||
// Repository description
|
||||
Description *string `json:"description,omitempty"`
|
||||
// UI driven Workflow that allow changes to the contends of the repository.
|
||||
// The order is relevant for defining the precedence of the workflows.
|
||||
// When empty, the repository does not support any edits (eg, readonly)
|
||||
Workflows []string `json:"workflows,omitempty"`
|
||||
// Sync settings -- how values are pulled from the repository into grafana
|
||||
Sync RepositorySyncOptions `json:"sync"`
|
||||
// The repository type. When selected oneOf the values below should be non-nil
|
||||
Type RepositorySpecType `json:"type"`
|
||||
// The repository on the local file system.
|
||||
// Mutually exclusive with local | github.
|
||||
Local *RepositoryLocalRepositoryConfig `json:"local,omitempty"`
|
||||
// The repository on GitHub.
|
||||
// Mutually exclusive with local | github | git.
|
||||
Github *RepositoryGitHubRepositoryConfig `json:"github,omitempty"`
|
||||
// The repository on Git.
|
||||
// Mutually exclusive with local | github | git.
|
||||
Git *RepositoryGitRepositoryConfig `json:"git,omitempty"`
|
||||
// The repository on Bitbucket.
|
||||
// Mutually exclusive with local | github | git.
|
||||
Bitbucket *RepositoryBitbucketRepositoryConfig `json:"bitbucket,omitempty"`
|
||||
// The repository on GitLab.
|
||||
// Mutually exclusive with local | github | git.
|
||||
Gitlab *RepositoryGitLabRepositoryConfig `json:"gitlab,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositorySpec creates a new RepositorySpec object.
|
||||
func NewRepositorySpec() *RepositorySpec {
|
||||
return &RepositorySpec{
|
||||
Sync: *NewRepositorySyncOptions(),
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySyncOptionsTarget string
|
||||
|
||||
const (
|
||||
RepositorySyncOptionsTargetUnified RepositorySyncOptionsTarget = "unified"
|
||||
RepositorySyncOptionsTargetLegacy RepositorySyncOptionsTarget = "legacy"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySpecType string
|
||||
|
||||
const (
|
||||
RepositorySpecTypeLocal RepositorySpecType = "local"
|
||||
RepositorySpecTypeGithub RepositorySpecType = "github"
|
||||
RepositorySpecTypeGit RepositorySpecType = "git"
|
||||
RepositorySpecTypeBitbucket RepositorySpecType = "bitbucket"
|
||||
RepositorySpecTypeGitlab RepositorySpecType = "gitlab"
|
||||
)
|
||||
@@ -1,137 +0,0 @@
|
||||
// Code generated - EDITING IS FUTILE. DO NOT EDIT.
|
||||
|
||||
package v0alpha1
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryHealthStatus struct {
|
||||
// When not healthy, requests will not be executed
|
||||
Healthy bool `json:"healthy"`
|
||||
// When the health was checked last time
|
||||
Checked *int64 `json:"checked,omitempty"`
|
||||
// Summary messages (can be shown to users)
|
||||
// Will only be populated when not healthy
|
||||
Message []string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryHealthStatus creates a new RepositoryHealthStatus object.
|
||||
func NewRepositoryHealthStatus() *RepositoryHealthStatus {
|
||||
return &RepositoryHealthStatus{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySyncStatus struct {
|
||||
// pending, running, success, error
|
||||
State RepositorySyncStatusState `json:"state"`
|
||||
// The ID for the job that ran this sync
|
||||
Job *string `json:"job,omitempty"`
|
||||
// When the sync job started
|
||||
Started *int64 `json:"started,omitempty"`
|
||||
// When the sync job finished
|
||||
Finished *int64 `json:"finished,omitempty"`
|
||||
// When the next sync check is scheduled
|
||||
Scheduled *int64 `json:"scheduled,omitempty"`
|
||||
// Summary messages (will be shown to users)
|
||||
Message []string `json:"message"`
|
||||
// The repository ref when the last successful sync ran
|
||||
LastRef *string `json:"lastRef,omitempty"`
|
||||
// Incremental synchronization for versioned repositories
|
||||
Incremental *bool `json:"incremental,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositorySyncStatus creates a new RepositorySyncStatus object.
|
||||
func NewRepositorySyncStatus() *RepositorySyncStatus {
|
||||
return &RepositorySyncStatus{
|
||||
Message: []string{},
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryResourceCount struct {
|
||||
Group string `json:"group"`
|
||||
Resource string `json:"resource"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// NewRepositoryResourceCount creates a new RepositoryResourceCount object.
|
||||
func NewRepositoryResourceCount() *RepositoryResourceCount {
|
||||
return &RepositoryResourceCount{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorystatusOperatorState 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 RepositoryStatusOperatorStateState `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"`
|
||||
}
|
||||
|
||||
// NewRepositorystatusOperatorState creates a new RepositorystatusOperatorState object.
|
||||
func NewRepositorystatusOperatorState() *RepositorystatusOperatorState {
|
||||
return &RepositorystatusOperatorState{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryWebhookStatus struct {
|
||||
Id *int64 `json:"id,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
EncryptedSecret []string `json:"encryptedSecret,omitempty"`
|
||||
SubscribedEvents []string `json:"subscribedEvents,omitempty"`
|
||||
LastEvent *int64 `json:"lastEvent,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryWebhookStatus creates a new RepositoryWebhookStatus object.
|
||||
func NewRepositoryWebhookStatus() *RepositoryWebhookStatus {
|
||||
return &RepositoryWebhookStatus{}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryStatus struct {
|
||||
// The generation of the spec last time reconciliation ran
|
||||
ObservedGeneration *int64 `json:"observedGeneration,omitempty"`
|
||||
// This will get updated with the current health status (and updated periodically)
|
||||
Health RepositoryHealthStatus `json:"health"`
|
||||
// Sync information with the last sync information
|
||||
Sync RepositorySyncStatus `json:"sync"`
|
||||
// The object count when sync last ran
|
||||
Stats []RepositoryResourceCount `json:"stats,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]RepositorystatusOperatorState `json:"operatorStates,omitempty"`
|
||||
// Webhook Information (if applicable)
|
||||
Webhook *RepositoryWebhookStatus `json:"webhook,omitempty"`
|
||||
// additionalFields is reserved for future use
|
||||
AdditionalFields map[string]interface{} `json:"additionalFields,omitempty"`
|
||||
}
|
||||
|
||||
// NewRepositoryStatus creates a new RepositoryStatus object.
|
||||
func NewRepositoryStatus() *RepositoryStatus {
|
||||
return &RepositoryStatus{
|
||||
Health: *NewRepositoryHealthStatus(),
|
||||
Sync: *NewRepositorySyncStatus(),
|
||||
}
|
||||
}
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositorySyncStatusState string
|
||||
|
||||
const (
|
||||
RepositorySyncStatusStatePending RepositorySyncStatusState = "pending"
|
||||
RepositorySyncStatusStateRunning RepositorySyncStatusState = "running"
|
||||
RepositorySyncStatusStateSuccess RepositorySyncStatusState = "success"
|
||||
RepositorySyncStatusStateError RepositorySyncStatusState = "error"
|
||||
)
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type RepositoryStatusOperatorStateState string
|
||||
|
||||
const (
|
||||
RepositoryStatusOperatorStateStateSuccess RepositoryStatusOperatorStateState = "success"
|
||||
RepositoryStatusOperatorStateStateInProgress RepositoryStatusOperatorStateState = "in_progress"
|
||||
RepositoryStatusOperatorStateStateFailed RepositoryStatusOperatorStateState = "failed"
|
||||
)
|
||||
@@ -1,879 +0,0 @@
|
||||
//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/provisioning/kinds/provisioning/v0alpha1.Repository": schema_provisioning_kinds_provisioning_v0alpha1_Repository(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryBitbucketRepositoryConfig": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryBitbucketRepositoryConfig(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitHubRepositoryConfig": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitHubRepositoryConfig(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitLabRepositoryConfig": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitLabRepositoryConfig(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitRepositoryConfig": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitRepositoryConfig(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryHealthStatus": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryHealthStatus(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryList": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryList(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryLocalRepositoryConfig": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryLocalRepositoryConfig(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryResourceCount": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryResourceCount(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySpec": schema_provisioning_kinds_provisioning_v0alpha1_RepositorySpec(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryStatus": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryStatus(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncOptions": schema_provisioning_kinds_provisioning_v0alpha1_RepositorySyncOptions(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncStatus": schema_provisioning_kinds_provisioning_v0alpha1_RepositorySyncStatus(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryWebhookStatus": schema_provisioning_kinds_provisioning_v0alpha1_RepositoryWebhookStatus(ref),
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorystatusOperatorState": schema_provisioning_kinds_provisioning_v0alpha1_RepositorystatusOperatorState(ref),
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_Repository(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{
|
||||
Description: "Spec is the spec of the Repository",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySpec"),
|
||||
},
|
||||
},
|
||||
"status": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryStatus"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"metadata", "spec", "status"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySpec", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryBitbucketRepositoryConfig(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: "The repository URL (e.g. `https://bitbucket.org/example/test`).",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"branch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The branch to use in the repository.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"tokenUser": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "TokenUser is the user that will be used to access the repository if it's a personal access token.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"branch"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitHubRepositoryConfig(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: "The repository URL (e.g. `https://github.com/example/test`).",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"branch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The branch to use in the repository.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"generateDashboardPreviews": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Whether we should show dashboard previews for pull requests. By default, this is false (i.e. we will not create previews).",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"branch"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitLabRepositoryConfig(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: "The repository URL (e.g. `https://gitlab.com/example/test`).",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"branch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The branch to use in the repository.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"branch"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryGitRepositoryConfig(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: "The repository URL (e.g. `https://github.com/example/test.git`).",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"branch": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The branch to use in the repository.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"tokenUser": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "TokenUser is the user that will be used to access the repository if it's a personal access token.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"branch"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryHealthStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"healthy": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When not healthy, requests will not be executed",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"checked": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When the health was checked last time",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"message": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Summary messages (can be shown to users) Will only be populated when not healthy",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"healthy"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryList(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/provisioning/kinds/provisioning/v0alpha1.Repository"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"metadata", "items"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.Repository", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryLocalRepositoryConfig(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path to the local repository",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"path"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryResourceCount(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"group": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"resource": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"count": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"group", "resource", "count"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositorySpec(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: "The repository display name (shown in the UI)",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"description": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Repository description",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"workflows": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "UI driven Workflow that allow changes to the contends of the repository. The order is relevant for defining the precedence of the workflows. When empty, the repository does not support any edits (eg, readonly)",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"sync": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Sync settings -- how values are pulled from the repository into grafana",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncOptions"),
|
||||
},
|
||||
},
|
||||
"type": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository type. When selected oneOf the values below should be non-nil",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"local": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository on the local file system. Mutually exclusive with local | github.",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryLocalRepositoryConfig"),
|
||||
},
|
||||
},
|
||||
"github": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository on GitHub. Mutually exclusive with local | github | git.",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitHubRepositoryConfig"),
|
||||
},
|
||||
},
|
||||
"git": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository on Git. Mutually exclusive with local | github | git.",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitRepositoryConfig"),
|
||||
},
|
||||
},
|
||||
"bitbucket": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository on Bitbucket. Mutually exclusive with local | github | git.",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryBitbucketRepositoryConfig"),
|
||||
},
|
||||
},
|
||||
"gitlab": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository on GitLab. Mutually exclusive with local | github | git.",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitLabRepositoryConfig"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"title", "sync", "type"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryBitbucketRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitHubRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitLabRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryGitRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryLocalRepositoryConfig", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncOptions"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"observedGeneration": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The generation of the spec last time reconciliation ran",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"health": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "This will get updated with the current health status (and updated periodically)",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryHealthStatus"),
|
||||
},
|
||||
},
|
||||
"sync": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Sync information with the last sync information",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncStatus"),
|
||||
},
|
||||
},
|
||||
"stats": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The object count when sync last ran",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryResourceCount"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"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/provisioning/kinds/provisioning/v0alpha1.RepositorystatusOperatorState"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"webhook": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Webhook Information (if applicable)",
|
||||
Ref: ref("github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryWebhookStatus"),
|
||||
},
|
||||
},
|
||||
"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: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"health", "sync"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
"github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryHealthStatus", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryResourceCount", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorySyncStatus", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositoryWebhookStatus", "github.com/grafana/grafana/apps/provisioning/kinds/provisioning/v0alpha1.RepositorystatusOperatorState"},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositorySyncOptions(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"enabled": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Enabled must be saved as true before any sync job will run",
|
||||
Default: false,
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"target": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Where values should be saved",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"intervalSeconds": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When non-zero, the sync will run periodically",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"enabled", "target"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositorySyncStatus(ref common.ReferenceCallback) common.OpenAPIDefinition {
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"state": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "pending, running, success, error",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"job": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The ID for the job that ran this sync",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"started": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When the sync job started",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"finished": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When the sync job finished",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"scheduled": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "When the next sync check is scheduled",
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"message": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Summary messages (will be shown to users)",
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"lastRef": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "The repository ref when the last successful sync ran",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"incremental": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Incremental synchronization for versioned repositories",
|
||||
Type: []string{"boolean"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"state", "message"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositoryWebhookStatus(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{
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"secret": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedSecret": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"subscribedEvents": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
Items: &spec.SchemaOrArray{
|
||||
Schema: &spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"lastEvent": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func schema_provisioning_kinds_provisioning_v0alpha1_RepositorystatusOperatorState(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"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -21,12 +21,11 @@ type Repository struct {
|
||||
Status RepositoryStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// NOT YET USED FOR REAL -- testing secure value workflow
|
||||
type SecureValues struct {
|
||||
// Token used to connect the configured repository
|
||||
Token common.InlineSecureValue `json:"token,omitzero,omitempty"`
|
||||
|
||||
// Some webhooks (github) require a secret key value
|
||||
// Some webhooks (including github) require a secret key value
|
||||
WebhookSecret common.InlineSecureValue `json:"webhookSecret,omitzero,omitempty"`
|
||||
}
|
||||
|
||||
@@ -55,11 +54,6 @@ type GitHubRepositoryConfig struct {
|
||||
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
// +listType=atomic
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
|
||||
// Whether we should show dashboard previews for pull requests.
|
||||
// By default, this is false (i.e. we will not create previews).
|
||||
@@ -80,11 +74,6 @@ type GitRepositoryConfig struct {
|
||||
Branch string `json:"branch"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser string `json:"tokenUser,omitempty"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
// +listType=atomic
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
// This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed.
|
||||
// The path is relative to the root of the repository, regardless of the leading slash.
|
||||
@@ -100,11 +89,6 @@ type BitbucketRepositoryConfig struct {
|
||||
Branch string `json:"branch"`
|
||||
// TokenUser is the user that will be used to access the repository if it's a personal access token.
|
||||
TokenUser string `json:"tokenUser,omitempty"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
// +listType=atomic
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
// This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed.
|
||||
// The path is relative to the root of the repository, regardless of the leading slash.
|
||||
@@ -118,11 +102,6 @@ type GitLabRepositoryConfig struct {
|
||||
URL string `json:"url,omitempty"`
|
||||
// The branch to use in the repository.
|
||||
Branch string `json:"branch"`
|
||||
// Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.
|
||||
Token string `json:"token,omitempty"`
|
||||
// Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.
|
||||
// +listType=atomic
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
// Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository.
|
||||
// This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed.
|
||||
// The path is relative to the root of the repository, regardless of the leading slash.
|
||||
@@ -297,8 +276,6 @@ type SyncStatus struct {
|
||||
type WebhookStatus struct {
|
||||
ID int64 `json:"id,omitempty"`
|
||||
URL string `json:"url,omitempty"`
|
||||
Secret string `json:"secret,omitempty"`
|
||||
EncryptedSecret []byte `json:"encryptedSecret,omitempty"`
|
||||
SubscribedEvents []string `json:"subscribedEvents,omitempty"`
|
||||
LastEvent int64 `json:"lastEvent,omitempty"`
|
||||
}
|
||||
|
||||
@@ -30,11 +30,6 @@ func (in *Author) DeepCopy() *Author {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *BitbucketRepositoryConfig) DeepCopyInto(out *BitbucketRepositoryConfig) {
|
||||
*out = *in
|
||||
if in.EncryptedToken != nil {
|
||||
in, out := &in.EncryptedToken, &out.EncryptedToken
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -156,11 +151,6 @@ func (in *FileList) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GitHubRepositoryConfig) DeepCopyInto(out *GitHubRepositoryConfig) {
|
||||
*out = *in
|
||||
if in.EncryptedToken != nil {
|
||||
in, out := &in.EncryptedToken, &out.EncryptedToken
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -177,11 +167,6 @@ func (in *GitHubRepositoryConfig) DeepCopy() *GitHubRepositoryConfig {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GitLabRepositoryConfig) DeepCopyInto(out *GitLabRepositoryConfig) {
|
||||
*out = *in
|
||||
if in.EncryptedToken != nil {
|
||||
in, out := &in.EncryptedToken, &out.EncryptedToken
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -198,11 +183,6 @@ func (in *GitLabRepositoryConfig) DeepCopy() *GitLabRepositoryConfig {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GitRepositoryConfig) DeepCopyInto(out *GitRepositoryConfig) {
|
||||
*out = *in
|
||||
if in.EncryptedToken != nil {
|
||||
in, out := &in.EncryptedToken, &out.EncryptedToken
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -738,22 +718,22 @@ func (in *RepositorySpec) DeepCopyInto(out *RepositorySpec) {
|
||||
if in.GitHub != nil {
|
||||
in, out := &in.GitHub, &out.GitHub
|
||||
*out = new(GitHubRepositoryConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
**out = **in
|
||||
}
|
||||
if in.Git != nil {
|
||||
in, out := &in.Git, &out.Git
|
||||
*out = new(GitRepositoryConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
**out = **in
|
||||
}
|
||||
if in.Bitbucket != nil {
|
||||
in, out := &in.Bitbucket, &out.Bitbucket
|
||||
*out = new(BitbucketRepositoryConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
**out = **in
|
||||
}
|
||||
if in.GitLab != nil {
|
||||
in, out := &in.GitLab, &out.GitLab
|
||||
*out = new(GitLabRepositoryConfig)
|
||||
(*in).DeepCopyInto(*out)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
@@ -1220,11 +1200,6 @@ func (in *WebhookResponse) DeepCopyObject() runtime.Object {
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WebhookStatus) DeepCopyInto(out *WebhookStatus) {
|
||||
*out = *in
|
||||
if in.EncryptedSecret != nil {
|
||||
in, out := &in.EncryptedSecret, &out.EncryptedSecret
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SubscribedEvents != nil {
|
||||
in, out := &in.SubscribedEvents, &out.SubscribedEvents
|
||||
*out = make([]string, len(*in))
|
||||
|
||||
@@ -128,25 +128,6 @@ func schema_pkg_apis_provisioning_v0alpha1_BitbucketRepositoryConfig(ref common.
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"string"},
|
||||
Format: "byte",
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
|
||||
@@ -402,25 +383,6 @@ func schema_pkg_apis_provisioning_v0alpha1_GitHubRepositoryConfig(ref common.Ref
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"string"},
|
||||
Format: "byte",
|
||||
},
|
||||
},
|
||||
"generateDashboardPreviews": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Whether we should show dashboard previews for pull requests. By default, this is false (i.e. we will not create previews).",
|
||||
@@ -463,25 +425,6 @@ func schema_pkg_apis_provisioning_v0alpha1_GitLabRepositoryConfig(ref common.Ref
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"string"},
|
||||
Format: "byte",
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
|
||||
@@ -524,25 +467,6 @@ func schema_pkg_apis_provisioning_v0alpha1_GitRepositoryConfig(ref common.Refere
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository. If set, it will be encrypted into encryptedToken, then set to an empty string again.",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedToken": {
|
||||
VendorExtensible: spec.VendorExtensible{
|
||||
Extensions: spec.Extensions{
|
||||
"x-kubernetes-list-type": "atomic",
|
||||
},
|
||||
},
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Token for accessing the repository, but encrypted. This is not possible to read back to a user decrypted.",
|
||||
Type: []string{"string"},
|
||||
Format: "byte",
|
||||
},
|
||||
},
|
||||
"path": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Path is the subdirectory for the Grafana data. If specified, Grafana will ignore anything that is outside this directory in the repository. This is usually something like `grafana/`. Trailing and leading slash are not required. They are always added when needed. The path is relative to the root of the repository, regardless of the leading slash.\n\nWhen specifying something like `grafana-`, we will not look for `grafana-*`; we will only look for files under the directory `/grafana-/`. That means `/grafana-example.json` would not be found.",
|
||||
@@ -2378,8 +2302,7 @@ func schema_pkg_apis_provisioning_v0alpha1_SecureValues(ref common.ReferenceCall
|
||||
return common.OpenAPIDefinition{
|
||||
Schema: spec.Schema{
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "NOT YET USED FOR REAL -- testing secure value workflow",
|
||||
Type: []string{"object"},
|
||||
Type: []string{"object"},
|
||||
Properties: map[string]spec.Schema{
|
||||
"token": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
@@ -2390,7 +2313,7 @@ func schema_pkg_apis_provisioning_v0alpha1_SecureValues(ref common.ReferenceCall
|
||||
},
|
||||
"webhookSecret": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Description: "Some webhooks (github) require a secret key value",
|
||||
Description: "Some webhooks (including github) require a secret key value",
|
||||
Default: map[string]interface{}{},
|
||||
Ref: ref("github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1.InlineSecureValue"),
|
||||
},
|
||||
@@ -2671,18 +2594,6 @@ func schema_pkg_apis_provisioning_v0alpha1_WebhookStatus(ref common.ReferenceCal
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"secret": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"encryptedSecret": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"string"},
|
||||
Format: "byte",
|
||||
},
|
||||
},
|
||||
"subscribedEvents": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Type: []string{"array"},
|
||||
|
||||
+4
-24
@@ -7,12 +7,10 @@ package v0alpha1
|
||||
// BitbucketRepositoryConfigApplyConfiguration represents a declarative configuration of the BitbucketRepositoryConfig type for use
|
||||
// with apply.
|
||||
type BitbucketRepositoryConfigApplyConfiguration struct {
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
Token *string `json:"token,omitempty"`
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// BitbucketRepositoryConfigApplyConfiguration constructs a declarative configuration of the BitbucketRepositoryConfig type for use with
|
||||
@@ -45,24 +43,6 @@ func (b *BitbucketRepositoryConfigApplyConfiguration) WithTokenUser(value string
|
||||
return b
|
||||
}
|
||||
|
||||
// WithToken sets the Token field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Token field is set to the value of the last call.
|
||||
func (b *BitbucketRepositoryConfigApplyConfiguration) WithToken(value string) *BitbucketRepositoryConfigApplyConfiguration {
|
||||
b.Token = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
|
||||
func (b *BitbucketRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *BitbucketRepositoryConfigApplyConfiguration {
|
||||
for i := range values {
|
||||
b.EncryptedToken = append(b.EncryptedToken, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPath sets the Path field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Path field is set to the value of the last call.
|
||||
|
||||
-20
@@ -9,8 +9,6 @@ package v0alpha1
|
||||
type GitHubRepositoryConfigApplyConfiguration struct {
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
Token *string `json:"token,omitempty"`
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
GenerateDashboardPreviews *bool `json:"generateDashboardPreviews,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
@@ -37,24 +35,6 @@ func (b *GitHubRepositoryConfigApplyConfiguration) WithBranch(value string) *Git
|
||||
return b
|
||||
}
|
||||
|
||||
// WithToken sets the Token field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Token field is set to the value of the last call.
|
||||
func (b *GitHubRepositoryConfigApplyConfiguration) WithToken(value string) *GitHubRepositoryConfigApplyConfiguration {
|
||||
b.Token = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
|
||||
func (b *GitHubRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *GitHubRepositoryConfigApplyConfiguration {
|
||||
for i := range values {
|
||||
b.EncryptedToken = append(b.EncryptedToken, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithGenerateDashboardPreviews sets the GenerateDashboardPreviews field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the GenerateDashboardPreviews field is set to the value of the last call.
|
||||
|
||||
+3
-23
@@ -7,11 +7,9 @@ package v0alpha1
|
||||
// GitLabRepositoryConfigApplyConfiguration represents a declarative configuration of the GitLabRepositoryConfig type for use
|
||||
// with apply.
|
||||
type GitLabRepositoryConfigApplyConfiguration struct {
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
Token *string `json:"token,omitempty"`
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// GitLabRepositoryConfigApplyConfiguration constructs a declarative configuration of the GitLabRepositoryConfig type for use with
|
||||
@@ -36,24 +34,6 @@ func (b *GitLabRepositoryConfigApplyConfiguration) WithBranch(value string) *Git
|
||||
return b
|
||||
}
|
||||
|
||||
// WithToken sets the Token field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Token field is set to the value of the last call.
|
||||
func (b *GitLabRepositoryConfigApplyConfiguration) WithToken(value string) *GitLabRepositoryConfigApplyConfiguration {
|
||||
b.Token = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
|
||||
func (b *GitLabRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *GitLabRepositoryConfigApplyConfiguration {
|
||||
for i := range values {
|
||||
b.EncryptedToken = append(b.EncryptedToken, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPath sets the Path field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Path field is set to the value of the last call.
|
||||
|
||||
+4
-24
@@ -7,12 +7,10 @@ package v0alpha1
|
||||
// GitRepositoryConfigApplyConfiguration represents a declarative configuration of the GitRepositoryConfig type for use
|
||||
// with apply.
|
||||
type GitRepositoryConfigApplyConfiguration struct {
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
Token *string `json:"token,omitempty"`
|
||||
EncryptedToken []byte `json:"encryptedToken,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Branch *string `json:"branch,omitempty"`
|
||||
TokenUser *string `json:"tokenUser,omitempty"`
|
||||
Path *string `json:"path,omitempty"`
|
||||
}
|
||||
|
||||
// GitRepositoryConfigApplyConfiguration constructs a declarative configuration of the GitRepositoryConfig type for use with
|
||||
@@ -45,24 +43,6 @@ func (b *GitRepositoryConfigApplyConfiguration) WithTokenUser(value string) *Git
|
||||
return b
|
||||
}
|
||||
|
||||
// WithToken sets the Token field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Token field is set to the value of the last call.
|
||||
func (b *GitRepositoryConfigApplyConfiguration) WithToken(value string) *GitRepositoryConfigApplyConfiguration {
|
||||
b.Token = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEncryptedToken adds the given value to the EncryptedToken field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the EncryptedToken field.
|
||||
func (b *GitRepositoryConfigApplyConfiguration) WithEncryptedToken(values ...byte) *GitRepositoryConfigApplyConfiguration {
|
||||
for i := range values {
|
||||
b.EncryptedToken = append(b.EncryptedToken, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithPath sets the Path field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Path field is set to the value of the last call.
|
||||
|
||||
-20
@@ -9,8 +9,6 @@ package v0alpha1
|
||||
type WebhookStatusApplyConfiguration struct {
|
||||
ID *int64 `json:"id,omitempty"`
|
||||
URL *string `json:"url,omitempty"`
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
EncryptedSecret []byte `json:"encryptedSecret,omitempty"`
|
||||
SubscribedEvents []string `json:"subscribedEvents,omitempty"`
|
||||
LastEvent *int64 `json:"lastEvent,omitempty"`
|
||||
}
|
||||
@@ -37,24 +35,6 @@ func (b *WebhookStatusApplyConfiguration) WithURL(value string) *WebhookStatusAp
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSecret sets the Secret field in the declarative configuration to the given value
|
||||
// and returns the receiver, so that objects can be built by chaining "With" function invocations.
|
||||
// If called multiple times, the Secret field is set to the value of the last call.
|
||||
func (b *WebhookStatusApplyConfiguration) WithSecret(value string) *WebhookStatusApplyConfiguration {
|
||||
b.Secret = &value
|
||||
return b
|
||||
}
|
||||
|
||||
// WithEncryptedSecret adds the given value to the EncryptedSecret field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the EncryptedSecret field.
|
||||
func (b *WebhookStatusApplyConfiguration) WithEncryptedSecret(values ...byte) *WebhookStatusApplyConfiguration {
|
||||
for i := range values {
|
||||
b.EncryptedSecret = append(b.EncryptedSecret, values[i])
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
// WithSubscribedEvents adds the given value to the SubscribedEvents field in the declarative configuration
|
||||
// and returns the receiver, so that objects can be build by chaining "With" function invocations.
|
||||
// If called multiple times, values provided by each call will be appended to the SubscribedEvents field.
|
||||
|
||||
@@ -19,7 +19,7 @@ SecureValueSpec: {
|
||||
// Minimum and maximum lengths in bytes.
|
||||
// +k8s:validation:minLength=1
|
||||
// +k8s:validation:maxLength=24576
|
||||
// +optional
|
||||
// +optional
|
||||
value?: #ExposedSecureValue
|
||||
|
||||
// When using a third-party keeper, the `ref` is used to reference a value inside the remote storage.
|
||||
@@ -41,13 +41,16 @@ SecureValueSpec: {
|
||||
// +k8s:validation:maxItems=64
|
||||
// +k8s:validation:uniqueItems=true
|
||||
// +listType=atomic
|
||||
// +optional
|
||||
// +optional
|
||||
decrypters?: [...string] & list.UniqueItems() & list.MaxItems(64)
|
||||
}
|
||||
|
||||
SecureValueStatus: {
|
||||
// Version of the secure value. Cannot be set.
|
||||
// +optional
|
||||
version: int64 & >=0
|
||||
|
||||
// External ID where the secret is stored. Cannot be set.
|
||||
// +optional
|
||||
externalID: string
|
||||
}
|
||||
|
||||
@@ -22,10 +22,13 @@ func NewSecureValuestatusOperatorState() *SecureValuestatusOperatorState {
|
||||
|
||||
// +k8s:openapi-gen=true
|
||||
type SecureValueStatus struct {
|
||||
// Version of the secure value. Cannot be set.
|
||||
// +optional
|
||||
Version int64 `json:"version"`
|
||||
// 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]SecureValuestatusOperatorState `json:"operatorStates,omitempty"`
|
||||
// External ID where the secret is stored. Cannot be set.
|
||||
// +optional
|
||||
ExternalID string `json:"externalID"`
|
||||
// additionalFields is reserved for future use
|
||||
|
||||
@@ -633,9 +633,10 @@ func schema_pkg_apis_secret_v1beta1_SecureValueStatus(ref common.ReferenceCallba
|
||||
Properties: map[string]spec.Schema{
|
||||
"version": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
Description: "Version of the secure value. Cannot be set.",
|
||||
Default: 0,
|
||||
Type: []string{"integer"},
|
||||
Format: "int64",
|
||||
},
|
||||
},
|
||||
"operatorStates": {
|
||||
@@ -655,9 +656,10 @@ func schema_pkg_apis_secret_v1beta1_SecureValueStatus(ref common.ReferenceCallba
|
||||
},
|
||||
"externalID": {
|
||||
SchemaProps: spec.SchemaProps{
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
Description: "External ID where the secret is stored. Cannot be set.",
|
||||
Default: "",
|
||||
Type: []string{"string"},
|
||||
Format: "",
|
||||
},
|
||||
},
|
||||
"additionalFields": {
|
||||
@@ -676,7 +678,6 @@ func schema_pkg_apis_secret_v1beta1_SecureValueStatus(ref common.ReferenceCallba
|
||||
},
|
||||
},
|
||||
},
|
||||
Required: []string{"version"},
|
||||
},
|
||||
},
|
||||
Dependencies: []string{
|
||||
|
||||
@@ -121,7 +121,7 @@ For an example of the `IsDisabled` method and custom initialization code when th
|
||||
|
||||
## Run Wire (generate code)
|
||||
|
||||
Running `make run` calls `make gen-go` on the first run. The `gen-go` in turn calls the Wire binary and generates the code in [`wire_gen.go`](/pkg/server/wire_gen.go). The Wire binary is installed using [`bingo`](https://github.com/bwplotka/bingo) which downloads and installs all the tools needed, including the Wire binary at the specified version.
|
||||
Running `make run` calls `make gen-go` on the first run. The `gen-go` in turn calls the Wire binary and generates the code in [`wire_gen.go`](/pkg/server/wire_gen.go). The Wire binary is installed using `go tool` which downloads and installs all the tools needed, including the Wire binary at the specified version.
|
||||
|
||||
## OSS vs. Enterprise
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
"fiscalYearStartMonth": 0,
|
||||
"graphTooltip": 0,
|
||||
"links": [],
|
||||
"liveNow": false,
|
||||
"panels": [
|
||||
{
|
||||
"datasource": {
|
||||
@@ -42,7 +41,7 @@
|
||||
"steps": [
|
||||
{
|
||||
"color": "green",
|
||||
"value": null
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "red",
|
||||
@@ -156,11 +155,19 @@
|
||||
"x": -0.8229007633587786,
|
||||
"y": 0.27741935483870966
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1223.8335877862596,
|
||||
"y": 300
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0112359550561798,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 20",
|
||||
"targetOriginal": {
|
||||
"x": 990,
|
||||
"y": 474
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": -0.18181818181818182,
|
||||
@@ -191,11 +198,19 @@
|
||||
"x": -0.3068702290076336,
|
||||
"y": -0.47419354838709676
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1401.090076335878,
|
||||
"y": 533
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0112359550561798,
|
||||
"y": -0.4805194805194805
|
||||
},
|
||||
"targetName": "Element 20",
|
||||
"targetOriginal": {
|
||||
"x": 990,
|
||||
"y": 492
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.415,
|
||||
@@ -227,11 +242,19 @@
|
||||
"x": 0.7903930131004366,
|
||||
"y": -0.36935483870967745
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1778,
|
||||
"y": 500.5
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0120481927710843,
|
||||
"y": 0.024691358024691357
|
||||
},
|
||||
"targetName": "Element 35",
|
||||
"targetOriginal": {
|
||||
"x": 1523,
|
||||
"y": 177
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": -0.1607843137254902,
|
||||
@@ -518,11 +541,19 @@
|
||||
"x": 0.8876404494382022,
|
||||
"y": 0.2597402597402597
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 741,
|
||||
"y": 356.5
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9775280898876404,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 19"
|
||||
"targetName": "Element 19",
|
||||
"targetOriginal": {
|
||||
"x": 813,
|
||||
"y": 358
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -614,11 +645,19 @@
|
||||
"x": 0.8876404494382022,
|
||||
"y": 0.2597402597402597
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 741,
|
||||
"y": 239.5
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9887640449438202,
|
||||
"y": -0.06493506493506493
|
||||
},
|
||||
"targetName": "Element 18"
|
||||
"targetName": "Element 18",
|
||||
"targetOriginal": {
|
||||
"x": 812,
|
||||
"y": 242
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -673,11 +712,19 @@
|
||||
"x": -0.2247191011235955,
|
||||
"y": -0.4805194805194805
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 342,
|
||||
"y": 395
|
||||
},
|
||||
"target": {
|
||||
"x": 0.011235955056179775,
|
||||
"y": 0.922077922077922
|
||||
},
|
||||
"targetName": "Element 12"
|
||||
"targetName": "Element 12",
|
||||
"targetOriginal": {
|
||||
"x": 343,
|
||||
"y": 458
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
@@ -693,11 +740,19 @@
|
||||
"x": 0.7752808988764045,
|
||||
"y": 0.5194805194805194
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 431,
|
||||
"y": 356.5
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0833333333333333,
|
||||
"y": 0.020618556701030927
|
||||
},
|
||||
"targetName": "Element 15"
|
||||
"targetName": "Element 15",
|
||||
"targetOriginal": {
|
||||
"x": 526,
|
||||
"y": 356
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -888,11 +943,19 @@
|
||||
"x": 1,
|
||||
"y": 0.5
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 431,
|
||||
"y": 337.25
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0112359550561798,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 16",
|
||||
"targetOriginal": {
|
||||
"x": 562,
|
||||
"y": 240
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.42748091603053434,
|
||||
@@ -963,11 +1026,19 @@
|
||||
"x": 0,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 150,
|
||||
"y": 223
|
||||
},
|
||||
"target": {
|
||||
"x": -0.5168539325842697,
|
||||
"y": 1
|
||||
},
|
||||
"targetName": "Element 6",
|
||||
"targetOriginal": {
|
||||
"x": 296,
|
||||
"y": 318
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0,
|
||||
@@ -996,11 +1067,19 @@
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 150,
|
||||
"y": 148
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0112359550561798,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 30",
|
||||
"targetOriginal": {
|
||||
"x": 563,
|
||||
"y": 82
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0,
|
||||
@@ -1062,11 +1141,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 216,
|
||||
"y": 356.5
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0112359550561798,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 6"
|
||||
"targetName": "Element 6",
|
||||
"targetOriginal": {
|
||||
"x": 252,
|
||||
"y": 357
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -1121,11 +1208,19 @@
|
||||
"x": 0,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 342,
|
||||
"y": 223
|
||||
},
|
||||
"target": {
|
||||
"x": 0.011235955056179775,
|
||||
"y": 1.025974025974026
|
||||
},
|
||||
"targetName": "Element 6"
|
||||
"targetName": "Element 6",
|
||||
"targetOriginal": {
|
||||
"x": 343,
|
||||
"y": 317
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -1218,11 +1313,19 @@
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 38,
|
||||
"y": 493.5
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0224719101123596,
|
||||
"y": 0.013333333333333334
|
||||
},
|
||||
"targetName": "Element 9",
|
||||
"targetOriginal": {
|
||||
"x": 59,
|
||||
"y": 185
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": -0.9523809523809523,
|
||||
@@ -1399,11 +1502,19 @@
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 563,
|
||||
"y": 473.5
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0224719101123596,
|
||||
"y": -0.45454545454545453
|
||||
},
|
||||
"targetName": "Element 6",
|
||||
"targetOriginal": {
|
||||
"x": 433,
|
||||
"y": 374
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.5692307692307692,
|
||||
@@ -1468,11 +1579,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 989,
|
||||
"y": 239.5
|
||||
},
|
||||
"target": {
|
||||
"x": -0.96,
|
||||
"y": 0.4583333333333333
|
||||
},
|
||||
"targetName": "Element 2",
|
||||
"targetOriginal": {
|
||||
"x": 1392,
|
||||
"y": 487
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.3349875930521092,
|
||||
@@ -1506,11 +1625,19 @@
|
||||
"x": 1,
|
||||
"y": -0.5
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 989,
|
||||
"y": 258.75
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9761904761904762,
|
||||
"y": 0.5263157894736842
|
||||
},
|
||||
"targetName": "Element 34",
|
||||
"targetOriginal": {
|
||||
"x": 1138,
|
||||
"y": 290
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.5033557046979866,
|
||||
@@ -1612,11 +1739,19 @@
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 811,
|
||||
"y": 473.5
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0112359550561798,
|
||||
"y": 0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 17"
|
||||
"targetName": "Element 17",
|
||||
"targetOriginal": {
|
||||
"x": 742,
|
||||
"y": 473
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -1671,11 +1806,19 @@
|
||||
"x": 1,
|
||||
"y": -0.5
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1025.5,
|
||||
"y": 382.25
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0238095238095237,
|
||||
"y": 0.10526315789473684
|
||||
},
|
||||
"targetName": "Element 33"
|
||||
"targetName": "Element 33",
|
||||
"targetOriginal": {
|
||||
"x": 1136,
|
||||
"y": 384
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
@@ -1691,11 +1834,19 @@
|
||||
"x": 1,
|
||||
"y": 0.5
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1025.5,
|
||||
"y": 333.75
|
||||
},
|
||||
"target": {
|
||||
"x": -1,
|
||||
"y": 0.05263157894736842
|
||||
},
|
||||
"targetName": "Element 34",
|
||||
"targetOriginal": {
|
||||
"x": 1137,
|
||||
"y": 299
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.5246636771300448,
|
||||
@@ -1721,11 +1872,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1025.5,
|
||||
"y": 358
|
||||
},
|
||||
"target": {
|
||||
"x": -0.98,
|
||||
"y": -0.10416666666666667
|
||||
},
|
||||
"targetName": "Element 2",
|
||||
"targetOriginal": {
|
||||
"x": 1391,
|
||||
"y": 514
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.7564979480164159,
|
||||
@@ -1792,11 +1951,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 742,
|
||||
"y": 81.5
|
||||
},
|
||||
"target": {
|
||||
"x": -1.0112359550561798,
|
||||
"y": -0.012987012987012988
|
||||
},
|
||||
"targetName": "Element 31"
|
||||
"targetName": "Element 31",
|
||||
"targetOriginal": {
|
||||
"x": 811,
|
||||
"y": 82
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
@@ -1818,11 +1985,19 @@
|
||||
"x": 0,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 653,
|
||||
"y": 43
|
||||
},
|
||||
"target": {
|
||||
"x": -0.029411764705882353,
|
||||
"y": 1
|
||||
},
|
||||
"targetName": "Element 38",
|
||||
"targetOriginal": {
|
||||
"x": 1673,
|
||||
"y": 249
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0,
|
||||
@@ -1892,11 +2067,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 990,
|
||||
"y": 81.5
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9939759036144579,
|
||||
"y": 0.5061728395061729
|
||||
},
|
||||
"targetName": "Element 35",
|
||||
"targetOriginal": {
|
||||
"x": 1190,
|
||||
"y": 138
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 0.48,
|
||||
@@ -1961,11 +2144,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1221,
|
||||
"y": 386
|
||||
},
|
||||
"target": {
|
||||
"x": 1.0337078651685394,
|
||||
"y": 0.45454545454545453
|
||||
},
|
||||
"targetName": "Element 20",
|
||||
"targetOriginal": {
|
||||
"x": 992,
|
||||
"y": 456
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": -0.05240174672489083,
|
||||
@@ -2067,11 +2258,19 @@
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1189,
|
||||
"y": 179
|
||||
},
|
||||
"target": {
|
||||
"x": 0.19444444444444445,
|
||||
"y": 0.9896907216494846
|
||||
},
|
||||
"targetName": "Element 29",
|
||||
"targetOriginal": {
|
||||
"x": 1011,
|
||||
"y": 310
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 1,
|
||||
@@ -2169,11 +2368,19 @@
|
||||
"x": -1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 1574,
|
||||
"y": 308
|
||||
},
|
||||
"target": {
|
||||
"x": -0.4977168949771689,
|
||||
"y": 1.017467248908297
|
||||
},
|
||||
"targetName": "Element 36",
|
||||
"targetOriginal": {
|
||||
"x": 1450,
|
||||
"y": 384
|
||||
},
|
||||
"vertices": [
|
||||
{
|
||||
"x": 1,
|
||||
@@ -2208,7 +2415,7 @@
|
||||
},
|
||||
"showAdvancedTypes": true
|
||||
},
|
||||
"pluginVersion": "11.1.0-pre",
|
||||
"pluginVersion": "12.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"datasource": {
|
||||
@@ -2236,7 +2443,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "#6ED0E0",
|
||||
@@ -2260,7 +2468,7 @@
|
||||
"h": 11,
|
||||
"w": 15,
|
||||
"x": 5,
|
||||
"y": 22
|
||||
"y": 36
|
||||
},
|
||||
"id": 4,
|
||||
"options": {
|
||||
@@ -2320,11 +2528,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 216,
|
||||
"y": 192
|
||||
},
|
||||
"target": {
|
||||
"x": -1.02020202020202,
|
||||
"y": 0.041666666666666664
|
||||
},
|
||||
"targetName": "Element 2"
|
||||
"targetName": "Element 2",
|
||||
"targetOriginal": {
|
||||
"x": 326,
|
||||
"y": 191
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -2377,11 +2593,19 @@
|
||||
"x": 1,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 426,
|
||||
"y": 168
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9797979797979798,
|
||||
"y": 0
|
||||
},
|
||||
"targetName": "Element 3"
|
||||
"targetName": "Element 3",
|
||||
"targetOriginal": {
|
||||
"x": 549,
|
||||
"y": 93
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
@@ -2398,11 +2622,19 @@
|
||||
"x": 1,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 426,
|
||||
"y": 216
|
||||
},
|
||||
"target": {
|
||||
"x": -1,
|
||||
"y": 0.041666666666666664
|
||||
},
|
||||
"targetName": "Element 4"
|
||||
"targetName": "Element 4",
|
||||
"targetOriginal": {
|
||||
"x": 549,
|
||||
"y": 297
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -2455,11 +2687,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 647,
|
||||
"y": 93
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9595959595959596,
|
||||
"y": -0.041666666666666664
|
||||
},
|
||||
"targetName": "Element 11"
|
||||
"targetName": "Element 11",
|
||||
"targetOriginal": {
|
||||
"x": 799,
|
||||
"y": 94
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -2512,11 +2752,19 @@
|
||||
"x": 1,
|
||||
"y": 0
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 648,
|
||||
"y": 298
|
||||
},
|
||||
"target": {
|
||||
"x": -0.9797979797979798,
|
||||
"y": 0.041666666666666664
|
||||
},
|
||||
"targetName": "Element 5"
|
||||
"targetName": "Element 5",
|
||||
"targetOriginal": {
|
||||
"x": 798,
|
||||
"y": 299
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -2838,7 +3086,7 @@
|
||||
},
|
||||
"showAdvancedTypes": false
|
||||
},
|
||||
"pluginVersion": "11.1.0-pre",
|
||||
"pluginVersion": "12.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"csvContent": "gateway, product-details, product-reviews, reviews-ratings, details-checkout\n100, 56, 44, 22, 28",
|
||||
@@ -2873,7 +3121,8 @@
|
||||
"mode": "absolute",
|
||||
"steps": [
|
||||
{
|
||||
"color": "green"
|
||||
"color": "green",
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"color": "blue",
|
||||
@@ -2897,7 +3146,7 @@
|
||||
"h": 15,
|
||||
"w": 15,
|
||||
"x": 5,
|
||||
"y": 33
|
||||
"y": 47
|
||||
},
|
||||
"id": 2,
|
||||
"options": {
|
||||
@@ -2949,6 +3198,10 @@
|
||||
"field": "server_database2",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "server_database2",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -2959,17 +3212,29 @@
|
||||
"x": -1,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 468,
|
||||
"y": 125
|
||||
},
|
||||
"target": {
|
||||
"x": 0.030303030303030304,
|
||||
"y": 0
|
||||
},
|
||||
"targetName": "Element 11"
|
||||
"targetName": "Element 11",
|
||||
"targetOriginal": {
|
||||
"x": 285,
|
||||
"y": 170
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
"field": "server_database",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "server_database",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -2980,17 +3245,29 @@
|
||||
"x": -1,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 468,
|
||||
"y": 125
|
||||
},
|
||||
"target": {
|
||||
"x": 0.09090909090909091,
|
||||
"y": 0.16666666666666666
|
||||
},
|
||||
"targetName": "Element 12"
|
||||
"targetName": "Element 12",
|
||||
"targetOriginal": {
|
||||
"x": 390,
|
||||
"y": 264
|
||||
}
|
||||
},
|
||||
{
|
||||
"color": {
|
||||
"field": "server_region",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "server_region",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -3001,11 +3278,19 @@
|
||||
"x": 1,
|
||||
"y": -1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 588.9921875,
|
||||
"y": 125
|
||||
},
|
||||
"target": {
|
||||
"x": -0.2727272727272727,
|
||||
"y": 0.4166666666666667
|
||||
},
|
||||
"targetName": "Element 13"
|
||||
"targetName": "Element 13",
|
||||
"targetOriginal": {
|
||||
"x": 658,
|
||||
"y": 259
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -3050,6 +3335,10 @@
|
||||
"field": "database_server",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "database_server",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -3060,11 +3349,19 @@
|
||||
"x": 1,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 328,
|
||||
"y": 367
|
||||
},
|
||||
"target": {
|
||||
"x": -0.15151515151515152,
|
||||
"y": -0.16666666666666666
|
||||
},
|
||||
"targetName": "Element 12"
|
||||
"targetName": "Element 12",
|
||||
"targetOriginal": {
|
||||
"x": 386,
|
||||
"y": 268
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -3109,6 +3406,10 @@
|
||||
"field": "region_server",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "region_server",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -3119,11 +3420,19 @@
|
||||
"x": -1,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 699,
|
||||
"y": 365
|
||||
},
|
||||
"target": {
|
||||
"x": -0.21212121212121213,
|
||||
"y": 0.08333333333333333
|
||||
},
|
||||
"targetName": "Element 13"
|
||||
"targetName": "Element 13",
|
||||
"targetOriginal": {
|
||||
"x": 659,
|
||||
"y": 263
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -3212,6 +3521,10 @@
|
||||
"field": "database2_server",
|
||||
"fixed": "white"
|
||||
},
|
||||
"direction": {
|
||||
"field": "database2_server",
|
||||
"mode": "field"
|
||||
},
|
||||
"path": "straight",
|
||||
"size": {
|
||||
"fixed": 2,
|
||||
@@ -3222,11 +3535,19 @@
|
||||
"x": 1,
|
||||
"y": 1
|
||||
},
|
||||
"sourceOriginal": {
|
||||
"x": 172,
|
||||
"y": 191
|
||||
},
|
||||
"target": {
|
||||
"x": -0.3333333333333333,
|
||||
"y": 0
|
||||
},
|
||||
"targetName": "Element 11"
|
||||
"targetName": "Element 11",
|
||||
"targetOriginal": {
|
||||
"x": 279,
|
||||
"y": 170
|
||||
}
|
||||
}
|
||||
],
|
||||
"constraint": {
|
||||
@@ -3605,7 +3926,7 @@
|
||||
},
|
||||
"showAdvancedTypes": false
|
||||
},
|
||||
"pluginVersion": "11.1.0-pre",
|
||||
"pluginVersion": "12.1.0-pre",
|
||||
"targets": [
|
||||
{
|
||||
"csvContent": "database_server, server_database, server_region, region_server, database2_server, server_database2\n10, 53, 35, 12, 22, 81",
|
||||
@@ -3620,9 +3941,9 @@
|
||||
"type": "canvas"
|
||||
}
|
||||
],
|
||||
"preload": false,
|
||||
"refresh": "",
|
||||
"revision": 1,
|
||||
"schemaVersion": 39,
|
||||
"schemaVersion": 41,
|
||||
"tags": ["gdev", "panel-tests", "canvas"],
|
||||
"templating": {
|
||||
"list": []
|
||||
@@ -3631,11 +3952,9 @@
|
||||
"from": "now-6h",
|
||||
"to": "now"
|
||||
},
|
||||
"timeRangeUpdatedDuringEditOrView": false,
|
||||
"timepicker": {},
|
||||
"timezone": "",
|
||||
"title": "Panel Tests - Canvas Connection Examples",
|
||||
"uid": "Pu8lwQAVz",
|
||||
"version": 6,
|
||||
"weekStart": ""
|
||||
"version": 15
|
||||
}
|
||||
|
||||
@@ -30,6 +30,16 @@ Read on for an overview on how to get started with plugins:
|
||||
- Configure backend communication between installed plugins.
|
||||
- Improve security by isolating plugins with the Plugin Frontend Sandbox.
|
||||
|
||||
## Types of plugins
|
||||
|
||||
Grafana supports three types of plugins:
|
||||
|
||||
- [Panels](/grafana/plugins/panel-plugins) - These plugins make it easy to create and add any kind of visualization, to show your data, or improve your favorite dashboards.
|
||||
- [Data sources](/grafana/plugins/data-source-plugins) - These plugins allow you to pull data from various data sources such as databases, APIs, log files, and so on, and display it in the form of graphs, charts, and dashboards in Grafana.
|
||||
- [Apps](/grafana/plugins/app-plugins) - These plugins enable the bundling of data sources, panels, dashboards, and Grafana pages into a cohesive experience.
|
||||
|
||||
Read more in [Types of plugins](plugin-types).
|
||||
|
||||
## 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](../roles-and-permissions/).
|
||||
@@ -40,41 +50,12 @@ The following access rules apply depending on the user role:
|
||||
- If you are a **Server Admin**, you can't configure app plugins, but you can install, uninstall, or update them.
|
||||
- If you are both **Org Admin** and **Server Admin**, you can configure app plugins and also install, uninstall, or update them.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
The Grafana plugin catalog is designed to work with a single Grafana server instance only. Support for Grafana clusters is planned for future Grafana releases.
|
||||
{{< /admonition >}}
|
||||
|
||||
<div class="medium-6 columns">
|
||||
<video width="700" height="600" controls>
|
||||
<source src="/static/assets/videos/plugins-catalog-install-9.2.mp4" type="video/mp4">
|
||||
Your browser does not support the video tag.
|
||||
</video>
|
||||
</div>
|
||||
|
||||
_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](../../setup-grafana/configure-grafana/#plugin_admin_enabled) file.
|
||||
{{< /admonition >}}
|
||||
|
||||
<a id="#plugin-catalog-entry"></a>
|
||||
|
||||
### Types of plugins
|
||||
|
||||
Grafana supports three types of plugins:
|
||||
|
||||
- [Panels](/grafana/plugins/panel-plugins) - These plugins make it easy to create and add any kind of panel, to show your data, or improve your favorite dashboards.
|
||||
- [Data sources](/grafana/plugins/data-source-plugins) - These plugins allow you to pull data from various data sources such as databases, APIs, log files, and so on, and display it in the form of graphs, charts, and dashboards in Grafana.
|
||||
- [Apps](/grafana/plugins/app-plugins) - These plugins enable the bundling of data sources, panels, dashboards, and Grafana pages into a cohesive experience.
|
||||
|
||||
Read more in [Types of plugins](plugin-types).
|
||||
|
||||
### Browse plugins
|
||||
|
||||
To browse for available plugins:
|
||||
|
||||
1. While logged into Grafana as an administrator, click **Administration > Plugins and data > Plugins** in the side menu to view installed and available plugins.
|
||||
1. Use the search to filter based on name, keywords, organization and other metadata.
|
||||
1. Use the search box to filter based on name, keywords, organization and other metadata.
|
||||
1. Click the **Data sources**, **Panels**, or **Applications** buttons to filter by plugin type.
|
||||
|
||||
## Manage your plugins
|
||||
@@ -126,7 +107,7 @@ Plugin signature verification, also known as _signing_, is a security measure to
|
||||
|
||||
You can relocate app plugin pages to customize the navigation menu structure, as explained in [Customize navigation placement of plugin pages](customize-nav-bar).
|
||||
|
||||
### Integrate plugins
|
||||
### Allow plugin backend communication
|
||||
|
||||
You can configure your Grafana instance to let the frontends of installed plugins directly communicate locally with the backends of other installed plugins. See how in [Configure backend communication between installed plugins](plugin-integrate).
|
||||
|
||||
@@ -134,6 +115,13 @@ You can configure your Grafana instance to let the frontends of installed plugin
|
||||
|
||||
You can use the [Plugin Frontend Sandbox](plugin-frontend-sandbox) to securely isolate plugin frontend code from the main Grafana application.
|
||||
|
||||
When enabled, plugins run in a separate JavaScript context, which provides several security benefits:
|
||||
|
||||
- Prevents plugins from modifying parts of the Grafana interface outside their designated areas
|
||||
- Stops plugins from interfering with other plugins functionality
|
||||
- Protects core Grafana features from being altered by plugins
|
||||
- Prevents plugins from modifying global browser objects and behaviors
|
||||
|
||||
### Learn more
|
||||
|
||||
- [Browse available plugins](/grafana/plugins)
|
||||
|
||||
@@ -45,6 +45,12 @@ Data source plugins communicate with external sources of data and return the dat
|
||||
|
||||
Use data source plugins when you want to query data from external or third-party systems.
|
||||
|
||||
### Managing access for data source plugins
|
||||
|
||||
Administrators can grant access to data source plugins with [LBAC](/docs/grafana/<GRAFANA_VERSION>/administration/data-source-management/teamlbac/).
|
||||
|
||||
Label Based Access Control (LBAC) customizes access rights based on team memberships, ensuring that users only query data relevant to their assigned permissions.
|
||||
|
||||
## App plugins
|
||||
|
||||
Applications, or app plugins, bundle data sources and panels to provide a cohesive experience, such as the [Zabbix](/grafana/plugins/alexanderzobnin-zabbix-app) app.
|
||||
@@ -57,7 +63,9 @@ Use app plugins when you want an out-of-the-box monitoring experience.
|
||||
|
||||
Customize access to app plugins with [RBAC](/docs/grafana/<GRAFANA_VERSION>/administration/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.
|
||||
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](/docs/grafana/<GRAFANA_VERSION>/administration/roles-and-permissions/access-control/plan-rbac-rollout-strategy/#prevent-viewers-from-accessing-an-app-plugin).
|
||||
|
||||
@@ -81,12 +81,16 @@ Folders help you organize and group dashboards, which is useful when you have ma
|
||||
|
||||
1. Enter a unique name and click **Create**.
|
||||
|
||||
Folder names can't include underscores (\_) or percentage signs (%), as it interferes with the search functionality.
|
||||
|
||||
Also, alerts can't be placed in folders with slashes (\ /) in the name. If you want to place alerts in the folder, don't use slashes in the folder name.
|
||||
|
||||
When you nest folders, you can do so up to four levels deep.
|
||||
|
||||
When you save a dashboard, you can optionally select a folder to save the dashboard in.
|
||||
|
||||
{{< admonition type="note" >}}
|
||||
Alerts can't be placed in folders with slashes (\ /) in the name. If you wish to place alerts in the folder, don't use slashes in the folder name.
|
||||
|
||||
{{< /admonition >}}
|
||||
|
||||
**To edit the name of a folder:**
|
||||
|
||||
@@ -688,7 +688,7 @@
|
||||
},
|
||||
"languages": {
|
||||
"type": "array",
|
||||
"description": "The list of languages supported by the plugin. Each entry should be a locale identifier in the format `language-COUNTRY` (e.g., `en-US`, `fr-FR`, `es-ES`).",
|
||||
"description": "The list of languages supported by the plugin. Each entry should be a locale identifier in the format `language-COUNTRY` (for example `en-US`, `fr-FR`, `es-ES`).",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
|
||||
@@ -481,12 +481,19 @@ You can style the selected connection using the following options:
|
||||
- **Color** - Set the connection color.
|
||||
- **Size** - Control the size of the connection by entering a number in the **Value** field.
|
||||
- **Radius** - Add curve to the connection by entering a value to represent the degree.
|
||||
- **Arrow Direction** - Control the appearance of the arrow head. Choose from:
|
||||
- **Direction** - Control the appearance of the arrow head. Choose your source from **Fixed** or **Field**. The default value is **Forward** regardless of the source type.
|
||||
|
||||
If the direction source is **Fixed**, choose from:
|
||||
- **Forward** - The arrow head points in the direction in which the connection was drawn.
|
||||
- **Reverse** - The arrow head points in the opposite direction of which the connection was drawn.
|
||||
- **Both** - Adds arrow heads to both ends of the connection.
|
||||
- **None** - Removes the arrow head.
|
||||
|
||||
If the direction source is **Field**, select a field that contains numeric values:
|
||||
- **Positive values** - Display forward arrows.
|
||||
- **Negative values** - Display reverse arrows.
|
||||
- **Zero** - Display no arrow heads.
|
||||
|
||||
- **Line style** - Choose from the following line styles: **Solid**, **Dashed**, and **Dotted**.
|
||||
|
||||
### Standard options
|
||||
|
||||
@@ -281,7 +281,7 @@ The markers layer allows you to display data points as different marker shapes s
|
||||
| Symbol Horizontal Align | Configures the horizontal alignment of the symbol relative to the data point. Note that the symbol's rotation angle is applied first around the data point, then the horizontal alignment is applied relative to the rotation of the symbol. |
|
||||
| Color | Configures the color of the markers. The default `Fixed color` sets all markers to a specific color. There is also an option to have conditional colors depending on the selected field data point values and the color scheme set in the `Standard options` section. |
|
||||
| Fill opacity | Configures the transparency of each marker. |
|
||||
| Rotation angle | Configures the rotation angle of each marker. The default is `Fixed value`, which makes all markers rotate to the same angle regardless of the data; however, there is also an option to set the rotation of the markers based on data corresponding to a selected field. |
|
||||
| Rotation angle | Configures the rotation angle of each marker in degrees. The default is `Fixed value`, which makes all markers rotate to the same angle regardless of the data; however, there is also an option to set the rotation of the markers based on data corresponding to a selected field. |
|
||||
| Text label | Configures a text label for each marker. |
|
||||
| Show legend | Allows you to toggle the legend for the layer. |
|
||||
| Display tooltip | Allows you to toggle tooltips for the layer. |
|
||||
@@ -448,7 +448,7 @@ You can convert node graph data to a network layer:
|
||||
| Symbol | Allows you to choose the symbol, icon, or graphic to aid in providing additional visual context to your data. Choose from assets that are included with Grafana such as simple symbols or the Unicon library. You can also specify a URL containing an image asset. The image must be a scalable vector graphic (SVG). |
|
||||
| Color | Configures the color of the nodes. The default `Fixed color` sets all nodes to a specific color. There is also an option to have conditional colors depending on the selected field data point values and the color scheme set in the `Standard options` section. |
|
||||
| Fill opacity | Configures the transparency of each node. |
|
||||
| Rotation angle | Configures the rotation angle of each node. The default is `Fixed value`, which makes all nodes rotate to the same angle regardless of the data; however, there is also an option to set the rotation of the nodes based on data corresponding to a selected field. |
|
||||
| Rotation angle | Configures the rotation angle of each node in degrees. The default is `Fixed value`, which makes all nodes rotate to the same angle regardless of the data; however, there is also an option to set the rotation of the nodes based on data corresponding to a selected field. |
|
||||
| Text label | Configures a text label for each node. |
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
|
||||
@@ -198,6 +198,14 @@ List of enabled loggers.
|
||||
|
||||
Keep dashboard content in the logs (request or response fields). This can significantly increase the size of your logs.
|
||||
|
||||
### log_datasource_query_request_body
|
||||
|
||||
Whether to record data source queries' request body. This can significantly increase the size of your logs. Enabled by default.
|
||||
|
||||
### log_datasource_query_response_body
|
||||
|
||||
Whether to record data source queries' response body. This can significantly increase the size of your logs. Enabled by default.
|
||||
|
||||
### verbose
|
||||
|
||||
Log all requests and keep requests and responses body. This can significantly increase the size of your logs.
|
||||
|
||||
@@ -371,6 +371,10 @@ enabled = false
|
||||
loggers = file
|
||||
# Keep dashboard content in the logs (request or response fields); this can significantly increase the size of your logs.
|
||||
log_dashboard_content = false
|
||||
# Whether to record data source queries' request body. This can significantly increase the size of your logs. Enabled by default.
|
||||
log_datasource_query_request_body = true
|
||||
# Whether to record data source queries' response body. This can significantly increase the size of your logs. Enabled by default.
|
||||
log_datasource_query_response_body = true
|
||||
# Keep requests and responses body; this can significantly increase the size of your logs.
|
||||
verbose = false
|
||||
# Write an audit log for every status code.
|
||||
|
||||
@@ -143,7 +143,7 @@ If set to `true`, the Grafana server redirects requests that have a Host-header
|
||||
Example:
|
||||
|
||||
```toml
|
||||
[sever]
|
||||
[server]
|
||||
# Redirect to correct domain if host header does not match domain
|
||||
# Prevents DNS rebinding attacks
|
||||
enforce_domain = true
|
||||
|
||||
@@ -68,7 +68,7 @@ Grafana currently follows a monthly release schedule. Below are the planned rele
|
||||
|
||||
- The schedule above outlines how we plan release dates. However, unforeseen events and circumstances may cause dates to change.
|
||||
- High severity security and feature degradation incidents will result in ad-hoc releases that are not scheduled ahead of time.
|
||||
- Patching releases are for the current (last released) minor version of Grafana. Additional older versions of Grafana may be included if there is a critical bug or security vulnerability that needs to be patched.
|
||||
- Patching releases are for all supported minor versions of Grafana. Each supported minor version receives patch releases with bug fixes and security patches until its end of life.
|
||||
- Release freezes: Each year Grafana implements two release freezes to accommodate for the holiday season. During these times, no scheduled releases will be executed. However, this does not apply to changes that may be required during the course of an operational or security incident.
|
||||
|
||||
## Grafana security releases: improved version naming convention
|
||||
@@ -96,47 +96,63 @@ For self-managed Grafana (both Enterprise and OSS), the support for versions fol
|
||||
- Each minor release is supported for 9 months after its release date
|
||||
- The last minor release of a major version receives extended support for 15 months after its release date
|
||||
- Support levels change as new versions are released:
|
||||
- **Full Support**: The most recently released major/minor version receive full support including new features, bug fixes, and security patches
|
||||
- **Security & Critical Bugs Only**: Versions that are outside of the most recently released major/minor version, but still within their support period, receive only security patches and critical bug fixes
|
||||
- **Full Support**: The current major version receives new features through new minor releases
|
||||
- **Patch Support**: Individual minor versions receive patch releases (bug fixes and security patches) until end of life
|
||||
- **Not Supported**: Versions beyond their support period receive no updates
|
||||
|
||||
Here is an overview of version support through 2026:
|
||||
|
||||
| **Version** | **Release date** | **Support end date** | **Support level** |
|
||||
| ------------------------- | ------------------ | -------------------- | ----------------------------- |
|
||||
| 10.2.x | October 24, 2023 | July 24, 2024 | Not Supported |
|
||||
| 10.3.x | January 23, 2024 | October 23, 2024 | Not Supported |
|
||||
| 10.4.x (Last minor of 10) | March 5, 2024 | June 5, 2025 | Not Supported |
|
||||
| 11.0.x | May 14, 2024 | February 14, 2025 | Not Supported |
|
||||
| 11.1.x | June 25, 2024 | April 23, 2025 | Not Supported |
|
||||
| 11.2.x | August 27, 2024 | May 27, 2025 | Not Supported |
|
||||
| 11.3.x | October 22, 2024 | July 22, 2025 | Not Supported |
|
||||
| 11.4.x | December 5, 2024 | September 5, 2025 | Security & Critical Bugs Only |
|
||||
| 11.5.x | January 28, 2025 | October 28, 2025 | Security & Critical Bugs Only |
|
||||
| 11.6.x (Last minor of 11) | March 25, 2025 | June 25, 2026 | Security & Critical Bugs Only |
|
||||
| 12.0.x | May 5, 2025 | February 5, 2026 | Security & Critical Bugs Only |
|
||||
| 12.1.x | July 22, 2025 | April 22, 2026 | Full Support until next minor |
|
||||
| 12.2.x | September 23, 2025 | June 23, 2026 | Yet to be released |
|
||||
| 12.3.x | November 18, 2025 | August 18, 2026 | Yet to be released |
|
||||
| **Version** | **Release date** | **Support end date** | **Support level** |
|
||||
| ------------------------- | ------------------ | -------------------- | ------------------ |
|
||||
| 10.2.x | October 24, 2023 | July 24, 2024 | Not Supported |
|
||||
| 10.3.x | January 23, 2024 | October 23, 2024 | Not Supported |
|
||||
| 10.4.x (Last minor of 10) | March 5, 2024 | June 5, 2025 | Not Supported |
|
||||
| 11.0.x | May 14, 2024 | February 14, 2025 | Not Supported |
|
||||
| 11.1.x | June 25, 2024 | April 23, 2025 | Not Supported |
|
||||
| 11.2.x | August 27, 2024 | May 27, 2025 | Not Supported |
|
||||
| 11.3.x | October 22, 2024 | July 22, 2025 | Not Supported |
|
||||
| 11.4.x | December 5, 2024 | September 5, 2025 | Patch Support |
|
||||
| 11.5.x | January 28, 2025 | October 28, 2025 | Patch Support |
|
||||
| 11.6.x (Last minor of 11) | March 25, 2025 | June 25, 2026 | Patch Support |
|
||||
| 12.0.x | May 5, 2025 | February 5, 2026 | Patch Support |
|
||||
| 12.1.x | July 22, 2025 | April 22, 2026 | Patch Support |
|
||||
| 12.2.x | September 23, 2025 | June 23, 2026 | Yet to be released |
|
||||
| 12.3.x | November 18, 2025 | August 18, 2026 | Yet to be released |
|
||||
|
||||
## How are these versions supported?
|
||||
|
||||
The level of support changes as new versions of Grafana are released. Here are the key details:
|
||||
Self-managed Grafana follows semantic-like versioning (MAJOR.MINOR.PATCH). Here's how different types of releases work:
|
||||
|
||||
- **Full Support**:
|
||||
- All new features
|
||||
- All bug fixes
|
||||
- Security patches
|
||||
- Regular updates
|
||||
- **Major releases** (e.g., 12.0.0, 13.0.0):
|
||||
- Awesome new features as well as significant architectural improvements and modernizations
|
||||
- May include breaking changes that require migration steps
|
||||
- Released once per year
|
||||
|
||||
- **Security & Critical Bugs Only**:
|
||||
- Security vulnerability patches
|
||||
- Critical bug fixes that cause feature degradation
|
||||
- No new features
|
||||
- **Minor releases** (e.g., 12.3.0, 12.4.0):
|
||||
- Contain new features and enhancements
|
||||
- Include bug fixes and security patches
|
||||
- Released every other month
|
||||
|
||||
- **Patch releases** (e.g., 12.3.1, 12.3.2):
|
||||
- **Only** contain bug fixes and security patches
|
||||
- **No new features** - these wait until the next minor release
|
||||
- Released monthly
|
||||
|
||||
**Support levels by version:**
|
||||
|
||||
- **Full Support** (current major version):
|
||||
- Gets new minor releases with new features approximately every other month
|
||||
- All minor versions within the major receive patch releases until end of life
|
||||
- Example: Major 12.x gets new features via 12.1.0, 12.2.0, 12.3.0, etc.
|
||||
|
||||
- **Patch Support** (individual minor versions):
|
||||
- Each minor version receives patch releases (bug fixes and security patches) until end of life
|
||||
- No new features - these only come with new minor releases
|
||||
- Example: 12.3.x gets 12.3.1, 12.3.2, etc. with fixes only
|
||||
|
||||
- **Not Supported**: Versions beyond their support period receive no updates and should be upgraded.
|
||||
|
||||
Keeping all this in mind, users that want to receive the most recent features and all bug fixes should be on the current (most recently released) version of Grafana.
|
||||
**Example**: When 12.3.0 is released, it includes new features. Subsequent releases like 12.3.1 and 12.3.2 only include bug fixes and security updates. All new features developed after 12.3.0 wait until 12.4.0 is released.
|
||||
|
||||
### What is a critical feature degradation?
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ test.describe(
|
||||
const initialBackground = await panelTitle.evaluate((el) => getComputedStyle(el).background);
|
||||
expect(initialBackground).not.toMatch(/rgba\(0, 0, 0, 0\)/);
|
||||
|
||||
await page.getByRole('switch', { name: 'Transparent background' }).click({ force: true });
|
||||
await page.locator('#transparent-background').click({ force: true });
|
||||
|
||||
const transparentBackground = await panelTitle.evaluate((el) => getComputedStyle(el).background);
|
||||
expect(transparentBackground).toMatch(/rgba\(0, 0, 0, 0\)/);
|
||||
|
||||
@@ -95,8 +95,8 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table']
|
||||
await dashboardPage
|
||||
.getByGrafanaSelector(selectors.components.PanelEditor.OptionsPane.fieldLabel('Cell options Cell value inspect'))
|
||||
.first()
|
||||
.getByRole('switch', { name: 'Cell value inspect' })
|
||||
.click({ force: true });
|
||||
.locator('label[for="custom.inspect"]')
|
||||
.click();
|
||||
await loremIpsumCell.hover();
|
||||
await expect(getCellHeight(page, 1, longTextColIdx)).resolves.toBeLessThan(100);
|
||||
|
||||
@@ -133,6 +133,15 @@ test.describe('Panels test: Table - Kitchen Sink', { tag: ['@panels', '@table']
|
||||
await displayNameInput.fill('State (renamed)');
|
||||
await displayNameInput.press('Enter');
|
||||
expect(page.getByRole('row').nth(0)).toContainText('State (renamed)');
|
||||
|
||||
// toggle the "State" column visibility again to hide it again. this confirms that we avoid bugs related to
|
||||
// array lengths between the fields array and the column widths array.
|
||||
await hideStateColumnSwitch.click();
|
||||
expect(page.getByRole('row').nth(0)).not.toContainText('State');
|
||||
|
||||
// since the previous assertion is just for the absence of text, let's also confirm that the table is
|
||||
// actually still on the page and that an error has not been throw.
|
||||
await waitForTableLoad(page);
|
||||
});
|
||||
|
||||
// we test niche cases for sorting, filtering, pagination, etc. in a unit tests already.
|
||||
|
||||
@@ -17,35 +17,35 @@ describe('Geomap layer controls options', () => {
|
||||
e2e.components.PanelEditor.showZoomField()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input[type="checkbox"]').check({ force: true });
|
||||
cy.get('input[type="checkbox"]').check({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
// Show attribution
|
||||
e2e.components.PanelEditor.showAttributionField()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input[type="checkbox"]').check({ force: true });
|
||||
cy.get('input[type="checkbox"]').check({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
// Show scale
|
||||
e2e.components.PanelEditor.showScaleField()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input[type="checkbox"]').check({ force: true });
|
||||
cy.get('input[type="checkbox"]').check({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
// Show measure tool
|
||||
e2e.components.PanelEditor.showMeasureField()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input[type="checkbox"]').check({ force: true });
|
||||
cy.get('input[type="checkbox"]').check({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
// Show debug
|
||||
e2e.components.PanelEditor.showDebugField()
|
||||
.should('be.visible')
|
||||
.within(() => {
|
||||
cy.get('input[type="checkbox"]').check({ force: true });
|
||||
cy.get('input[type="checkbox"]').check({ force: true }).should('be.checked');
|
||||
});
|
||||
|
||||
e2e.components.Panels.Panel.content({ timeout: TIMEOUT })
|
||||
|
||||
+6
-13
@@ -8,8 +8,6 @@ const jsxA11yPlugin = require('eslint-plugin-jsx-a11y');
|
||||
const lodashPlugin = require('eslint-plugin-lodash');
|
||||
const barrelPlugin = require('eslint-plugin-no-barrel-files');
|
||||
const reactPlugin = require('eslint-plugin-react');
|
||||
// FIXME: Remove once eslint-config-grafana is updated to include correct plugin
|
||||
const hooksPlugin = require('eslint-plugin-react-hooks');
|
||||
const testingLibraryPlugin = require('eslint-plugin-testing-library');
|
||||
const unicornPlugin = require('eslint-plugin-unicorn');
|
||||
|
||||
@@ -60,17 +58,7 @@ module.exports = [
|
||||
'public/build-swagger', // swagger build output
|
||||
],
|
||||
},
|
||||
// FIXME: Remove once eslint-config-grafana is updated to include correct plugin
|
||||
{
|
||||
name: 'react-hooks-plugin',
|
||||
plugins: {
|
||||
'react-hooks': hooksPlugin,
|
||||
},
|
||||
},
|
||||
// Conditionally run the betterer rules if enabled in dev's config
|
||||
...(enableBettererRules ? bettererConfig : []),
|
||||
// FIXME: Remove filtering once eslint-config-grafana is updated to include correct plugin
|
||||
...grafanaConfig.filter(Boolean),
|
||||
...grafanaConfig,
|
||||
{
|
||||
name: 'react/jsx-runtime-rules',
|
||||
rules: reactPlugin.configs.flat['jsx-runtime'].rules,
|
||||
@@ -176,6 +164,8 @@ module.exports = [
|
||||
],
|
||||
// FIXME: Fix these in follow up PR
|
||||
'react/no-unescaped-entities': 'off',
|
||||
// Turn off react-hooks/rules-of-hooks whilst present in betterer
|
||||
'react-hooks/rules-of-hooks': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -455,4 +445,7 @@ module.exports = [
|
||||
],
|
||||
},
|
||||
},
|
||||
// Conditionally run the betterer rules if enabled in dev's config
|
||||
// Should be last in the config so it can override any temporary disables in here
|
||||
...(enableBettererRules ? bettererConfig : []),
|
||||
];
|
||||
|
||||
@@ -85,7 +85,7 @@ require (
|
||||
github.com/googleapis/gax-go/v2 v2.14.2 // @grafana/grafana-backend-group
|
||||
github.com/gorilla/mux v1.8.1 // @grafana/grafana-backend-group
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // @grafana/grafana-app-platform-squad
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1 // @grafana/alerting-backend
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0 // @grafana/alerting-backend
|
||||
github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team
|
||||
github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 // @grafana/identity-access-team
|
||||
github.com/grafana/dataplane/examples v0.0.1 // @grafana/observability-metrics
|
||||
|
||||
@@ -1580,8 +1580,8 @@ github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7Fsg
|
||||
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1 h1:nn19bwMFBGWOvUTxZsdewOfRiXERhKHp0jEira8uQA8=
|
||||
github.com/grafana/alerting v0.0.0-20250812203446-a38b2187d4e1/go.mod h1:VKxaR93Gff0ZlO2sPcdPVob1a/UzArFEW5zx3Bpyhls=
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0 h1:CC+ShIgoLTBsAulRfJH9xF++Us6Y3va3VFbeDeJym2M=
|
||||
github.com/grafana/alerting v0.0.0-20250821181654-10915888e4f0/go.mod h1:VKxaR93Gff0ZlO2sPcdPVob1a/UzArFEW5zx3Bpyhls=
|
||||
github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43 h1:vVPT0i5Y1vI6qzecYStV2yk7cHKrC3Pc7AgvwT5KydQ=
|
||||
github.com/grafana/authlib v0.0.0-20250710201142-9542f2f28d43/go.mod h1:1fWkOiL+m32NBgRHZtlZGz2ji868tPZACYbqP3nBRJI=
|
||||
github.com/grafana/authlib/types v0.0.0-20250710201142-9542f2f28d43 h1:NlkGMnVi/oUn6Cr90QbJYpQJ4FnjyAIG9Ex5GtTZIzw=
|
||||
|
||||
+13
@@ -1095,6 +1095,8 @@ github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGU
|
||||
github.com/jackc/pgx v3.2.0+incompatible h1:0Vihzu20St42/UDsvZGdNE6jak7oi/UOeMzwMPHkgFY=
|
||||
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1 h1:9Xm8CKtMZIXgcopfdWk/qZ1rt0HjMgfMR9nxxSeK6vk=
|
||||
github.com/jackspirou/syscerts v0.0.0-20160531025014-b68f5469dff1/go.mod h1:zuHl3Hh+e9P6gmBPvcqR1HjkaWHC/csgyskg6IaFKFo=
|
||||
github.com/jaegertracing/jaeger v1.67.0 h1:t0BiJZVW9D3Z16y3uHqKzV9bKFTusooTH1Kgr77xF2Q=
|
||||
github.com/jaegertracing/jaeger v1.67.0/go.mod h1:tE/FEQfybCSdUbBgel51YaCSkc58O+Njih8oTl6j8vw=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7 h1:m+LbHpm0aIAPLzLbMfn8dc3Ht8MW7lsSO4MPItz/Uuo=
|
||||
github.com/jedib0t/go-pretty/v6 v6.6.7/go.mod h1:YwC5CE4fJ1HFUDeivSV1r//AmANFHyqczZk+U6BDALU=
|
||||
github.com/jhump/gopoet v0.1.0 h1:gYjOPnzHd2nzB37xYQZxj4EIQNpBrBskRqQQ3q4ZgSg=
|
||||
@@ -1268,6 +1270,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.1
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/extension/storage v0.121.0/go.mod h1:/+tb7Hkt0i92WFkkfHurT7rXrZ98nxat5AeGmbBYFm4=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.121.0 h1:Q27uarV8CEGLKfG4OJQGFkOKZ49/SDEqTr6BbMOoKmA=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.121.0/go.mod h1:f9MPSdMvooe2s9Zg0WVBJOvg72d9fFikxFt7yniFros=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1 h1:NrjsoVPxI6lmV8jPImDcMeqYh+97Y71f/HB5Sfpfe3I=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/coreinternal v0.124.1/go.mod h1:AFMryJmht7dZxcAwc2sx/r4gxbriElWw49ugxKp2mcA=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.121.0 h1:I+F6xdXQsiXXdce7yjHN+y4LX5MrZI1kNmhBunJffdA=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/exp/metrics v0.121.0/go.mod h1:cRh3l2emFBwW96dHnlPLr1psbEYjYJmn5qFujOkbfRo=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/filter v0.124.1 h1:2uQmRiQ7EV7s1slz7fEvAVhJIFTyExnj/4unfw0Era8=
|
||||
@@ -1280,6 +1284,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcompone
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/internal/sharedcomponent v0.124.1/go.mod h1:jRQpw8VJDmUmyH8ONQ5FmhYEXkaxzMFX6Tei8N4GDZs=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.121.0 h1:dnRf9xyjTBGHui949SS0A87fNa49Al32dog9XmeGY7I=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/batchpersignal v0.121.0/go.mod h1:ZAFQ1Te56fodNun+lmC/jFjVxhecumV882ct8sbdeAM=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1 h1:E1e96GTHmiAfIfeYfA5ZVnOxud3+vbisGp0gE1tfd4s=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/core/xidutils v0.124.1/go.mod h1:MOhFATtYSLad9nKunjh6uGf8nQUcWje2LPlhD2uu3do=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.124.1 h1:QX88VjAiUaG7SQe4A14b3JPgvzZK6OXpWoBd32Zlp1o=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.124.1/go.mod h1:jRsmTRbn1HkrOpoeXS0KGfXobrh7E3W/p9fLwLdpcB8=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/kafka/topic v0.121.0 h1:7xzxbwIBpb8LlMNY+RIdEnWTJH+pDu0LiL+tcIziEkA=
|
||||
@@ -1296,6 +1302,8 @@ github.com/open-telemetry/opentelemetry-collector-contrib/pkg/status v0.121.0 h1
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/status v0.121.0/go.mod h1:PQjfR4WB9Q1MR9X/6IqxWGpKfavp9OF1fUcAqnPGGpQ=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/azure v0.124.1 h1:kPPjaOlncaJjoaJRUzW3TbqHM4v/+TtxC2Bzpa7z9X4=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/azure v0.124.1/go.mod h1:+6zqsZ1YGNsl7RUxfjzg7MKEWd5J6QAlq7zM3Nqy8UI=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1 h1:9c6L4xlAMqhOg5y54Bc2B5t0i49yz7v2I6I8RY4Z0/o=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/jaeger v0.124.1/go.mod h1:6f0N58o0cOHC0ApSM/qrooVmQza1eQ7L53PDE91uO1Q=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus v0.124.1 h1:IYxc8uPVCtKlgxjbYFGZ5/wXLdwAH1WQPKRlzaXtr8E=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/opencensus v0.124.1/go.mod h1:jFRiSEn2ss3e4CWG6GTDOJMYRI0C/N2XbMMIBzZuqZY=
|
||||
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheus v0.121.0 h1:QzV771eoAx2W9HCFq/YJVMNgEuG4lvalPTQIutheFhc=
|
||||
@@ -1535,6 +1543,7 @@ go.etcd.io/gofail v0.2.0 h1:p19drv16FKK345a09a1iubchlw/vmRuksmRzgBIGjcA=
|
||||
go.etcd.io/gofail v0.2.0/go.mod h1:nL3ILMGfkXTekKI3clMBNazKnjUZjYLKmBHzsVAnC1o=
|
||||
go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c=
|
||||
go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
|
||||
go.opentelemetry.io/collector v0.124.0 h1:g/dfdGFhBcQI0ggGxTmGlJnJ6Yl6T2gVxQoIj4UfXCc=
|
||||
go.opentelemetry.io/collector v0.124.0/go.mod h1:QzERYfmHUedawjr8Ph/CBEEkVqWS8IlxRLAZt+KHlCg=
|
||||
go.opentelemetry.io/collector/client v1.30.0 h1:QbvOrvwUGcnVjnIBn2zyLLubisOjgh7kMgkzDAiYpHg=
|
||||
go.opentelemetry.io/collector/client v1.30.0/go.mod h1:msXhZlNdAra2fZiyeT0o/xj43Kl1yvF9zYW0r+FhGUI=
|
||||
@@ -1636,6 +1645,8 @@ go.opentelemetry.io/collector/internal/telemetry v0.124.0 h1:kzd1/ZYhLj4bt2pDB52
|
||||
go.opentelemetry.io/collector/internal/telemetry v0.124.0/go.mod h1:ZjXjqV0dJ+6D4XGhTOxg/WHjnhdmXsmwmUSgALea66Y=
|
||||
go.opentelemetry.io/collector/otelcol v0.124.0 h1:q/+ebTZgEZX+yFbvO7FeqpEtvtRPJ+YzZzHsVzqA71s=
|
||||
go.opentelemetry.io/collector/otelcol v0.124.0/go.mod h1:mFGJZn5YuffdMVO/lPBavbW+R64Dgd3jOMgw2WAmJEM=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.124.0 h1:ZjL9wKqzP4BHj0/F1jfGxs1Va8B7xmYayipZeNVoWJE=
|
||||
go.opentelemetry.io/collector/pdata/pprofile v0.124.0/go.mod h1:1EN3Gw5LSI4fSVma/Yfv/6nqeuYgRTm1/kmG5nE5Oyo=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.124.0 h1:vY+pWG7CQfzzGSB5+zGYHQOltRQr59Ek9QiPe+rI+NY=
|
||||
go.opentelemetry.io/collector/pdata/testdata v0.124.0/go.mod h1:lNH48lGhGv4CYk27fJecpsR1zYHmZjKgNrAprwjym0o=
|
||||
go.opentelemetry.io/collector/pipeline v0.124.0 h1:hKvhDyH2GPnNO8LGL34ugf36sY7EOXPjBvlrvBhsOdw=
|
||||
@@ -1668,6 +1679,8 @@ go.opentelemetry.io/collector/receiver/receivertest v0.124.0 h1:mx0290aXAo+wfjm4
|
||||
go.opentelemetry.io/collector/receiver/receivertest v0.124.0/go.mod h1:3RpopRmIzx5T4zTStHJC0HHfd8YFWm8e9bia1HiuDtY=
|
||||
go.opentelemetry.io/collector/receiver/xreceiver v0.124.0 h1:YigTUKk8p/aIfqaT0ST7teT9KbLThWD5n2km83byftw=
|
||||
go.opentelemetry.io/collector/receiver/xreceiver v0.124.0/go.mod h1:NkTpmpAEDT17Dko4gpHUnRztrSkdSd6B0+Y4gfuCWIA=
|
||||
go.opentelemetry.io/collector/semconv v0.124.0 h1:YTdo3UFwNyDQCh9DiSm2rbzAgBuwn/9dNZ0rv454goA=
|
||||
go.opentelemetry.io/collector/semconv v0.124.0/go.mod h1:te6VQ4zZJO5Lp8dM2XIhDxDiL45mwX0YAQQWRQ0Qr9U=
|
||||
go.opentelemetry.io/collector/service v0.124.0 h1:lUpizko/Y2P+XXbZ9wiKM8acLSt6ZIvC3/6/j6rcq4w=
|
||||
go.opentelemetry.io/collector/service v0.124.0/go.mod h1:w2eL3KKOMW4CvqCWyZ3P/Qh1ZBEPGG/uRz/0LpHbpv0=
|
||||
go.opentelemetry.io/collector/service/hostcapabilities v0.124.0 h1:ArxbARF7+bnzK8xLnN2G41KInbcN1aGhSBR76VeUQi8=
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
include ../.bingo/Variables.mk
|
||||
|
||||
.PHONY: all
|
||||
all: dashboards
|
||||
|
||||
|
||||
+2
-2
@@ -89,7 +89,7 @@
|
||||
"@crowdin/crowdin-api-client": "^1.42.0",
|
||||
"@cypress/webpack-preprocessor": "6.0.4",
|
||||
"@emotion/eslint-plugin": "11.12.0",
|
||||
"@grafana/eslint-config": "8.1.0",
|
||||
"@grafana/eslint-config": "8.2.0",
|
||||
"@grafana/eslint-plugin": "link:./packages/grafana-eslint-rules",
|
||||
"@grafana/plugin-e2e": "2.1.7",
|
||||
"@grafana/test-utils": "workspace:*",
|
||||
@@ -195,7 +195,7 @@
|
||||
"eslint-plugin-lodash": "8.0.0",
|
||||
"eslint-plugin-no-barrel-files": "^1.1.1",
|
||||
"eslint-plugin-react": "7.37.5",
|
||||
"eslint-plugin-react-hooks": "5.1.0",
|
||||
"eslint-plugin-react-hooks": "5.2.0",
|
||||
"eslint-plugin-testing-library": "^7.0.0",
|
||||
"eslint-plugin-unicorn": "^56.0.0",
|
||||
"eslint-scope": "^8.1.0",
|
||||
|
||||
@@ -197,10 +197,6 @@ export interface FeatureToggles {
|
||||
*/
|
||||
provisioning?: boolean;
|
||||
/**
|
||||
* Experimental feature to use the secrets service for provisioning instead of the legacy secrets
|
||||
*/
|
||||
provisioningSecretsService?: boolean;
|
||||
/**
|
||||
* Start an additional https handler and write kubectl options
|
||||
*/
|
||||
grafanaAPIServerEnsureKubectlAccess?: boolean;
|
||||
|
||||
@@ -137,6 +137,8 @@ export interface LogRowContextOptions {
|
||||
direction?: LogRowContextQueryDirection;
|
||||
limit?: number;
|
||||
scopedVars?: ScopedVars;
|
||||
// Optional. Size of the time window to get logs before of after the referenced entry.
|
||||
timeWindowMs?: number;
|
||||
}
|
||||
|
||||
export enum LogRowContextQueryDirection {
|
||||
@@ -181,6 +183,9 @@ export interface DataSourceWithLogsContextSupport<TQuery extends DataQuery = Dat
|
||||
origQuery?: TQuery,
|
||||
scopedVars?: ScopedVars
|
||||
): React.ReactNode;
|
||||
|
||||
// Does the datasource support the user adjusting the time range in the logs context window? https://github.com/grafana/grafana/pull/109901
|
||||
supportsAdjustableWindow?: boolean;
|
||||
}
|
||||
|
||||
export const hasLogsContextSupport = (datasource: unknown): datasource is DataSourceWithLogsContextSupport => {
|
||||
|
||||
@@ -13,6 +13,9 @@ interface FolderPickerProps {
|
||||
/* Folder UIDs to exclude from the picker, to prevent invalid operations */
|
||||
excludeUIDs?: string[];
|
||||
|
||||
/* Start tree from this folder instead of root */
|
||||
rootFolderUID?: string;
|
||||
|
||||
/* Show folders matching this permission, mainly used to also show folders user can view. Defaults to showing only folders user has Edit */
|
||||
permission?: 'view' | 'edit';
|
||||
|
||||
|
||||
@@ -111,6 +111,26 @@ export enum ResourceDimensionMode {
|
||||
Mapping = 'mapping',
|
||||
}
|
||||
|
||||
/**
|
||||
* Links to a resource (image/svg path)
|
||||
*/
|
||||
export interface ResourceDimensionConfig extends BaseDimensionConfig {
|
||||
fixed?: string;
|
||||
mode: ResourceDimensionMode;
|
||||
}
|
||||
|
||||
export enum ConnectionDirection {
|
||||
Both = 'both',
|
||||
Forward = 'forward',
|
||||
None = 'none',
|
||||
Reverse = 'reverse',
|
||||
}
|
||||
|
||||
export enum DirectionDimensionMode {
|
||||
Field = 'field',
|
||||
Fixed = 'fixed',
|
||||
}
|
||||
|
||||
export interface MapLayerOptions {
|
||||
/**
|
||||
* Custom options depending on the type
|
||||
@@ -899,12 +919,9 @@ export interface DataSourceRef {
|
||||
uid?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links to a resource (image/svg path)
|
||||
*/
|
||||
export interface ResourceDimensionConfig extends BaseDimensionConfig {
|
||||
fixed?: string;
|
||||
mode: ResourceDimensionMode;
|
||||
export interface DirectionDimensionConfig extends BaseDimensionConfig {
|
||||
fixed?: ConnectionDirection;
|
||||
mode: DirectionDimensionMode;
|
||||
}
|
||||
|
||||
export interface FrameGeometrySource {
|
||||
|
||||
@@ -35,7 +35,7 @@ TextDimensionMode: "fixed" | "field" | "template" @cuetsy(kind="enum")
|
||||
TextDimensionConfig: {
|
||||
BaseDimensionConfig
|
||||
mode: TextDimensionMode
|
||||
fixed?: string
|
||||
fixed?: string
|
||||
}@cuetsy(kind="interface")
|
||||
|
||||
ResourceDimensionMode: "fixed" | "field" | "mapping" @cuetsy(kind="enum")
|
||||
@@ -44,6 +44,15 @@ ResourceDimensionMode: "fixed" | "field" | "mapping" @cuetsy(kind="enum")
|
||||
ResourceDimensionConfig: {
|
||||
BaseDimensionConfig
|
||||
mode: ResourceDimensionMode
|
||||
fixed?: string
|
||||
fixed?: string
|
||||
}@cuetsy(kind="interface")
|
||||
|
||||
ConnectionDirection: "forward" | "reverse" | "both" | "none" @cuetsy(kind="enum", memberNames="Forward|Reverse|Both|None")
|
||||
|
||||
DirectionDimensionMode: "fixed" | "field" @cuetsy(kind="enum")
|
||||
|
||||
DirectionDimensionConfig: {
|
||||
BaseDimensionConfig
|
||||
mode: DirectionDimensionMode
|
||||
fixed?: ConnectionDirection
|
||||
}@cuetsy(kind="interface")
|
||||
|
||||
+1
@@ -80,6 +80,7 @@ export enum ConnectionPath {
|
||||
|
||||
export interface CanvasConnection {
|
||||
color?: ui.ColorDimensionConfig;
|
||||
direction?: ui.DirectionDimensionConfig;
|
||||
path: ConnectionPath;
|
||||
size?: ui.ScaleDimensionConfig;
|
||||
source: ConnectionCoordinates;
|
||||
|
||||
@@ -1,9 +1,22 @@
|
||||
import { HttpHandler } from 'msw';
|
||||
|
||||
import folderHandlers from './api/folders/handlers';
|
||||
import searchHandlers from './api/search/handlers';
|
||||
import teamsHandlers from './api/teams/handlers';
|
||||
import appPlatformFolderHandlers from './apis/dashboard.grafana.app/v0alpha1/handlers';
|
||||
import appPlatformDashboardv0alpha1Handlers from './apis/dashboard.grafana.app/v0alpha1/handlers';
|
||||
import appPlatformFolderv1beta1Handlers from './apis/folder.grafana.app/v1beta1/handlers';
|
||||
import appPlatformIamv0alpha1Handlers from './apis/iam.grafana.app/v0alpha1/handlers';
|
||||
|
||||
const allHandlers: HttpHandler[] = [...teamsHandlers, ...folderHandlers, ...appPlatformFolderHandlers];
|
||||
const allHandlers: HttpHandler[] = [
|
||||
// Legacy handlers
|
||||
...teamsHandlers,
|
||||
...folderHandlers,
|
||||
...searchHandlers,
|
||||
|
||||
// App platform handlers
|
||||
...appPlatformDashboardv0alpha1Handlers,
|
||||
...appPlatformFolderv1beta1Handlers,
|
||||
...appPlatformIamv0alpha1Handlers,
|
||||
];
|
||||
|
||||
export default allHandlers;
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { Chance } from 'chance';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
|
||||
import { treeViewersCanEdit, wellFormedTree } from '../../../fixtures/folders';
|
||||
@@ -6,6 +7,26 @@ const [mockTree] = wellFormedTree();
|
||||
const [mockTreeThatViewersCanEdit] = treeViewersCanEdit();
|
||||
const collator = new Intl.Collator();
|
||||
|
||||
// TODO: Generalise access control response and additional properties
|
||||
const mockAccessControl = {
|
||||
'dashboards.permissions:write': true,
|
||||
'dashboards:create': true,
|
||||
};
|
||||
const additionalProperties = {
|
||||
canAdmin: true,
|
||||
canDelete: true,
|
||||
canEdit: true,
|
||||
canSave: true,
|
||||
created: '2025-07-14T12:07:36+02:00',
|
||||
createdBy: 'Anonymous',
|
||||
hasAcl: false,
|
||||
orgId: 1,
|
||||
updated: '2025-07-15T18:01:36+02:00',
|
||||
updatedBy: 'Anonymous',
|
||||
url: '/grafana/dashboards/f/1ca93012-1ffc-5d64-ae2e-54835c234c67/rik-cujahda-pi',
|
||||
version: 1,
|
||||
};
|
||||
|
||||
const listFoldersHandler = () =>
|
||||
http.get('/api/folders', ({ request }) => {
|
||||
const url = new URL(request.url);
|
||||
@@ -21,7 +42,9 @@ const listFoldersHandler = () =>
|
||||
const folders = tree
|
||||
.filter((v) => v.item.kind === 'folder' && v.item.parentUID === parentUid)
|
||||
.map((folder) => {
|
||||
const random = Chance(folder.item.uid);
|
||||
return {
|
||||
id: random.integer({ min: 1, max: 1000 }),
|
||||
uid: folder.item.uid,
|
||||
title: folder.item.kind === 'folder' ? folder.item.title : "invalid - this shouldn't happen",
|
||||
};
|
||||
@@ -33,17 +56,25 @@ const listFoldersHandler = () =>
|
||||
});
|
||||
|
||||
const getFolderHandler = () =>
|
||||
http.get('/api/folders/:uid', ({ params }) => {
|
||||
http.get('/api/folders/:uid', ({ params, request }) => {
|
||||
const { uid } = params;
|
||||
const url = new URL(request.url);
|
||||
const accessControlQueryParam = url.searchParams.get('accesscontrol');
|
||||
|
||||
const folder = mockTree.find((v) => v.item.uid === uid);
|
||||
|
||||
if (!folder) {
|
||||
return HttpResponse.json({ message: 'folder not found', status: 'not-found' }, { status: 404 });
|
||||
}
|
||||
|
||||
const random = Chance(folder.item.uid);
|
||||
|
||||
return HttpResponse.json({
|
||||
id: random.integer({ min: 1, max: 1000 }),
|
||||
title: folder?.item.title,
|
||||
uid: folder?.item.uid,
|
||||
...additionalProperties,
|
||||
...(accessControlQueryParam ? { accessControl: mockAccessControl } : {}),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
import { Chance } from 'chance';
|
||||
import { HttpResponse, http } from 'msw';
|
||||
|
||||
import { wellFormedTree } from '../../../fixtures/folders';
|
||||
|
||||
const [mockTree] = wellFormedTree();
|
||||
|
||||
type FilterArray = Array<(v: (typeof mockTree)[number]) => boolean>;
|
||||
|
||||
const slugify = (str: string) => {
|
||||
return str
|
||||
.toLowerCase()
|
||||
.replace(/[^\w ]+/g, '')
|
||||
.replace(/ +/g, '-');
|
||||
};
|
||||
|
||||
const getLegacySearchHandler = () =>
|
||||
http.get('/api/search', ({ request }) => {
|
||||
const folderFilter = new URL(request.url).searchParams.get('folderUIDs') || null;
|
||||
const typeFilter = new URL(request.url).searchParams.get('type') || null;
|
||||
// Workaround for the fixture kind being 'dashboard' instead of 'dash-db'
|
||||
const mappedTypeFilter = typeFilter === 'dash-db' ? 'dashboard' : typeFilter;
|
||||
const response = mockTree
|
||||
.filter((filterItem) => {
|
||||
const filters: FilterArray = [];
|
||||
if (folderFilter && folderFilter !== 'general') {
|
||||
filters.push(
|
||||
({ item }) => (item.kind === 'folder' || item.kind === 'dashboard') && item.parentUID === folderFilter
|
||||
);
|
||||
}
|
||||
|
||||
if (folderFilter === 'general') {
|
||||
filters.push(
|
||||
({ item }) => (item.kind === 'folder' || item.kind === 'dashboard') && item.parentUID === undefined
|
||||
);
|
||||
}
|
||||
|
||||
if (mappedTypeFilter) {
|
||||
filters.push(({ item }) => item.kind === mappedTypeFilter);
|
||||
}
|
||||
|
||||
return filters.every((filterPredicate) => filterPredicate(filterItem));
|
||||
})
|
||||
|
||||
.map(({ item }) => {
|
||||
const random = Chance(item.uid);
|
||||
const slugified = slugify(item.title || '');
|
||||
const parentFolder =
|
||||
item.kind === 'dashboard'
|
||||
? mockTree.find((t) => t.item.kind === 'folder' && t.item.uid === item.parentUID)
|
||||
: undefined;
|
||||
return {
|
||||
id: random.integer({ min: 1, max: 1000 }),
|
||||
uid: item.uid,
|
||||
orgId: 1,
|
||||
title: item.title,
|
||||
uri: `db/${slugified}`,
|
||||
url: `/d/${item.uid}/${slugified}`,
|
||||
folderUid: parentFolder?.item.uid,
|
||||
folderTitle: parentFolder?.item.title,
|
||||
slug: '',
|
||||
type: item.kind,
|
||||
tags: [],
|
||||
isStarred: false,
|
||||
sortMeta: 0,
|
||||
isDeleted: false,
|
||||
};
|
||||
});
|
||||
|
||||
return HttpResponse.json(response);
|
||||
});
|
||||
|
||||
export default [getLegacySearchHandler()];
|
||||
@@ -0,0 +1,117 @@
|
||||
import { HttpResponse, http } from 'msw';
|
||||
|
||||
import { wellFormedTree } from '../../../../fixtures/folders';
|
||||
|
||||
const [mockTree] = wellFormedTree();
|
||||
|
||||
const getFolderHandler = () =>
|
||||
http.get<{ folderUid: string; namespace: string }>(
|
||||
'/apis/folder.grafana.app/v1beta1/namespaces/:namespace/folders/:folderUid',
|
||||
({ params }) => {
|
||||
const { folderUid, namespace } = params;
|
||||
const response = mockTree.find(({ item }) => {
|
||||
return item.uid === folderUid;
|
||||
});
|
||||
|
||||
if (!response) {
|
||||
return HttpResponse.json(
|
||||
{
|
||||
kind: 'Status',
|
||||
apiVersion: 'v1',
|
||||
metadata: {},
|
||||
status: 'Failure',
|
||||
message: 'folder not found',
|
||||
code: 404,
|
||||
},
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
return HttpResponse.json({
|
||||
kind: 'Folder',
|
||||
apiVersion: 'folder.grafana.app/v1beta1',
|
||||
metadata: {
|
||||
name: response.item.uid,
|
||||
namespace,
|
||||
uid: response.item.uid,
|
||||
creationTimestamp: '2023-01-01T00:00:00Z',
|
||||
annotations: {
|
||||
// TODO: Generalise annotations in fixture data
|
||||
'grafana.app/createdBy': 'user:1',
|
||||
'grafana.app/updatedBy': 'user:2',
|
||||
'grafana.app/managedBy': 'user',
|
||||
'grafana.app/updatedTimestamp': '2024-01-01T00:00:00Z',
|
||||
'grafana.app/folder': response.item.kind === 'folder' ? response.item.parentUID : undefined,
|
||||
},
|
||||
labels: {
|
||||
'grafana.app/deprecatedInternalID': '123',
|
||||
},
|
||||
},
|
||||
spec: { title: response.item.title, description: '' },
|
||||
status: {},
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
const getFolderParentsHandler = () =>
|
||||
http.get<{ folderUid: string; namespace: string }>(
|
||||
'/apis/folder.grafana.app/v1beta1/namespaces/:namespace/folders/:folderUid/parents',
|
||||
({ params }) => {
|
||||
const { folderUid } = params;
|
||||
|
||||
const folder = mockTree.find(({ item }) => {
|
||||
return item.kind === 'folder' && item.uid === folderUid;
|
||||
});
|
||||
if (!folder || folder.item.kind !== 'folder') {
|
||||
return HttpResponse.json({
|
||||
kind: 'Status',
|
||||
apiVersion: 'v1',
|
||||
metadata: {},
|
||||
status: 'Failure',
|
||||
message: 'folder not found',
|
||||
code: 404,
|
||||
});
|
||||
}
|
||||
|
||||
const findParents = (parents: Array<(typeof mockTree)[number]>, folderUid?: string) => {
|
||||
if (!folderUid) {
|
||||
return parents;
|
||||
}
|
||||
|
||||
const parent = mockTree.find(({ item }) => {
|
||||
return item.kind === 'folder' && item.uid === folderUid;
|
||||
});
|
||||
|
||||
if (parent) {
|
||||
parents.push(parent);
|
||||
return findParents(parents, parent.item.kind === 'folder' ? parent.item.parentUID : undefined);
|
||||
}
|
||||
return parents;
|
||||
};
|
||||
|
||||
const parents = findParents([], folder?.item?.parentUID);
|
||||
|
||||
const mapped = parents.map((parent) => ({
|
||||
name: parent.item.uid,
|
||||
title: parent.item.title,
|
||||
parentUid: parent.item.kind === 'folder' ? parent.item.parentUID : undefined,
|
||||
}));
|
||||
|
||||
if (folder) {
|
||||
mapped.push({
|
||||
name: folder.item.uid,
|
||||
title: folder.item.title,
|
||||
parentUid: folder.item.parentUID,
|
||||
});
|
||||
}
|
||||
|
||||
return HttpResponse.json({
|
||||
kind: 'FolderInfoList',
|
||||
apiVersion: 'folder.grafana.app/v1beta1',
|
||||
metadata: {},
|
||||
items: mapped,
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
export default [getFolderHandler(), getFolderParentsHandler()];
|
||||
@@ -0,0 +1,29 @@
|
||||
import { HttpResponse, http } from 'msw';
|
||||
|
||||
const getDisplayMapping = () =>
|
||||
http.get<{ namespace: string }>('/apis/iam.grafana.app/v0alpha1/namespaces/:namespace/display', ({ request }) => {
|
||||
const url = new URL(request.url);
|
||||
const keys = url.searchParams.getAll('key');
|
||||
|
||||
// Turn query params such as `user:1` into mock mapping of `User 1` etc.
|
||||
const mockMappings = keys.map((key) => {
|
||||
const [_, id] = key.split(':');
|
||||
const displayName = `User ${id}`;
|
||||
return {
|
||||
identity: {
|
||||
type: 'user',
|
||||
name: `u00000000${id}`,
|
||||
},
|
||||
displayName,
|
||||
internalId: parseInt(id, 10),
|
||||
};
|
||||
});
|
||||
|
||||
return HttpResponse.json({
|
||||
metadata: {},
|
||||
keys,
|
||||
display: mockMappings,
|
||||
});
|
||||
});
|
||||
|
||||
export default [getDisplayMapping()];
|
||||
@@ -37,7 +37,7 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
||||
pickerTriggerRef = createRef<any>();
|
||||
|
||||
render() {
|
||||
const { theme, children, onChange, color, id } = this.props;
|
||||
const { theme, children, onChange, color } = this.props;
|
||||
const styles = getStyles(theme);
|
||||
const popoverElement = React.createElement(popover, {
|
||||
...{ ...this.props, children: null },
|
||||
@@ -67,7 +67,6 @@ export const colorPickerFactory = <T extends ColorPickerProps>(
|
||||
})
|
||||
) : (
|
||||
<ColorSwatch
|
||||
id={id}
|
||||
ref={this.pickerTriggerRef}
|
||||
onClick={showPopper}
|
||||
onMouseLeave={hidePopper}
|
||||
|
||||
@@ -22,7 +22,6 @@ export interface ColorPickerProps extends Themeable2 {
|
||||
color: string;
|
||||
onChange: ColorPickerChangeHandler;
|
||||
enableNamedColors?: boolean;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export interface Props<T> extends ColorPickerProps, PopoverContentProps {
|
||||
|
||||
@@ -66,6 +66,31 @@ export const Basic: Story = {
|
||||
},
|
||||
};
|
||||
|
||||
export const WithInfoOption: Story = {
|
||||
name: 'With infoOption',
|
||||
args: {
|
||||
...commonArgs,
|
||||
options: [
|
||||
...commonArgs.options,
|
||||
{ label: 'Can’t find your country? Select “Other” or contact an admin', value: '__INFO__', infoOption: true },
|
||||
],
|
||||
},
|
||||
render: (args) => {
|
||||
const [{ value }, setArgs] = useArgs();
|
||||
|
||||
return (
|
||||
<MultiCombobox
|
||||
{...args}
|
||||
value={value}
|
||||
onChange={(val) => {
|
||||
onChangeAction(val);
|
||||
setArgs({ value: val });
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
};
|
||||
|
||||
export const AutoSize: Story = {
|
||||
args: { ...commonArgs, width: 'auto', minWidth: 20 },
|
||||
render: (args) => {
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useFieldDisplayNames, useSelectOptions, frameHasName } from './utils';
|
||||
type Props = StandardEditorProps<string, FieldNamePickerConfigSettings>;
|
||||
|
||||
// Pick a field name out of the fields
|
||||
export const FieldNamePicker = ({ value, onChange, context, item, id }: Props) => {
|
||||
export const FieldNamePicker = ({ value, onChange, context, item }: Props) => {
|
||||
const settings: FieldNamePickerConfigSettings = item.settings ?? {};
|
||||
const names = useFieldDisplayNames(context.data, settings?.filter);
|
||||
const selectOptions = useSelectOptions(names, value, undefined, undefined, settings.baseNameMode);
|
||||
@@ -29,7 +29,6 @@ export const FieldNamePicker = ({ value, onChange, context, item, id }: Props) =
|
||||
return (
|
||||
<>
|
||||
<Select
|
||||
inputId={id}
|
||||
value={selectedOption}
|
||||
placeholder={
|
||||
settings.placeholderText ?? t('grafana-ui.matchers-ui.field-name-picker.placeholder', 'Select field')
|
||||
|
||||
@@ -41,11 +41,10 @@ export interface Props {
|
||||
data: DataFrame[];
|
||||
onChange: (value: string) => void;
|
||||
placeholder?: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
// Not exported globally... but used in grafana core
|
||||
export function RefIDPicker({ value, data, onChange, placeholder, id }: Props) {
|
||||
export function RefIDPicker({ value, data, onChange, placeholder }: Props) {
|
||||
const listOfRefIds = useMemo(() => getListOfQueryRefIds(data), [data]);
|
||||
|
||||
const [priorSelectionState, updatePriorSelectionState] = useState<{
|
||||
@@ -78,7 +77,6 @@ export function RefIDPicker({ value, data, onChange, placeholder, id }: Props) {
|
||||
}
|
||||
return (
|
||||
<Select
|
||||
inputId={id}
|
||||
options={listOfRefIds}
|
||||
onChange={onFilterChange}
|
||||
isClearable={true}
|
||||
@@ -116,10 +114,9 @@ export interface MultiProps {
|
||||
data: DataFrame[];
|
||||
onChange: (value: string[]) => void;
|
||||
placeholder?: string;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
export function RefIDMultiPicker({ value, data, onChange, placeholder, id }: MultiProps) {
|
||||
export function RefIDMultiPicker({ value, data, onChange, placeholder }: MultiProps) {
|
||||
const listOfRefIds = useMemo(() => getListOfQueryRefIds(data), [data]);
|
||||
|
||||
const [priorSelectionState, updatePriorSelectionState] = useState<{
|
||||
@@ -175,7 +172,6 @@ export function RefIDMultiPicker({ value, data, onChange, placeholder, id }: Mul
|
||||
}
|
||||
return (
|
||||
<MultiSelect
|
||||
inputId={id}
|
||||
options={listOfRefIds}
|
||||
onChange={onFilterChange}
|
||||
isClearable={true}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { formattedValueToString } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { AutoCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export function AutoCell({ value, field, rowIdx }: AutoCellProps) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { ThresholdsConfig, ThresholdsMode, VizOrientation, getFieldConfigWithMin
|
||||
import { BarGaugeDisplayMode, BarGaugeValueMode, TableCellDisplayMode } from '@grafana/schema';
|
||||
|
||||
import { BarGauge } from '../../../BarGauge/BarGauge';
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { TABLE } from '../constants';
|
||||
import { BarGaugeCellProps } from '../types';
|
||||
import { getCellOptions, getAlignmentFactor } from '../utils';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { css } from '@emotion/css';
|
||||
|
||||
import { TableCellDisplayMode } from '../../types';
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { ImageCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export const ImageCell = ({ cellOptions, field, value, rowIdx }: ImageCellProps) => {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { css } from '@emotion/css';
|
||||
|
||||
import { renderMarkdown } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from '../MaybeWrapWithLink';
|
||||
import { MaybeWrapWithLink } from '../components/MaybeWrapWithLink';
|
||||
import { MarkdownCellProps, TableCellStyles } from '../types';
|
||||
|
||||
export function MarkdownCell({ field, rowIdx, disableSanitizeHtml }: MarkdownCellProps) {
|
||||
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
DataGridHandle,
|
||||
DataGridProps,
|
||||
RenderCellProps,
|
||||
Renderers,
|
||||
RenderRowProps,
|
||||
Row,
|
||||
SortColumn,
|
||||
@@ -42,6 +43,7 @@ import { TableCellTooltip } from './components/TableCellTooltip';
|
||||
import { COLUMN, TABLE } from './constants';
|
||||
import {
|
||||
useColumnResize,
|
||||
useColWidths,
|
||||
useFilteredRows,
|
||||
useFooterCalcs,
|
||||
useHeaderHeight,
|
||||
@@ -51,6 +53,7 @@ import {
|
||||
useSortedRows,
|
||||
} from './hooks';
|
||||
import {
|
||||
getCellActionStyles,
|
||||
getDefaultCellStyles,
|
||||
getFooterStyles,
|
||||
getGridStyles,
|
||||
@@ -58,11 +61,19 @@ import {
|
||||
getLinkStyles,
|
||||
getTooltipStyles,
|
||||
} from './styles';
|
||||
import { TableNGProps, TableRow, TableSummaryRow, TableColumn, InspectCellProps, TableCellStyleOptions } from './types';
|
||||
import {
|
||||
TableNGProps,
|
||||
TableRow,
|
||||
TableSummaryRow,
|
||||
TableColumn,
|
||||
InspectCellProps,
|
||||
TableCellStyleOptions,
|
||||
FromFieldsResult,
|
||||
CellRootRenderer,
|
||||
} from './types';
|
||||
import {
|
||||
applySort,
|
||||
canFieldBeColorized,
|
||||
computeColWidths,
|
||||
createTypographyContext,
|
||||
displayJsonValue,
|
||||
extractPixelValue,
|
||||
@@ -84,7 +95,7 @@ import {
|
||||
withDataLinksActionsTooltip,
|
||||
} from './utils';
|
||||
|
||||
type CellRootRenderer = (key: React.Key, props: CellRendererProps<TableRow, TableSummaryRow>) => React.ReactNode;
|
||||
const EXPANDED_COLUMN_KEY = 'expanded';
|
||||
|
||||
export function TableNG(props: TableNGProps) {
|
||||
const {
|
||||
@@ -148,6 +159,7 @@ export function TableNG(props: TableNGProps) {
|
||||
} = useSortedRows(filteredRows, data.fields, { hasNestedFrames, initialSortBy });
|
||||
|
||||
const [inspectCell, setInspectCell] = useState<InspectCellProps | null>(null);
|
||||
const [tooltipState, setTooltipState] = useState<DataLinksActionsTooltipState>();
|
||||
const [expandedRows, setExpandedRows] = useState(() => new Set<number>());
|
||||
|
||||
// vt scrollbar accounting for column auto-sizing
|
||||
@@ -171,20 +183,9 @@ export function TableNG(props: TableNGProps) {
|
||||
),
|
||||
[theme]
|
||||
);
|
||||
const widths = useMemo(() => computeColWidths(visibleFields, availableWidth), [visibleFields, availableWidth]);
|
||||
const numColsFullyInView = useMemo(
|
||||
() =>
|
||||
widths.reduce(
|
||||
([count, remainingWidth], nextWidth) => {
|
||||
if (remainingWidth - nextWidth >= 0) {
|
||||
return [count + 1, remainingWidth - nextWidth];
|
||||
}
|
||||
return [count, 0];
|
||||
},
|
||||
[0, availableWidth]
|
||||
)[0],
|
||||
[widths, availableWidth]
|
||||
);
|
||||
|
||||
const [widths, numFrozenColsFullyInView] = useColWidths(visibleFields, availableWidth, frozenColumns);
|
||||
|
||||
const headerHeight = useHeaderHeight({
|
||||
columnWidths: widths,
|
||||
fields: visibleFields,
|
||||
@@ -270,15 +271,84 @@ export function TableNG(props: TableNGProps) {
|
||||
[enableVirtualization, resizeHandler, sortColumns, rowHeight, hasFooter, setSortColumns, onSortByChange]
|
||||
);
|
||||
|
||||
interface Schema {
|
||||
columns: TableColumn[];
|
||||
cellRootRenderers: Record<string, CellRootRenderer>;
|
||||
colsWithTooltip: Record<string, boolean>;
|
||||
}
|
||||
const buildNestedTableExpanderColumn = useCallback(
|
||||
(
|
||||
nestedColumns: TableColumn[],
|
||||
hasNestedHeaders: boolean,
|
||||
renderers: Renderers<TableRow, TableSummaryRow>
|
||||
): TableColumn => ({
|
||||
key: EXPANDED_COLUMN_KEY,
|
||||
name: '',
|
||||
field: {
|
||||
name: '',
|
||||
type: FieldType.other,
|
||||
config: {},
|
||||
values: [],
|
||||
},
|
||||
cellClass(row) {
|
||||
if (row.__depth !== 0) {
|
||||
return styles.cellNested;
|
||||
}
|
||||
return;
|
||||
},
|
||||
colSpan(args) {
|
||||
return args.type === 'ROW' && args.row.__depth === 1 ? data.fields.length : 1;
|
||||
},
|
||||
renderCell: ({ row }) => {
|
||||
if (row.__depth === 0) {
|
||||
const rowIdx = row.__index;
|
||||
|
||||
const { columns, cellRootRenderers, colsWithTooltip } = useMemo(() => {
|
||||
const fromFields = (f: Field[], widths: number[]) => {
|
||||
const result: Schema = {
|
||||
return (
|
||||
<RowExpander
|
||||
isExpanded={expandedRows.has(rowIdx)}
|
||||
onCellExpand={() => {
|
||||
if (expandedRows.has(rowIdx)) {
|
||||
expandedRows.delete(rowIdx);
|
||||
} else {
|
||||
expandedRows.add(rowIdx);
|
||||
}
|
||||
setExpandedRows(new Set(expandedRows));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Type guard to check if data exists as it's optional
|
||||
const nestedData = row.data;
|
||||
if (!nestedData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const expandedRecords = applySort(frameToRecords(nestedData), nestedData.fields, sortColumns);
|
||||
if (!expandedRecords.length) {
|
||||
return (
|
||||
<div className={styles.noDataNested}>
|
||||
<Trans i18nKey="grafana-ui.table.nested-table.no-data">No data</Trans>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DataGrid<TableRow, TableSummaryRow>
|
||||
{...commonDataGridProps}
|
||||
className={clsx(styles.grid, styles.gridNested)}
|
||||
headerRowClass={clsx(styles.headerRow, { [styles.displayNone]: !hasNestedHeaders })}
|
||||
headerRowHeight={hasNestedHeaders ? TABLE.HEADER_HEIGHT : 0}
|
||||
columns={nestedColumns}
|
||||
rows={expandedRecords}
|
||||
renderers={renderers}
|
||||
/>
|
||||
);
|
||||
},
|
||||
width: COLUMN.EXPANDER_WIDTH,
|
||||
minWidth: COLUMN.EXPANDER_WIDTH,
|
||||
}),
|
||||
[commonDataGridProps, data.fields.length, expandedRows, sortColumns, styles]
|
||||
);
|
||||
|
||||
const fromFields = useCallback(
|
||||
(f: Field[], widths: number[]): FromFieldsResult => {
|
||||
const result: FromFieldsResult = {
|
||||
columns: [],
|
||||
cellRootRenderers: {},
|
||||
colsWithTooltip: {},
|
||||
@@ -334,11 +404,7 @@ export function TableNG(props: TableNGProps) {
|
||||
|
||||
// helps us avoid string cx and emotion per-cell
|
||||
const cellActionClassName = showActions
|
||||
? clsx(
|
||||
'table-cell-actions',
|
||||
styles.cellActions,
|
||||
justifyContent === 'flex-end' ? styles.cellActionsEnd : styles.cellActionsStart
|
||||
)
|
||||
? clsx('table-cell-actions', getCellActionStyles(theme, textAlign))
|
||||
: undefined;
|
||||
|
||||
const shouldOverflow = rowHeight !== 'auto' && shouldTextOverflow(field);
|
||||
@@ -509,13 +575,13 @@ export function TableNG(props: TableNGProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const column: TableColumn = {
|
||||
result.columns.push({
|
||||
field,
|
||||
key: displayName,
|
||||
name: displayName,
|
||||
width,
|
||||
headerCellClass,
|
||||
frozen: Math.min(frozenColumns, numColsFullyInView) > i,
|
||||
frozen: Math.min(frozenColumns, numFrozenColsFullyInView) > i,
|
||||
renderCell: renderCellContent,
|
||||
renderHeaderCell: ({ column, sortDirection }) => (
|
||||
<HeaderCell
|
||||
@@ -543,136 +609,78 @@ export function TableNG(props: TableNGProps) {
|
||||
}
|
||||
return <div className={footerStyles.footerCell}>{footerCalcs[i]}</div>;
|
||||
},
|
||||
};
|
||||
|
||||
result.columns.push(column);
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
},
|
||||
[
|
||||
applyToRowBgFn,
|
||||
crossFilterOrder,
|
||||
crossFilterRows,
|
||||
data,
|
||||
disableSanitizeHtml,
|
||||
filter,
|
||||
footerCalcs,
|
||||
frozenColumns,
|
||||
getCellActions,
|
||||
isCountRowsSet,
|
||||
numFrozenColsFullyInView,
|
||||
onCellFilterAdded,
|
||||
rowHeight,
|
||||
rowHeightFn,
|
||||
rows,
|
||||
setFilter,
|
||||
showTypeIcons,
|
||||
theme,
|
||||
timeRange,
|
||||
]
|
||||
);
|
||||
|
||||
// set up the first row's nested data and the nest field widths using useColWidths to avoid
|
||||
// unnecessary re-renders on re-size.
|
||||
const firstRowNestedData = useMemo(
|
||||
() => (hasNestedFrames ? rows.find((r) => r.data)?.data : undefined),
|
||||
[hasNestedFrames, rows]
|
||||
);
|
||||
const [nestedFieldWidths] = useColWidths(firstRowNestedData?.fields ?? [], availableWidth);
|
||||
|
||||
const { columns, cellRootRenderers, colsWithTooltip } = useMemo(() => {
|
||||
const result = fromFields(visibleFields, widths);
|
||||
|
||||
// handle nested frames rendering from here.
|
||||
if (!hasNestedFrames) {
|
||||
// if nested frames are present, augment the columns to include the nested table expander column.
|
||||
if (!firstRowNestedData) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// pre-calculate renderRow and expandedColumns based on the first nested frame's fields.
|
||||
const firstNestedData = rows.find((r) => r.data)?.data;
|
||||
if (!firstNestedData) {
|
||||
return result;
|
||||
}
|
||||
|
||||
const hasNestedHeaders = firstNestedData.meta?.custom?.noHeader !== true;
|
||||
const renderRow = renderRowFactory(firstNestedData.fields, panelContext, expandedRows, enableSharedCrosshair);
|
||||
const hasNestedHeaders = firstRowNestedData.meta?.custom?.noHeader !== true;
|
||||
const renderRow = renderRowFactory(firstRowNestedData.fields, panelContext, expandedRows, enableSharedCrosshair);
|
||||
const { columns: nestedColumns, cellRootRenderers: nestedCellRootRenderers } = fromFields(
|
||||
firstNestedData.fields,
|
||||
computeColWidths(firstNestedData.fields, availableWidth)
|
||||
firstRowNestedData.fields,
|
||||
nestedFieldWidths
|
||||
);
|
||||
|
||||
const renderCellRoot: CellRootRenderer = (key, props) => nestedCellRootRenderers[props.column.key](key, props);
|
||||
|
||||
result.cellRootRenderers.expanded = (key, props) => <Cell key={key} {...props} />;
|
||||
const expanderCellRenderer: CellRootRenderer = (key, props) => <Cell key={key} {...props} />;
|
||||
result.cellRootRenderers[EXPANDED_COLUMN_KEY] = expanderCellRenderer;
|
||||
|
||||
// If we have nested frames, we need to add a column for the row expansion
|
||||
result.columns.unshift({
|
||||
key: 'expanded',
|
||||
name: '',
|
||||
field: {
|
||||
name: '',
|
||||
type: FieldType.other,
|
||||
config: {},
|
||||
values: [],
|
||||
},
|
||||
cellClass(row) {
|
||||
if (row.__depth !== 0) {
|
||||
return styles.cellNested;
|
||||
}
|
||||
return;
|
||||
},
|
||||
colSpan(args) {
|
||||
return args.type === 'ROW' && args.row.__depth === 1 ? data.fields.length : 1;
|
||||
},
|
||||
renderCell: ({ row }) => {
|
||||
if (row.__depth === 0) {
|
||||
const rowIdx = row.__index;
|
||||
|
||||
return (
|
||||
<RowExpander
|
||||
isExpanded={expandedRows.has(rowIdx)}
|
||||
onCellExpand={() => {
|
||||
if (expandedRows.has(rowIdx)) {
|
||||
expandedRows.delete(rowIdx);
|
||||
} else {
|
||||
expandedRows.add(rowIdx);
|
||||
}
|
||||
setExpandedRows(new Set(expandedRows));
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
// Type guard to check if data exists as it's optional
|
||||
const nestedData = row.data;
|
||||
if (!nestedData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const expandedRecords = applySort(frameToRecords(nestedData), nestedData.fields, sortColumns);
|
||||
if (!expandedRecords.length) {
|
||||
return (
|
||||
<div className={styles.noDataNested}>
|
||||
<Trans i18nKey="grafana-ui.table.nested-table.no-data">No data</Trans>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<DataGrid<TableRow, TableSummaryRow>
|
||||
{...commonDataGridProps}
|
||||
className={clsx(styles.grid, styles.gridNested)}
|
||||
headerRowClass={clsx(styles.headerRow, { [styles.displayNone]: !hasNestedHeaders })}
|
||||
headerRowHeight={hasNestedHeaders ? TABLE.HEADER_HEIGHT : 0}
|
||||
columns={nestedColumns}
|
||||
rows={expandedRecords}
|
||||
renderers={{ renderRow, renderCell: renderCellRoot }}
|
||||
/>
|
||||
);
|
||||
},
|
||||
width: COLUMN.EXPANDER_WIDTH,
|
||||
minWidth: COLUMN.EXPANDER_WIDTH,
|
||||
});
|
||||
result.columns.unshift(
|
||||
buildNestedTableExpanderColumn(nestedColumns, hasNestedHeaders, {
|
||||
renderRow,
|
||||
renderCell: (key, props) => nestedCellRootRenderers[props.column.key](key, props),
|
||||
})
|
||||
);
|
||||
|
||||
return result;
|
||||
}, [
|
||||
applyToRowBgFn,
|
||||
availableWidth,
|
||||
commonDataGridProps,
|
||||
crossFilterOrder,
|
||||
crossFilterRows,
|
||||
data,
|
||||
disableSanitizeHtml,
|
||||
buildNestedTableExpanderColumn,
|
||||
enableSharedCrosshair,
|
||||
expandedRows,
|
||||
filter,
|
||||
footerCalcs,
|
||||
frozenColumns,
|
||||
getCellActions,
|
||||
hasNestedFrames,
|
||||
isCountRowsSet,
|
||||
numColsFullyInView,
|
||||
onCellFilterAdded,
|
||||
firstRowNestedData,
|
||||
fromFields,
|
||||
nestedFieldWidths,
|
||||
panelContext,
|
||||
rowHeight,
|
||||
rowHeightFn,
|
||||
rows,
|
||||
setFilter,
|
||||
showTypeIcons,
|
||||
sortColumns,
|
||||
styles,
|
||||
timeRange,
|
||||
theme,
|
||||
visibleFields,
|
||||
widths,
|
||||
]);
|
||||
@@ -680,18 +688,16 @@ export function TableNG(props: TableNGProps) {
|
||||
// invalidate columns on every structureRev change. this supports width editing in the fieldConfig.
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
const structureRevColumns = useMemo(() => columns, [columns, structureRev]);
|
||||
const renderCellRoot: CellRootRenderer = useCallback(
|
||||
(key, props) => cellRootRenderers[props.column.key](key, props),
|
||||
[cellRootRenderers]
|
||||
);
|
||||
|
||||
// we need to have variables with these exact names for the localization to work properly
|
||||
const itemsRangeStart = pageRangeStart;
|
||||
const displayedEnd = pageRangeEnd;
|
||||
const numRows = sortedRows.length;
|
||||
|
||||
const renderCellRoot: CellRootRenderer = (key, props) => {
|
||||
return cellRootRenderers[props.column.key](key, props);
|
||||
};
|
||||
|
||||
const [tooltipState, setTooltipState] = useState<DataLinksActionsTooltipState>();
|
||||
|
||||
return (
|
||||
<>
|
||||
<DataGrid<TableRow, TableSummaryRow>
|
||||
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
import { render, screen } from '@testing-library/react';
|
||||
|
||||
import { ActionType, Field, FieldType, HttpRequestMethod } from '@grafana/data';
|
||||
|
||||
import { MaybeWrapWithLink } from './MaybeWrapWithLink';
|
||||
|
||||
describe('MaybeWrapWithLink', () => {
|
||||
describe('single link', () => {
|
||||
it('renders children as a link when there is a single link', () => {
|
||||
const link = { title: 'My link', url: 'http://example.com' };
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => [{ title: link.title, href: link.url, target: '_blank', origin: field }]),
|
||||
config: {
|
||||
links: [link],
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
const linkElement = screen.getByTitle(link.title);
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement).toHaveAttribute('href', link.url);
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('does not throw if getLinks unexpectedly returns nothing when a single link is present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [{ title: 'My link', url: 'http://example.com' }],
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const childElement = screen.getByText('Test Link');
|
||||
expect(childElement).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('multi link and/or actions', () => {
|
||||
it('renders a popup target link if multiple links are present', () => {
|
||||
const links = [
|
||||
{ title: 'My link', url: 'http://example.com' },
|
||||
{ title: 'Another link', url: 'http://example.com' },
|
||||
];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => links.map((l) => ({ title: l.title, href: l.url, target: '_blank', origin: field }))),
|
||||
config: {
|
||||
links,
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if multiple actions are present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [],
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'Another action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.POST, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if a single action is present', () => {
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links: [],
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
|
||||
it('renders a popup target link if a mixture of actions and links are present', () => {
|
||||
const links = [{ title: 'My link', url: 'http://example.com' }];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => links.map((l) => ({ title: l.title, href: l.url, target: '_blank', origin: field }))),
|
||||
config: {
|
||||
links,
|
||||
actions: [
|
||||
{
|
||||
type: ActionType.Fetch,
|
||||
title: 'My action',
|
||||
[ActionType.Fetch]: { method: HttpRequestMethod.GET, url: 'http://example.com' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const linkElement = screen.getByTitle('view data links and actions');
|
||||
expect(linkElement).toBeInTheDocument();
|
||||
expect(linkElement.tagName).toBe('A');
|
||||
expect(linkElement).toHaveAttribute('aria-haspopup', 'menu');
|
||||
expect(linkElement).toHaveTextContent('Test Link');
|
||||
});
|
||||
});
|
||||
|
||||
describe('no links or actions', () => {
|
||||
it('passes the children through when no links or actions are present', () => {
|
||||
const links = [
|
||||
{ title: 'My link', url: 'http://example.com' },
|
||||
{ title: 'Another link', url: 'http://example.com' },
|
||||
];
|
||||
const field: Field = {
|
||||
type: FieldType.string,
|
||||
name: 'Test Field',
|
||||
values: [],
|
||||
getLinks: jest.fn(() => []),
|
||||
config: {
|
||||
links,
|
||||
actions: [],
|
||||
},
|
||||
};
|
||||
const rowIdx = 0;
|
||||
const children = <span>Test Link</span>;
|
||||
|
||||
render(<MaybeWrapWithLink field={field} rowIdx={rowIdx} children={children} />);
|
||||
|
||||
const childElement = screen.getByText('Test Link');
|
||||
expect(childElement).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
});
|
||||
+9
-5
@@ -1,10 +1,10 @@
|
||||
import { memo, ReactNode } from 'react';
|
||||
|
||||
import { Field } from '@grafana/data';
|
||||
import { t } from '@grafana/i18n';
|
||||
|
||||
import { renderSingleLink } from '../DataLinksActionsTooltip';
|
||||
|
||||
import { getCellLinks } from './utils';
|
||||
import { renderSingleLink } from '../../DataLinksActionsTooltip';
|
||||
import { getCellLinks } from '../utils';
|
||||
|
||||
interface MaybeWrapWithLinkProps {
|
||||
field: Field;
|
||||
@@ -23,8 +23,12 @@ export const MaybeWrapWithLink = memo(({ field, rowIdx, children }: MaybeWrapWit
|
||||
}
|
||||
// as faux link that acts as hit-area for tooltip activation
|
||||
else if (linksCount + actionsCount > 0) {
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
return <a aria-haspopup="menu">{children}</a>;
|
||||
return (
|
||||
// eslint-disable-next-line jsx-a11y/anchor-is-valid
|
||||
<a title={t('table.link-wrapper.menu', 'view data links and actions')} aria-haspopup="menu">
|
||||
{children}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
// raw value
|
||||
@@ -477,7 +477,7 @@ describe('TableNG hooks', () => {
|
||||
}),
|
||||
columnWidths: [100, 100, 100],
|
||||
enabled: true,
|
||||
typographyCtx: { ...typographyCtx, avgCharWidth: 5, measureHeight: jest.fn(() => 38) },
|
||||
typographyCtx: { ...typographyCtx, avgCharWidth: 5, measureHeight: jest.fn(() => 44) },
|
||||
sortColumns: [],
|
||||
});
|
||||
});
|
||||
@@ -518,7 +518,7 @@ describe('TableNG hooks', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(heightFn).toHaveBeenCalledWith('Longer name that needs wrapping', 86, modifiedFields[0], -1, 6);
|
||||
expect(heightFn).toHaveBeenCalledWith('Longer name that needs wrapping', 86, modifiedFields[0], -1, 22);
|
||||
|
||||
modifiedFields = fields.map((field) => {
|
||||
if (field.name === 'name') {
|
||||
@@ -549,7 +549,21 @@ describe('TableNG hooks', () => {
|
||||
});
|
||||
});
|
||||
|
||||
expect(heightFn).toHaveBeenCalledWith('Longer name that needs wrapping', 26, modifiedFields[0], -1, 6);
|
||||
expect(heightFn).toHaveBeenCalledWith('Longer name that needs wrapping', 26, modifiedFields[0], -1, 22);
|
||||
});
|
||||
|
||||
it('does not throw if a field has been deleted but the colWidth has not yet been updated', () => {
|
||||
const { fields } = setupData();
|
||||
const { result } = renderHook(() => {
|
||||
return useHeaderHeight({
|
||||
fields,
|
||||
columnWidths: [100, 100, 100, 100],
|
||||
enabled: true,
|
||||
typographyCtx,
|
||||
sortColumns: [],
|
||||
});
|
||||
});
|
||||
expect(result.current).toBe(28);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
import { useState, useMemo, useCallback, useRef, useLayoutEffect, RefObject, CSSProperties } from 'react';
|
||||
import { useState, useMemo, useCallback, useRef, useLayoutEffect, RefObject, CSSProperties, useEffect } from 'react';
|
||||
import { Column, DataGridHandle, DataGridProps, SortColumn } from 'react-data-grid';
|
||||
|
||||
import { Field, fieldReducers, FieldType, formattedValueToString, reduceField } from '@grafana/data';
|
||||
import {
|
||||
compareArrayValues,
|
||||
Field,
|
||||
fieldReducers,
|
||||
FieldType,
|
||||
formattedValueToString,
|
||||
reduceField,
|
||||
} from '@grafana/data';
|
||||
|
||||
import { TableColumnResizeActionCallback } from '../types';
|
||||
|
||||
@@ -13,6 +20,7 @@ import {
|
||||
applySort,
|
||||
getColumnTypes,
|
||||
getRowHeight,
|
||||
computeColWidths,
|
||||
buildHeaderHeightMeasurers,
|
||||
buildCellHeightMeasurers,
|
||||
} from './utils';
|
||||
@@ -183,16 +191,17 @@ export function usePaginatedRows(
|
||||
return rows.slice(0, 100).reduce((avg, row, _, { length }) => avg + rowHeight(row) / length, 0);
|
||||
}, [rows, rowHeight, enabled]);
|
||||
|
||||
const smallPagination = useMemo(() => enabled && width < TABLE.PAGINATION_LIMIT, [enabled, width]);
|
||||
|
||||
// using dimensions of the panel, calculate pagination parameters
|
||||
const { numPages, rowsPerPage, pageRangeStart, pageRangeEnd, smallPagination } = useMemo((): {
|
||||
const { numPages, rowsPerPage, pageRangeStart, pageRangeEnd } = useMemo((): {
|
||||
numPages: number;
|
||||
rowsPerPage: number;
|
||||
pageRangeStart: number;
|
||||
pageRangeEnd: number;
|
||||
smallPagination: boolean;
|
||||
} => {
|
||||
if (!enabled) {
|
||||
return { numPages: 0, rowsPerPage: 0, pageRangeStart: 1, pageRangeEnd: numRows, smallPagination: false };
|
||||
return { numPages: 0, rowsPerPage: 0, pageRangeStart: 1, pageRangeEnd: numRows };
|
||||
}
|
||||
|
||||
// calculate number of rowsPerPage based on height stack
|
||||
@@ -207,16 +216,15 @@ export function usePaginatedRows(
|
||||
if (pageRangeEnd > numRows) {
|
||||
pageRangeEnd = numRows;
|
||||
}
|
||||
const smallPagination = width < TABLE.PAGINATION_LIMIT;
|
||||
|
||||
const numPages = Math.ceil(numRows / rowsPerPage);
|
||||
return {
|
||||
numPages,
|
||||
rowsPerPage,
|
||||
pageRangeStart,
|
||||
pageRangeEnd,
|
||||
smallPagination,
|
||||
};
|
||||
}, [width, height, headerHeight, footerHeight, avgRowHeight, enabled, numRows, page]);
|
||||
}, [height, headerHeight, footerHeight, avgRowHeight, enabled, numRows, page]);
|
||||
|
||||
// safeguard against page overflow on panel resize or other factors
|
||||
useLayoutEffect(() => {
|
||||
@@ -345,13 +353,19 @@ export function useHeaderHeight({
|
||||
const columnAvailableWidths = useMemo(
|
||||
() =>
|
||||
columnWidths.map((c, idx) => {
|
||||
if (idx >= fields.length) {
|
||||
return 0; // no width available for this column yet
|
||||
}
|
||||
|
||||
let width = c - 2 * TABLE.CELL_PADDING - TABLE.BORDER_RIGHT;
|
||||
const field = fields[idx];
|
||||
|
||||
// filtering icon
|
||||
if (fields[idx]?.config?.custom?.filterable) {
|
||||
if (field.config?.custom?.filterable) {
|
||||
width -= perIconSpace;
|
||||
}
|
||||
// sorting icon
|
||||
if (sortColumns.some((col) => col.columnKey === getDisplayName(fields[idx]))) {
|
||||
if (sortColumns.some((col) => col.columnKey === getDisplayName(field))) {
|
||||
width -= perIconSpace;
|
||||
}
|
||||
// type icon
|
||||
@@ -368,7 +382,15 @@ export function useHeaderHeight({
|
||||
if (!enabled) {
|
||||
return 0;
|
||||
}
|
||||
return getRowHeight(fields, -1, columnAvailableWidths, TABLE.HEADER_HEIGHT, measurers, TABLE.CELL_PADDING);
|
||||
return getRowHeight(
|
||||
fields,
|
||||
-1,
|
||||
columnAvailableWidths,
|
||||
TABLE.HEADER_HEIGHT,
|
||||
measurers,
|
||||
TABLE.LINE_HEIGHT,
|
||||
TABLE.CELL_PADDING
|
||||
);
|
||||
}, [fields, enabled, columnAvailableWidths, measurers]);
|
||||
|
||||
return headerHeight;
|
||||
@@ -534,3 +556,45 @@ export function useScrollbarWidth(ref: RefObject<DataGridHandle>, height: number
|
||||
|
||||
return scrollbarWidth;
|
||||
}
|
||||
|
||||
const numIsEqual = (a: number, b: number) => a === b;
|
||||
|
||||
export function useColWidths(
|
||||
visibleFields: Field[],
|
||||
availableWidth: number,
|
||||
frozenColumns?: number
|
||||
): [number[], number] {
|
||||
const [widths, setWidths] = useState<number[]>(computeColWidths(visibleFields, availableWidth));
|
||||
|
||||
// only replace the widths array if something actually changed
|
||||
useEffect(() => {
|
||||
const newWidths = computeColWidths(visibleFields, availableWidth);
|
||||
if (!compareArrayValues(widths, newWidths, numIsEqual)) {
|
||||
setWidths(newWidths);
|
||||
}
|
||||
}, [availableWidth, widths, visibleFields]);
|
||||
|
||||
// this is to avoid buggy situations where all visible columns are frozen
|
||||
const numFrozenColsFullyInView = useMemo(() => {
|
||||
if (!frozenColumns || frozenColumns <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const fullyVisibleCols = widths.reduce(
|
||||
([count, remainingWidth], nextWidth) => {
|
||||
if (remainingWidth - nextWidth >= 0) {
|
||||
return [count + 1, remainingWidth - nextWidth];
|
||||
}
|
||||
return [count, 0];
|
||||
},
|
||||
[0, availableWidth]
|
||||
)[0];
|
||||
|
||||
// de-noise memoized changes to the columns array, and only change this
|
||||
// number when the number of frozen columns changes or once there are fewer
|
||||
// visible columns than the number of frozen columns.
|
||||
return Math.min(fullyVisibleCols, frozenColumns);
|
||||
}, [widths, availableWidth, frozenColumns]);
|
||||
|
||||
return [widths, numFrozenColsFullyInView];
|
||||
}
|
||||
|
||||
@@ -88,19 +88,6 @@ export const getGridStyles = (theme: GrafanaTheme2, enablePagination?: boolean,
|
||||
color: theme.colors.text.secondary,
|
||||
fontSize: theme.typography.h4.fontSize,
|
||||
}),
|
||||
cellActions: css({
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
margin: 'auto',
|
||||
height: '100%',
|
||||
color: theme.colors.text.primary,
|
||||
background: theme.isDark ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)',
|
||||
padding: theme.spacing.x0_5,
|
||||
paddingInlineStart: theme.spacing.x1,
|
||||
}),
|
||||
cellActionsEnd: css({ left: 0 }),
|
||||
cellActionsStart: css({ right: 0 }),
|
||||
headerRow: css({
|
||||
paddingBlockStart: 0,
|
||||
fontWeight: 'normal',
|
||||
@@ -158,6 +145,20 @@ export const getDefaultCellStyles: TableCellStyles = (theme, { textAlign, should
|
||||
},
|
||||
});
|
||||
|
||||
export const getCellActionStyles = (theme: GrafanaTheme2, textAlign: TextAlign) =>
|
||||
css({
|
||||
display: 'none',
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
margin: 'auto',
|
||||
height: '100%',
|
||||
color: theme.colors.text.primary,
|
||||
background: theme.isDark ? 'rgba(0, 0, 0, 0.7)' : 'rgba(255, 255, 255, 0.7)',
|
||||
padding: theme.spacing.x0_5,
|
||||
paddingInlineStart: theme.spacing.x1,
|
||||
[textAlign === 'right' ? 'left' : 'right']: 0,
|
||||
});
|
||||
|
||||
export const getLinkStyles = (theme: GrafanaTheme2, canBeColorized: boolean) =>
|
||||
css({
|
||||
a: {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FC, SyntheticEvent } from 'react';
|
||||
import { Column } from 'react-data-grid';
|
||||
import { CellRendererProps, Column } from 'react-data-grid';
|
||||
|
||||
import {
|
||||
DataFrame,
|
||||
@@ -306,3 +306,11 @@ export interface MeasureCellHeightEntry {
|
||||
*/
|
||||
fieldIdxs: number[];
|
||||
}
|
||||
|
||||
export type CellRootRenderer = (key: React.Key, props: CellRendererProps<TableRow, TableSummaryRow>) => React.ReactNode;
|
||||
|
||||
export interface FromFieldsResult {
|
||||
columns: TableColumn[];
|
||||
cellRootRenderers: Record<string, CellRootRenderer>;
|
||||
colsWithTooltip: Record<string, boolean>;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ export interface UnitPickerProps {
|
||||
onChange: (item?: string) => void;
|
||||
value?: string;
|
||||
width?: number;
|
||||
id?: string;
|
||||
}
|
||||
|
||||
function formatCreateLabel(input: string) {
|
||||
@@ -22,7 +21,7 @@ export class UnitPicker extends PureComponent<UnitPickerProps> {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { value, width, id } = this.props;
|
||||
const { value, width } = this.props;
|
||||
|
||||
// Set the current selection
|
||||
let current: SelectableValue<string> | undefined = undefined;
|
||||
@@ -57,7 +56,6 @@ export class UnitPicker extends PureComponent<UnitPickerProps> {
|
||||
|
||||
return (
|
||||
<Cascader
|
||||
id={id}
|
||||
width={width}
|
||||
initialValue={current && current.label}
|
||||
allowCustomValue
|
||||
|
||||
+2
-3
@@ -82,6 +82,5 @@ They can observe its output into the `public/api-merged.json` and `public/openap
|
||||
|
||||
Finally, they can browser and try out both the OpenAPI v2 and v3 via the Swagger UI editor (served by the grafana server) by navigating to `/swagger`.
|
||||
|
||||
If there are any issues generating the specifications (e.g., diff containing unrelated changes to your PR or unusually large diff), please run the following two commands to ensure your Swagger version is up to date, then re-run the make commands.
|
||||
- `go install github.com/bwplotka/bingo@latest`
|
||||
- `bingo get github.com/go-swagger/go-swagger/cmd/swagger@v0.30.2`
|
||||
If there are any issues generating the specifications (e.g., diff containing unrelated changes to your PR or unusually large diff), please run the following command to ensure your Swagger version is up to date, then re-run the make commands.
|
||||
- `go tool github.com/go-swagger/go-swagger/cmd/swagger@v0.30.6`
|
||||
|
||||
@@ -199,7 +199,6 @@ func Wire(d *dagger.Client, src *dagger.Directory, platform dagger.Platform, goV
|
||||
}).
|
||||
WithDirectory("/src/pkg", src.Directory("pkg")).
|
||||
WithDirectory("/src/apps", src.Directory("apps")).
|
||||
WithDirectory("/src/.bingo", src.Directory(".bingo")).
|
||||
WithDirectory("/src/.citools", src.Directory(".citools")).
|
||||
WithFile("/src/Makefile", src.File("Makefile")).
|
||||
WithWorkdir("/src").
|
||||
|
||||
@@ -31,7 +31,7 @@ type RepoGetter interface {
|
||||
// Given a repository configuration, return it as a repository instance
|
||||
// This will only error for un-recoverable system errors
|
||||
// the repository instance may or may not be valid/healthy
|
||||
AsRepository(ctx context.Context, cfg *provisioning.Repository) (repository.Repository, error)
|
||||
RepositoryFromConfig(ctx context.Context, r *provisioning.Repository) (repository.Repository, error)
|
||||
}
|
||||
|
||||
const loggerName = "provisioning-repository-controller"
|
||||
@@ -223,7 +223,7 @@ func (rc *RepositoryController) handleDelete(ctx context.Context, obj *provision
|
||||
|
||||
// Process any finalizers
|
||||
if len(obj.Finalizers) > 0 {
|
||||
repo, err := rc.repoGetter.AsRepository(ctx, obj)
|
||||
repo, err := rc.repoGetter.RepositoryFromConfig(ctx, obj)
|
||||
if err != nil {
|
||||
logger.Warn("unable to get repository for cleanup")
|
||||
} else {
|
||||
@@ -438,7 +438,7 @@ func (rc *RepositoryController) process(item *queueItem) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
repo, err := rc.repoGetter.AsRepository(ctx, obj)
|
||||
repo, err := rc.repoGetter.RepositoryFromConfig(ctx, obj)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to create repository from configuration: %w", err)
|
||||
}
|
||||
|
||||
@@ -3,13 +3,14 @@ package provisioning
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
|
||||
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/controller"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/jobs"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/provisioning/repository"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
"k8s.io/kube-openapi/pkg/spec3"
|
||||
)
|
||||
|
||||
type Extra interface {
|
||||
@@ -17,7 +18,7 @@ type Extra interface {
|
||||
UpdateStorage(storage map[string]rest.Storage) error
|
||||
PostProcessOpenAPI(oas *spec3.OpenAPI) error
|
||||
GetJobWorkers() []jobs.Worker
|
||||
AsRepository(ctx context.Context, r *provisioning.Repository) (repository.Repository, error)
|
||||
AsRepository(ctx context.Context, r *provisioning.Repository, secure repository.SecureValues) (repository.Repository, error)
|
||||
RepositoryTypes() []provisioning.RepositoryType
|
||||
Mutators() []controller.Mutator
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
type jobsConnector struct {
|
||||
repoGetter RepoGetter
|
||||
jobs jobs.Queue
|
||||
historic jobs.History
|
||||
historic jobs.HistoryReader
|
||||
}
|
||||
|
||||
func (*jobsConnector) New() runtime.Object {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user