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.", "103"],
|
||||
[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": [
|
||||
[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.", "20"],
|
||||
[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, "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.", "26"],
|
||||
[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.", "31"],
|
||||
[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.", "34"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "35"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "33"]
|
||||
],
|
||||
"public/app/plugins/datasource/prometheus/language_provider.test.ts:5381": [
|
||||
[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. |
|
||||
| `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`. |
|
||||
| `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. |
|
||||
| `User` | User name 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 { DataSourcePluginOptionsEditorProps, DataSourceSettings } from '@grafana/data';
|
||||
@ -16,6 +16,8 @@ export type Props = DataSourcePluginOptionsEditorProps<PromOptions>;
|
||||
export const ConfigEditor = (props: Props) => {
|
||||
const { options, onOptionsChange } = props;
|
||||
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 = {
|
||||
azureAuthSupported: config.azureAuthEnabled,
|
||||
@ -28,15 +30,15 @@ export const ConfigEditor = (props: Props) => {
|
||||
return (
|
||||
<>
|
||||
{options.access === 'direct' && (
|
||||
<Alert title="Deprecation Notice" severity="warning">
|
||||
Browser access mode in the Prometheus datasource is deprecated and will be removed in a future release.
|
||||
<Alert title="Error" severity="error">
|
||||
Browser access mode in the Prometheus datasource is no longer available. Switch to server access mode.
|
||||
</Alert>
|
||||
)}
|
||||
|
||||
<DataSourceHttpSettings
|
||||
defaultUrl="http://localhost:9090"
|
||||
dataSourceConfig={options}
|
||||
showAccessOptions={true}
|
||||
showAccessOptions={showAccessOptions.current}
|
||||
onChange={onOptionsChange}
|
||||
sigV4AuthToggleEnabled={config.sigV4AuthEnabled}
|
||||
azureAuthSettings={azureAuthSettings}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { cloneDeep } from 'lodash';
|
||||
import { of, throwError } from 'rxjs';
|
||||
import { lastValueFrom, of, throwError } from 'rxjs';
|
||||
|
||||
import {
|
||||
CoreApp,
|
||||
@ -100,6 +100,57 @@ describe('PrometheusDatasource', () => {
|
||||
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', () => {
|
||||
@ -683,7 +734,7 @@ const HOUR = 60 * MINUTE;
|
||||
|
||||
const time = ({ hours = 0, seconds = 0, minutes = 0 }) => dateTime(hours * HOUR + minutes * MINUTE + seconds * SECOND);
|
||||
|
||||
describe('PrometheusDatasource', () => {
|
||||
describe('PrometheusDatasource2', () => {
|
||||
const instanceSettings = {
|
||||
url: 'proxied',
|
||||
directUrl: 'direct',
|
||||
|
@ -22,6 +22,7 @@ import {
|
||||
TimeRange,
|
||||
DataFrame,
|
||||
dateTime,
|
||||
AnnotationQueryRequest,
|
||||
QueryFixAction,
|
||||
} from '@grafana/data';
|
||||
import {
|
||||
@ -161,6 +162,13 @@ export class PrometheusDatasource
|
||||
data: Record<string, string> | null,
|
||||
overrides: Partial<BackendSrvRequest> = {}
|
||||
): 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 || {};
|
||||
for (const [key, value] of this.customQueryParameters) {
|
||||
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 { 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;
|
||||
if (!frames || !frames.length) {
|
||||
return [];
|
||||
|
Loading…
Reference in New Issue
Block a user