mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Throw error on direct access (#50162)
* Disable direct access * Hide access select if Server mode is already selected * Update docs * Add more tests Co-authored-by: Beto Muniz <contato@betomuniz.com>
This commit is contained in:
parent
b5cb7738da
commit
f30795b088
@ -7857,7 +7857,10 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "102"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "102"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "103"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "103"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "104"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "104"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "105"]
|
[0, 0, 0, "Unexpected any. Specify a different type.", "105"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "106"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "107"],
|
||||||
|
[0, 0, 0, "Unexpected any. Specify a different type.", "108"]
|
||||||
],
|
],
|
||||||
"public/app/plugins/datasource/prometheus/datasource.tsx:5381": [
|
"public/app/plugins/datasource/prometheus/datasource.tsx:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
@ -7882,9 +7885,9 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "19"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "20"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "21"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
|
[0, 0, 0, "Do not use any type assertions.", "22"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
|
||||||
[0, 0, 0, "Do not use any type assertions.", "24"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "24"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "26"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "26"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "27"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "27"],
|
||||||
@ -7893,9 +7896,7 @@ exports[`better eslint`] = {
|
|||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "30"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "30"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "31"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "31"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "32"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "32"],
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "33"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "33"]
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "34"],
|
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "35"]
|
|
||||||
],
|
],
|
||||||
"public/app/plugins/datasource/prometheus/language_provider.test.ts:5381": [
|
"public/app/plugins/datasource/prometheus/language_provider.test.ts:5381": [
|
||||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||||
|
@ -26,7 +26,7 @@ To access Prometheus settings, hover your mouse over the **Configuration** (gear
|
|||||||
| `Name` | The data source name. This is how you refer to the data source in panels and queries. |
|
| `Name` | The data source name. This is how you refer to the data source in panels and queries. |
|
||||||
| `Default` | Default data source that is pre-selected for new panels. |
|
| `Default` | Default data source that is pre-selected for new panels. |
|
||||||
| `Url` | The URL of your Prometheus server, for example, `http://prometheus.example.org:9090`. |
|
| `Url` | The URL of your Prometheus server, for example, `http://prometheus.example.org:9090`. |
|
||||||
| `Access` | Server (default) = URL needs to be accessible from the Grafana backend/server, Browser = URL needs to be accessible from the browser. **Note**: Browser (direct) access is deprecated and will be removed in a future release. |
|
| `Access` | Only Server access mode is functional. If Server mode is already selected this option is hidden. Otherwise change to Server mode to prevent errors. |
|
||||||
| `Basic Auth` | Enable basic authentication to the Prometheus data source. |
|
| `Basic Auth` | Enable basic authentication to the Prometheus data source. |
|
||||||
| `User` | User name for basic authentication. |
|
| `User` | User name for basic authentication. |
|
||||||
| `Password` | Password for basic authentication. |
|
| `Password` | Password for basic authentication. |
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, { useRef } from 'react';
|
||||||
|
|
||||||
import { SIGV4ConnectionConfig } from '@grafana/aws-sdk';
|
import { SIGV4ConnectionConfig } from '@grafana/aws-sdk';
|
||||||
import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
|
import { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
|
||||||
@ -16,6 +16,8 @@ export type Props = DataSourcePluginOptionsEditorProps<PromOptions>;
|
|||||||
export const ConfigEditor = (props: Props) => {
|
export const ConfigEditor = (props: Props) => {
|
||||||
const { options, onOptionsChange } = props;
|
const { options, onOptionsChange } = props;
|
||||||
const alertmanagers = getAllAlertmanagerDataSources();
|
const alertmanagers = getAllAlertmanagerDataSources();
|
||||||
|
// use ref so this is evaluated only first time it renders and the select does not disappear suddenly.
|
||||||
|
const showAccessOptions = useRef(props.options.access === 'direct');
|
||||||
|
|
||||||
const azureAuthSettings = {
|
const azureAuthSettings = {
|
||||||
azureAuthSupported: config.azureAuthEnabled,
|
azureAuthSupported: config.azureAuthEnabled,
|
||||||
@ -28,15 +30,15 @@ export const ConfigEditor = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{options.access === 'direct' && (
|
{options.access === 'direct' && (
|
||||||
<Alert title="Deprecation Notice" severity="warning">
|
<Alert title="Error" severity="error">
|
||||||
Browser access mode in the Prometheus datasource is deprecated and will be removed in a future release.
|
Browser access mode in the Prometheus datasource is no longer available. Switch to server access mode.
|
||||||
</Alert>
|
</Alert>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<DataSourceHttpSettings
|
<DataSourceHttpSettings
|
||||||
defaultUrl="http://localhost:9090"
|
defaultUrl="http://localhost:9090"
|
||||||
dataSourceConfig={options}
|
dataSourceConfig={options}
|
||||||
showAccessOptions={true}
|
showAccessOptions={showAccessOptions.current}
|
||||||
onChange={onOptionsChange}
|
onChange={onOptionsChange}
|
||||||
sigV4AuthToggleEnabled={config.sigV4AuthEnabled}
|
sigV4AuthToggleEnabled={config.sigV4AuthEnabled}
|
||||||
azureAuthSettings={azureAuthSettings}
|
azureAuthSettings={azureAuthSettings}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { cloneDeep } from 'lodash';
|
import { cloneDeep } from 'lodash';
|
||||||
import { of, throwError } from 'rxjs';
|
import { lastValueFrom, of, throwError } from 'rxjs';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
CoreApp,
|
CoreApp,
|
||||||
@ -100,6 +100,57 @@ describe('PrometheusDatasource', () => {
|
|||||||
expect(response[0].state).toBe(LoadingState.Done);
|
expect(response[0].state).toBe(LoadingState.Done);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('throws if using direct access', async () => {
|
||||||
|
const instanceSettings = {
|
||||||
|
url: 'proxied',
|
||||||
|
directUrl: 'direct',
|
||||||
|
user: 'test',
|
||||||
|
password: 'mupp',
|
||||||
|
access: 'direct',
|
||||||
|
jsonData: {
|
||||||
|
customQueryParameters: '',
|
||||||
|
} as any,
|
||||||
|
} as unknown as DataSourceInstanceSettings<PromOptions>;
|
||||||
|
const range = { from: time({ seconds: 63 }), to: time({ seconds: 183 }) };
|
||||||
|
const directDs = new PrometheusDatasource(instanceSettings, templateSrvStub as any, timeSrvStub as any);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
lastValueFrom(directDs.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard })))
|
||||||
|
).rejects.toMatchObject({ message: expect.stringMatching('Browser access') });
|
||||||
|
|
||||||
|
// Cannot test because some other tests need "./metric_find_query" to be mocked and that prevents this to be
|
||||||
|
// tested. Checked manually that this ends up with throwing
|
||||||
|
// await expect(directDs.metricFindQuery('label_names(foo)')).rejects.toBeDefined();
|
||||||
|
|
||||||
|
jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||||
|
await expect(directDs.testDatasource()).resolves.toMatchObject({
|
||||||
|
message: expect.stringMatching('Browser access'),
|
||||||
|
status: 'error',
|
||||||
|
});
|
||||||
|
await expect(
|
||||||
|
directDs.annotationQuery({
|
||||||
|
range: { ...range, raw: range },
|
||||||
|
rangeRaw: range,
|
||||||
|
// Should be DataModel but cannot import that here from the main app. Needs to be moved to package first.
|
||||||
|
dashboard: {},
|
||||||
|
annotation: {
|
||||||
|
expr: 'metric',
|
||||||
|
name: 'test',
|
||||||
|
enable: true,
|
||||||
|
iconColor: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).rejects.toMatchObject({
|
||||||
|
message: expect.stringMatching('Browser access'),
|
||||||
|
});
|
||||||
|
await expect(directDs.getTagKeys()).rejects.toMatchObject({
|
||||||
|
message: expect.stringMatching('Browser access'),
|
||||||
|
});
|
||||||
|
await expect(directDs.getTagValues()).rejects.toMatchObject({
|
||||||
|
message: expect.stringMatching('Browser access'),
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Datasource metadata requests', () => {
|
describe('Datasource metadata requests', () => {
|
||||||
@ -683,7 +734,7 @@ const HOUR = 60 * MINUTE;
|
|||||||
|
|
||||||
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
||||||
|
|
||||||
describe('PrometheusDatasource', () => {
|
describe('PrometheusDatasource2', () => {
|
||||||
const instanceSettings = {
|
const instanceSettings = {
|
||||||
url: 'proxied',
|
url: 'proxied',
|
||||||
directUrl: 'direct',
|
directUrl: 'direct',
|
||||||
|
@ -22,6 +22,7 @@ import {
|
|||||||
TimeRange,
|
TimeRange,
|
||||||
DataFrame,
|
DataFrame,
|
||||||
dateTime,
|
dateTime,
|
||||||
|
AnnotationQueryRequest,
|
||||||
QueryFixAction,
|
QueryFixAction,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import {
|
import {
|
||||||
@ -161,6 +162,13 @@ export class PrometheusDatasource
|
|||||||
data: Record<string, string> | null,
|
data: Record<string, string> | null,
|
||||||
overrides: Partial<BackendSrvRequest> = {}
|
overrides: Partial<BackendSrvRequest> = {}
|
||||||
): Observable<FetchResponse<T>> {
|
): Observable<FetchResponse<T>> {
|
||||||
|
if (this.access === 'direct') {
|
||||||
|
const error = new Error(
|
||||||
|
'Browser access mode in the Prometheus datasource is no longer available. Switch to server access mode.'
|
||||||
|
);
|
||||||
|
return throwError(() => error);
|
||||||
|
}
|
||||||
|
|
||||||
data = data || {};
|
data = data || {};
|
||||||
for (const [key, value] of this.customQueryParameters) {
|
for (const [key, value] of this.customQueryParameters) {
|
||||||
if (data[key] == null) {
|
if (data[key] == null) {
|
||||||
@ -698,7 +706,14 @@ export class PrometheusDatasource
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
async annotationQuery(options: any): Promise<AnnotationEvent[]> {
|
async annotationQuery(options: AnnotationQueryRequest<PromQuery>): Promise<AnnotationEvent[]> {
|
||||||
|
if (this.access === 'direct') {
|
||||||
|
const error = new Error(
|
||||||
|
'Browser access mode in the Prometheus datasource is no longer available. Switch to server access mode.'
|
||||||
|
);
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
|
||||||
const annotation = options.annotation;
|
const annotation = options.annotation;
|
||||||
const { expr = '' } = annotation;
|
const { expr = '' } = annotation;
|
||||||
|
|
||||||
@ -738,7 +753,7 @@ export class PrometheusDatasource
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
processAnnotationResponse = (options: any, data: BackendDataSourceResponse) => {
|
processAnnotationResponse = (options: AnnotationQueryRequest<PromQuery>, data: BackendDataSourceResponse) => {
|
||||||
const frames: DataFrame[] = toDataQueryResponse({ data: data }).data;
|
const frames: DataFrame[] = toDataQueryResponse({ data: data }).data;
|
||||||
if (!frames || !frames.length) {
|
if (!frames || !frames.length) {
|
||||||
return [];
|
return [];
|
||||||
|
Loading…
Reference in New Issue
Block a user