From b1a839825fdb3a98f20145654d5474e1037188d2 Mon Sep 17 00:00:00 2001
From: Andres Martinez Gotor
Date: Tue, 15 Jun 2021 18:51:06 +0200
Subject: [PATCH] AzureMonitor: Remove support for different credentials for
Azure Monitor Logs (#35121)
---
.../__mocks__/instanceSettings.ts | 3 -
.../api/routes.ts | 15 -
.../azure_log_analytics_datasource.test.ts | 4 +-
.../azure_log_analytics_datasource.ts | 18 +-
.../components/AnalyticsConfig.test.tsx | 34 +-
.../components/AnalyticsConfig.tsx | 106 +-
.../components/AzureCredentialsForm.test.tsx | 24 +
.../components/AzureCredentialsForm.tsx | 88 +-
.../components/ConfigEditor.tsx | 6 +-
.../components/InsightsConfig.tsx | 7 +-
.../AnalyticsConfig.test.tsx.snap | 1096 ++++++-----------
.../InsightsConfig.test.tsx.snap | 36 +-
.../credentials.ts | 117 --
.../plugin.json | 86 +-
.../resourcePicker/resourcePickerData.ts | 4 +-
.../types/index.ts | 13 +-
16 files changed, 555 insertions(+), 1102 deletions(-)
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts
index 2832df6c9a6..6473078b17c 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/__mocks__/instanceSettings.ts
@@ -17,8 +17,5 @@ export const createMockInstanceSetttings = (): AzureDataSourceInstanceSettings =
tenantId: 'abc-123',
clientId: 'def-456',
subscriptionId: 'ghi-789',
-
- // logs
- azureLogAnalyticsSameAs: true,
},
});
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/api/routes.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/api/routes.ts
index ffd4bcb17aa..7a1cfa23c19 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/api/routes.ts
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/api/routes.ts
@@ -13,21 +13,6 @@ export function getManagementApiRoute(azureCloud: string): string {
}
}
-export function getLogAnalyticsManagementApiRoute(azureCloud: string): string {
- switch (azureCloud) {
- case 'azuremonitor':
- return 'workspacesloganalytics';
- case 'chinaazuremonitor':
- return 'chinaworkspacesloganalytics';
- case 'govazuremonitor':
- return 'govworkspacesloganalytics';
- case 'germanyazuremonitor':
- return 'germanyworkspacesloganalytics';
- default:
- throw new Error('The cloud not supported.');
- }
-}
-
export function getLogAnalyticsApiRoute(azureCloud: string): string {
switch (azureCloud) {
case 'azuremonitor':
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts
index 4636532c5df..11db877acd1 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.test.ts
@@ -33,7 +33,7 @@ describe('AzureLogAnalyticsDatasource', () => {
beforeEach(() => {
ctx.instanceSettings = {
- jsonData: { logAnalyticsSubscriptionId: 'xxx', azureLogAnalyticsSameAs: false },
+ jsonData: { subscriptionId: 'xxx' },
url: 'http://azureloganalyticsapi',
};
@@ -93,7 +93,7 @@ describe('AzureLogAnalyticsDatasource', () => {
it('should use the loganalyticsazure plugin route', async () => {
await ctx.ds.metricFindQuery('workspace("aworkspace").AzureActivity | distinct Category');
- expect(workspacesUrl).toContain('workspacesloganalytics');
+ expect(workspacesUrl).toContain('azuremonitor');
expect(azureLogAnalyticsUrl).toContain('loganalyticsazure');
});
});
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts
index 4d01fcdb2cf..bdf3140648f 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/azure_log_analytics/azure_log_analytics_datasource.ts
@@ -18,8 +18,8 @@ import {
import { getBackendSrv, getTemplateSrv, DataSourceWithBackend, FetchResponse } from '@grafana/runtime';
import { Observable, from } from 'rxjs';
import { mergeMap } from 'rxjs/operators';
-import { getAuthType, getAzureCloud, isLogAnalyticsSameAs } from '../credentials';
-import { getLogAnalyticsApiRoute, getLogAnalyticsManagementApiRoute } from '../api/routes';
+import { getAuthType, getAzureCloud } from '../credentials';
+import { getLogAnalyticsApiRoute, getManagementApiRoute } from '../api/routes';
import { AzureLogAnalyticsMetadata } from '../types/logAnalyticsMetadata';
import { isGUIDish } from '../components/ResourcePicker/utils';
@@ -51,17 +51,11 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
const logAnalyticsRoute = getLogAnalyticsApiRoute(cloud);
this.baseUrl = `/${logAnalyticsRoute}`;
- const managementRoute = getLogAnalyticsManagementApiRoute(cloud);
+ const managementRoute = getManagementApiRoute(cloud);
this.azureMonitorUrl = `/${managementRoute}/subscriptions`;
this.url = instanceSettings.url || '';
-
- const sameAsMonitor = isLogAnalyticsSameAs(instanceSettings);
-
- this.defaultSubscriptionId = sameAsMonitor
- ? instanceSettings.jsonData.subscriptionId
- : instanceSettings.jsonData.logAnalyticsSubscriptionId;
-
+ this.defaultSubscriptionId = this.instanceSettings.jsonData.subscriptionId || '';
this.defaultOrFirstWorkspace = this.instanceSettings.jsonData.logAnalyticsDefaultWorkspace || '';
}
@@ -485,14 +479,14 @@ export default class AzureLogAnalyticsDatasource extends DataSourceWithBackend<
const authType = getAuthType(this.instanceSettings);
if (authType === 'clientsecret') {
- if (!this.isValidConfigField(this.instanceSettings.jsonData.logAnalyticsTenantId)) {
+ if (!this.isValidConfigField(this.instanceSettings.jsonData.tenantId)) {
return {
status: 'error',
message: 'The Tenant Id field is required.',
};
}
- if (!this.isValidConfigField(this.instanceSettings.jsonData.logAnalyticsClientId)) {
+ if (!this.isValidConfigField(this.instanceSettings.jsonData.clientId)) {
return {
status: 'error',
message: 'The Client Id field is required.',
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.test.tsx
index 88edcf8bcfe..9c48ffde49f 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.test.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.test.tsx
@@ -22,18 +22,11 @@ const setup = (propsFunc?: (props: Props) => Props) => {
basicAuthPassword: '',
withCredentials: false,
isDefault: false,
- secureJsonFields: {
- logAnalyticsClientSecret: false,
- },
+ secureJsonFields: {},
jsonData: {
cloudName: '',
subscriptionId: '',
- azureLogAnalyticsSameAs: false,
logAnalyticsDefaultWorkspace: '',
- logAnalyticsTenantId: '',
- },
- secureJsonData: {
- logAnalyticsClientSecret: '',
},
version: 1,
readOnly: false,
@@ -80,10 +73,10 @@ describe('Render', () => {
...props.options.jsonData,
azureLogAnalyticsSameAs: false,
logAnalyticsDefaultWorkspace: '',
- logAnalyticsTenantId: 'e7f3f661-a933-4b3f-8176-51c4f982ec48',
- logAnalyticsClientId: '44693801-6ee6-49de-9b2d-9106972f9572',
- logAnalyticsSubscriptionId: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
- logAnalyticsClientSecret: 'cddcc020-2c94-460a-a3d0-df3147ffa792',
+ tenantId: 'e7f3f661-a933-4b3f-8176-51c4f982ec48',
+ clientId: '44693801-6ee6-49de-9b2d-9106972f9572',
+ subscriptionId: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
+ clientSecret: 'cddcc020-2c94-460a-a3d0-df3147ffa792',
},
},
}));
@@ -91,18 +84,8 @@ describe('Render', () => {
});
it('should not render the Switch to use different creds for log analytics by default', () => {
- setup((props) => ({
- ...props,
- options: {
- ...props.options,
- jsonData: {
- ...props.options.jsonData,
- azureLogAnalyticsSameAs: undefined,
- },
- },
- }));
- expect(screen.queryByLabelText('Same details as Azure Monitor API')).not.toBeInTheDocument();
- expect(screen.queryByText('is deprecated', { exact: false })).not.toBeInTheDocument();
+ setup();
+ expect(screen.queryByText('is no longer supported', { exact: false })).not.toBeInTheDocument();
});
// Remove this test with deprecated code
@@ -117,7 +100,6 @@ describe('Render', () => {
},
},
}));
- expect(screen.queryByLabelText('Same details as Azure Monitor API')).toBeInTheDocument();
- expect(screen.queryByText('is deprecated', { exact: false })).toBeInTheDocument();
+ expect(screen.queryByText('is no longer supported', { exact: false })).toBeInTheDocument();
});
});
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.tsx
index 50cf4fc7485..07103f872a2 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AnalyticsConfig.tsx
@@ -2,15 +2,9 @@ import React, { FunctionComponent, useEffect, useMemo, useReducer, useState } fr
import { SelectableValue } from '@grafana/data';
import { AzureCredentialsForm } from './AzureCredentialsForm';
import { InlineFormLabel, LegacyForms, Button, Alert } from '@grafana/ui';
-const { Select, Switch } = LegacyForms;
-import { AzureDataSourceSettings, AzureCredentials } from '../types';
-import {
- getCredentials,
- getLogAnalyticsCredentials,
- isCredentialsComplete,
- updateLogAnalyticsCredentials,
- updateLogAnalyticsSameAs,
-} from '../credentials';
+const { Select } = LegacyForms;
+import { AzureDataSourceSettings } from '../types';
+import { getCredentials, isCredentialsComplete } from '../credentials';
export interface Props {
options: AzureDataSourceSettings;
@@ -22,22 +16,16 @@ export interface Props {
export const AnalyticsConfig: FunctionComponent = (props: Props) => {
const { updateOptions, getSubscriptions, getWorkspaces } = props;
const primaryCredentials = useMemo(() => getCredentials(props.options), [props.options]);
- const logAnalyticsCredentials = useMemo(() => getLogAnalyticsCredentials(props.options), [props.options]);
- const subscriptionId = logAnalyticsCredentials
- ? logAnalyticsCredentials.defaultSubscriptionId
- : primaryCredentials.defaultSubscriptionId;
+ const subscriptionId = primaryCredentials.defaultSubscriptionId;
- // Only show a section for setting LogAnalytics credentials if they were set from before
- // And the authType is supported
- const [credentialsUsed, _] = useState(!!logAnalyticsCredentials);
- const credentialsEnabled = credentialsUsed && primaryCredentials.authType === 'clientsecret';
+ // Only show a section for setting LogAnalytics credentials if
+ // they were set from before with different values and the
+ // authType is supported
+ const logCredentialsEnabled =
+ primaryCredentials.authType === 'clientsecret' && props.options.jsonData.azureLogAnalyticsSameAs === false;
- const hasRequiredFields =
- subscriptionId &&
- (logAnalyticsCredentials
- ? isCredentialsComplete(logAnalyticsCredentials)
- : isCredentialsComplete(primaryCredentials));
+ const hasRequiredFields = subscriptionId && isCredentialsComplete(primaryCredentials);
const defaultWorkspace = props.options.jsonData.logAnalyticsDefaultWorkspace;
@@ -91,18 +79,6 @@ export const AnalyticsConfig: FunctionComponent = (props: Props) => {
}
};
- const [sameAsSwitched, setSameAsSwitched] = useState(false);
-
- const onCredentialsChange = (updatedCredentials: AzureCredentials) => {
- updateOptions((options) => updateLogAnalyticsCredentials(options, updatedCredentials));
- };
-
- const onLogAnalyticsSameAsChange = (event: React.SyntheticEvent) => {
- const sameAs = event.currentTarget.checked;
- updateOptions((options) => updateLogAnalyticsSameAs(options, sameAs));
- setSameAsSwitched(true);
- };
-
const onDefaultWorkspaceChange = (selected: SelectableValue) => {
updateOptions((options) => {
return {
@@ -115,55 +91,29 @@ export const AnalyticsConfig: FunctionComponent = (props: Props) => {
});
};
- const tooltipAttribute = {
- ...(!logAnalyticsCredentials && {
- tooltip: 'Workspaces are pulled from default subscription selected above.',
- }),
- };
-
- const showSameAsHelpMsg =
- credentialsEnabled &&
- sameAsSwitched &&
- primaryCredentials.authType === 'clientsecret' &&
- !primaryCredentials.clientSecret;
-
return (
<>
Azure Monitor Logs
- {credentialsEnabled && (
+ {logCredentialsEnabled && (
<>
-
+ Using different credentials for Azure Monitor Logs is no longer supported. Authentication information above
+ will be used instead. Please create a new data source with the credentials below.
+
+
+
-
- {showSameAsHelpMsg && (
-
-
-
Re-enter your Azure Monitor Client Secret to use this setting.
-
-
- )}
-
- {logAnalyticsCredentials && (
- <>
-
- Using different credentials for Azure Monitor Logs is deprecated and will be removed in a future
- version.
-
- Create a different Data Source if you need to use different credentials.
-
-
-
- >
- )}
>
)}
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx
index 52a403a246b..67161abf641 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.test.tsx
@@ -1,6 +1,8 @@
import React from 'react';
import { shallow } from 'enzyme';
import AzureCredentialsForm, { Props } from './AzureCredentialsForm';
+import { LegacyForms, Button } from '@grafana/ui';
+const { Input } = LegacyForms;
const setup = (propsFunc?: (props: Props) => Props) => {
let props: Props = {
@@ -63,4 +65,26 @@ describe('Render', () => {
}));
expect(wrapper).toMatchSnapshot();
});
+
+ describe('when disabled', () => {
+ it('should disable inputs', () => {
+ const wrapper = setup((props) => ({
+ ...props,
+ disabled: true,
+ }));
+ const inputs = wrapper.find(Input);
+ expect(inputs.length).toBeGreaterThan(1);
+ inputs.forEach((input) => {
+ expect(input.prop('disabled')).toBe(true);
+ });
+ });
+
+ it('should remove buttons', () => {
+ const wrapper = setup((props) => ({
+ ...props,
+ disabled: true,
+ }));
+ expect(wrapper.find(Button).exists()).toBe(false);
+ });
+ });
});
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx
index af5fa69f081..217ecb39cfc 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/AzureCredentialsForm.tsx
@@ -9,8 +9,9 @@ export interface Props {
managedIdentityEnabled: boolean;
credentials: AzureCredentials;
azureCloudOptions?: SelectableValue[];
- onCredentialsChange: (updatedCredentials: AzureCredentials) => void;
+ onCredentialsChange?: (updatedCredentials: AzureCredentials) => void;
getSubscriptions?: () => Promise
;
+ disabled?: boolean;
}
const authTypeOptions: Array> = [
@@ -25,7 +26,7 @@ const authTypeOptions: Array> = [
];
export const AzureCredentialsForm: FunctionComponent = (props: Props) => {
- const { credentials, azureCloudOptions, onCredentialsChange, getSubscriptions } = props;
+ const { credentials, azureCloudOptions, onCredentialsChange, getSubscriptions, disabled } = props;
const hasRequiredFields = isCredentialsComplete(credentials);
const [subscriptions, setSubscriptions] = useState>>([]);
@@ -189,6 +190,7 @@ export const AzureCredentialsForm: FunctionComponent = (props: Props) =>
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
value={credentials.tenantId || ''}
onChange={onTenantIdChange}
+ disabled={disabled}
/>
@@ -202,39 +204,42 @@ export const AzureCredentialsForm: FunctionComponent = (props: Props) =>
placeholder="XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX"
value={credentials.clientId || ''}
onChange={onClientIdChange}
+ disabled={disabled}
/>
- {typeof credentials.clientSecret === 'symbol' ? (
-
-
- Client Secret
-
-
-
-
-
- reset
-
+ {!disabled &&
+ (typeof credentials.clientSecret === 'symbol' ? (
+
-
- ) : (
-
-
-
Client Secret
-
- )}
+ ))}
>
)}
{getSubscriptions && (
@@ -251,25 +256,28 @@ export const AzureCredentialsForm: FunctionComponent
= (props: Props) =>
}
options={subscriptions}
onChange={onSubscriptionChange}
+ isDisabled={disabled}
/>
-
-
-
-
- Load Subscriptions
-
+ {!disabled && (
+
+
+
+
+ Load Subscriptions
+
+
-
+ )}
>
)}
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx
index 6436da7d3d2..163e8dc07a2 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx
@@ -14,7 +14,7 @@ import { InsightsConfig } from './InsightsConfig';
import ResponseParser from '../azure_monitor/response_parser';
import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData, AzureDataSourceSettings } from '../types';
import { getAzureCloud, isAppInsightsConfigured } from '../credentials';
-import { getLogAnalyticsManagementApiRoute, getManagementApiRoute } from '../api/routes';
+import { getManagementApiRoute } from '../api/routes';
export type Props = DataSourcePluginOptionsEditorProps
;
@@ -77,7 +77,7 @@ export class ConfigEditor extends PureComponent {
await this.saveOptions();
const cloud = getAzureCloud(this.props.options);
- const route = getLogAnalyticsManagementApiRoute(cloud);
+ const route = getManagementApiRoute(cloud);
const url = `/${route}/subscriptions?api-version=2019-03-01`;
const result = await getBackendSrv().datasourceRequest({
@@ -92,7 +92,7 @@ export class ConfigEditor extends PureComponent {
await this.saveOptions();
const cloud = getAzureCloud(this.props.options);
- const route = getLogAnalyticsManagementApiRoute(cloud);
+ const route = getManagementApiRoute(cloud);
const url = `/${route}/subscriptions/${subscriptionId}/providers/Microsoft.OperationalInsights/workspaces?api-version=2017-04-26-preview`;
const result = await getBackendSrv().datasourceRequest({
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.tsx b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.tsx
index 12f756b5147..438d7865893 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.tsx
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.tsx
@@ -23,6 +23,9 @@ export class InsightsConfig extends PureComponent {
return (
<>
Azure Application Insights
+
+ Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
+
{options.secureJsonFields.appInsightsApiKey ? (
@@ -66,10 +69,6 @@ export class InsightsConfig extends PureComponent
{
-
-
- Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
-
>
);
}
diff --git a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AnalyticsConfig.test.tsx.snap b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AnalyticsConfig.test.tsx.snap
index 5ba969e22da..0a8189bffe8 100644
--- a/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AnalyticsConfig.test.tsx.snap
+++ b/public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/AnalyticsConfig.test.tsx.snap
@@ -8,706 +8,6 @@ exports[`Render should disable log analytics credentials form 1`] = `
>
Azure Monitor Logs
-
-
-
-
-
- Azure Monitor Logs
-
-
-
-
-
-
- Deprecated
-
-
- Using different credentials for Azure Monitor Logs is deprecated and will be removed in a future version.
-
- Create a different Data Source if you need to use different credentials.
-
-
-
-
-
-
-
-
-
- Azure Monitor Logs
-
-
-
-
-
-
- Deprecated
-
-
- Using different credentials for Azure Monitor Logs is deprecated and will be removed in a future version.
-
- Create a different Data Source if you need to use different credentials.
-
-
-
-
@@ -818,3 +118,399 @@ exports[`Render should render component 1`] = `
+
+
+ Azure Monitor Logs
+
+
+
+
+
+ Deprecated
+
+
+ Using different credentials for Azure Monitor Logs is no longer supported. Authentication information above will be used instead. Please create a new data source with the credentials below.
+
+
+
+
+
+
+
+
+
+ Azure Monitor Logs
+
+
+
+