AzureMonitor: Hide App Insights for data sources not using it (#34725)

* AzureMonitor: Hide Application Insights and Insights Analytics for panels not using them

* AzureMonitor: Hide Application Insights config

* simplify

* fix test
pull/34828/head^2
Josh Hunt 4 years ago committed by GitHub
parent 6d750c000e
commit 7646246d8c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 93
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.test.tsx
  2. 18
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/ConfigEditor.tsx
  3. 6
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/InsightsConfig.tsx
  4. 50
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryEditor.test.tsx
  5. 33
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/QueryEditor/QueryTypeField.tsx
  6. 110
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/ConfigEditor.test.tsx.snap
  7. 18
      public/app/plugins/datasource/grafana-azure-monitor-datasource/components/__snapshots__/InsightsConfig.test.tsx.snap
  8. 4
      public/app/plugins/datasource/grafana-azure-monitor-datasource/credentials.ts

@ -1,46 +1,63 @@
import { render, screen } from '@testing-library/react';
import React from 'react';
import { shallow } from 'enzyme';
import ConfigEditor, { Props } from './ConfigEditor';
import ConfigEditor from './ConfigEditor';
const setup = () => {
const props: Props = {
options: {
id: 21,
uid: 'y',
orgId: 1,
name: 'Azure Monitor-10-10',
type: 'grafana-azure-monitor-datasource',
typeLogoUrl: '',
typeName: 'Azure',
access: 'proxy',
url: '',
password: '',
user: '',
database: '',
basicAuth: false,
basicAuthUser: '',
basicAuthPassword: '',
withCredentials: false,
isDefault: false,
jsonData: {
subscriptionId: '44987801-6nn6-49he-9b2d-9106972f9789',
azureLogAnalyticsSameAs: true,
cloudName: 'azuremonitor',
},
secureJsonFields: {},
version: 1,
readOnly: false,
},
onOptionsChange: jest.fn(),
describe('AppInsights ConfigEditor', () => {
const baseOptions = {
id: 21,
uid: 'y',
orgId: 1,
name: 'Azure Monitor-10-10',
type: 'grafana-azure-monitor-datasource',
typeLogoUrl: '',
typeName: 'Azure',
access: 'proxy',
url: '',
password: '',
user: '',
database: '',
basicAuth: false,
basicAuthUser: '',
basicAuthPassword: '',
withCredentials: false,
isDefault: false,
jsonData: {},
secureJsonFields: {},
version: 1,
readOnly: false,
};
return shallow(<ConfigEditor {...props} />);
};
const jsonData = {
subscriptionId: '44987801-6nn6-49he-9b2d-9106972f9789',
azureLogAnalyticsSameAs: true,
cloudName: 'azuremonitor',
};
const onOptionsChange = jest.fn();
it('should not render application insights config for new data sources', () => {
const options = {
...baseOptions,
jsonData,
};
render(<ConfigEditor options={options} onOptionsChange={onOptionsChange} />);
describe('Render', () => {
it('should render component', () => {
const wrapper = setup();
expect(screen.queryByText('Azure Application Insights')).not.toBeInTheDocument();
});
it('should render application insights config for data sources using application insights', () => {
const options = {
...baseOptions,
jsonData: {
...jsonData,
appInsightsAppId: 'abc-123',
},
secureJsonFields: {
appInsightsApiKey: true,
},
};
render(<ConfigEditor options={options} onOptionsChange={onOptionsChange} />);
expect(wrapper).toMatchSnapshot();
expect(screen.queryByText('Azure Application Insights')).toBeInTheDocument();
});
});

@ -13,13 +13,14 @@ import { getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
import { InsightsConfig } from './InsightsConfig';
import ResponseParser from '../azure_monitor/response_parser';
import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData, AzureDataSourceSettings } from '../types';
import { getAzureCloud } from '../credentials';
import { getAzureCloud, isAppInsightsConfigured } from '../credentials';
import { getLogAnalyticsManagementApiRoute, getManagementApiRoute } from '../api/routes';
export type Props = DataSourcePluginOptionsEditorProps<AzureDataSourceJsonData, AzureDataSourceSecureJsonData>;
export interface State {
unsaved: boolean;
appInsightsInitiallyConfigured: boolean;
}
export class ConfigEditor extends PureComponent<Props, State> {
@ -30,6 +31,7 @@ export class ConfigEditor extends PureComponent<Props, State> {
this.state = {
unsaved: false,
appInsightsInitiallyConfigured: isAppInsightsConfigured(props.options),
};
if (this.props.options.id) {
@ -138,12 +140,14 @@ export class ConfigEditor extends PureComponent<Props, State> {
getWorkspaces={this.getWorkspaces}
/>
<InsightsConfig
options={options}
onUpdateJsonDataOption={this.onUpdateJsonDataOption}
onUpdateSecureJsonDataOption={this.onUpdateSecureJsonDataOption}
onResetOptionKey={this.resetSecureKey}
/>
{this.state.appInsightsInitiallyConfigured && (
<InsightsConfig
options={options}
onUpdateJsonDataOption={this.onUpdateJsonDataOption}
onUpdateSecureJsonDataOption={this.onUpdateSecureJsonDataOption}
onResetOptionKey={this.resetSecureKey}
/>
)}
</>
);
}

@ -1,5 +1,5 @@
import React, { PureComponent } from 'react';
import { InlineFormLabel, Button, LegacyForms } from '@grafana/ui';
import { InlineFormLabel, Button, LegacyForms, Alert } from '@grafana/ui';
const { Input } = LegacyForms;
import { AzureDataSourceSettings, AzureDataSourceJsonData, AzureDataSourceSecureJsonData } from '../types';
@ -66,6 +66,10 @@ export class InsightsConfig extends PureComponent<Props> {
</div>
</div>
</div>
<Alert severity="info" title="Application Insights credentials are deprecated">
Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
</Alert>
</>
);
}

@ -133,4 +133,54 @@ describe('Azure Monitor QueryEditor', () => {
expect(screen.getByText("The resource namespace 'grafanadev' is invalid.")).toBeInTheDocument();
});
it('hides deprecated services', async () => {
const mockDatasource = createMockDatasource();
const mockQuery = {
...createMockQuery(),
queryType: AzureQueryType.AzureMonitor,
};
render(
<QueryEditor
query={mockQuery}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={() => {}}
/>
);
await waitFor(() => expect(screen.getByTestId('azure-monitor-metrics-query-editor')).toBeInTheDocument());
const metrics = await screen.findByLabelText('Service');
selectEvent.openMenu(metrics);
expect(screen.queryByText('Application Insights')).not.toBeInTheDocument();
});
it("shows deprecated services when they're selected", async () => {
const mockDatasource = createMockDatasource();
const mockQuery = {
...createMockQuery(),
queryType: AzureQueryType.ApplicationInsights,
};
render(
<QueryEditor
query={mockQuery}
datasource={mockDatasource}
variableOptionGroup={variableOptionGroup}
onChange={() => {}}
/>
);
await waitFor(() =>
expect(screen.getByTestId('azure-monitor-application-insights-query-editor')).toBeInTheDocument()
);
expect(screen.queryByText('Application Insights')).toBeInTheDocument();
const metrics = await screen.findByLabelText('Service');
await selectEvent.select(metrics, 'Logs');
expect(screen.queryByText('Application Insights')).toBeInTheDocument();
});
});

@ -1,24 +1,35 @@
import React, { useCallback } from 'react';
import React, { useCallback, useState } from 'react';
import { Select } from '@grafana/ui';
import { Field } from '../Field';
import { AzureMonitorQuery, AzureQueryType } from '../../types';
import { SelectableValue } from '@grafana/data';
import { findOption } from '../../utils/common';
const QUERY_TYPES = [
{ value: AzureQueryType.AzureMonitor, label: 'Metrics' },
{ value: AzureQueryType.LogAnalytics, label: 'Logs' },
{ value: AzureQueryType.ApplicationInsights, label: 'Application Insights' },
{ value: AzureQueryType.InsightsAnalytics, label: 'Insights Analytics' },
{ value: AzureQueryType.AzureResourceGraph, label: 'Azure Resource Graph' },
];
interface QueryTypeFieldProps {
query: AzureMonitorQuery;
onQueryChange: (newQuery: AzureMonitorQuery) => void;
}
const QueryTypeField: React.FC<QueryTypeFieldProps> = ({ query, onQueryChange }) => {
// Use useState to capture the initial value on first mount. We're not interested in when it changes
// We only show App Insights and Insights Analytics if they were initially selected. Otherwise, hide them.
const [initialQueryType] = useState(query.queryType);
const showAppInsights =
initialQueryType === AzureQueryType.ApplicationInsights || initialQueryType === AzureQueryType.InsightsAnalytics;
const queryTypes = [
{ value: AzureQueryType.AzureMonitor, label: 'Metrics' },
{ value: AzureQueryType.LogAnalytics, label: 'Logs' },
{ value: AzureQueryType.AzureResourceGraph, label: 'Azure Resource Graph' },
];
if (showAppInsights) {
queryTypes.push(
{ value: AzureQueryType.ApplicationInsights, label: 'Application Insights' },
{ value: AzureQueryType.InsightsAnalytics, label: 'Insights Analytics' }
);
}
const handleChange = useCallback(
(change: SelectableValue<AzureQueryType>) => {
change.value &&
@ -34,8 +45,8 @@ const QueryTypeField: React.FC<QueryTypeFieldProps> = ({ query, onQueryChange })
<Field label="Service">
<Select
inputId="azure-monitor-query-type-field"
value={findOption(QUERY_TYPES, query.queryType)}
options={QUERY_TYPES}
value={findOption(queryTypes, query.queryType)}
options={queryTypes}
onChange={handleChange}
width={38}
/>

@ -1,110 +0,0 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Render should render component 1`] = `
<Fragment>
<MonitorConfig
getSubscriptions={[Function]}
options={
Object {
"access": "proxy",
"basicAuth": false,
"basicAuthPassword": "",
"basicAuthUser": "",
"database": "",
"id": 21,
"isDefault": false,
"jsonData": Object {
"azureLogAnalyticsSameAs": true,
"cloudName": "azuremonitor",
"subscriptionId": "44987801-6nn6-49he-9b2d-9106972f9789",
},
"name": "Azure Monitor-10-10",
"orgId": 1,
"password": "",
"readOnly": false,
"secureJsonData": Object {},
"secureJsonFields": Object {},
"type": "grafana-azure-monitor-datasource",
"typeLogoUrl": "",
"typeName": "Azure",
"uid": "y",
"url": "",
"user": "",
"version": 1,
"withCredentials": false,
}
}
updateOptions={[Function]}
/>
<AnalyticsConfig
getSubscriptions={[Function]}
getWorkspaces={[Function]}
options={
Object {
"access": "proxy",
"basicAuth": false,
"basicAuthPassword": "",
"basicAuthUser": "",
"database": "",
"id": 21,
"isDefault": false,
"jsonData": Object {
"azureLogAnalyticsSameAs": true,
"cloudName": "azuremonitor",
"subscriptionId": "44987801-6nn6-49he-9b2d-9106972f9789",
},
"name": "Azure Monitor-10-10",
"orgId": 1,
"password": "",
"readOnly": false,
"secureJsonData": Object {},
"secureJsonFields": Object {},
"type": "grafana-azure-monitor-datasource",
"typeLogoUrl": "",
"typeName": "Azure",
"uid": "y",
"url": "",
"user": "",
"version": 1,
"withCredentials": false,
}
}
updateOptions={[Function]}
/>
<InsightsConfig
onResetOptionKey={[Function]}
onUpdateJsonDataOption={[Function]}
onUpdateSecureJsonDataOption={[Function]}
options={
Object {
"access": "proxy",
"basicAuth": false,
"basicAuthPassword": "",
"basicAuthUser": "",
"database": "",
"id": 21,
"isDefault": false,
"jsonData": Object {
"azureLogAnalyticsSameAs": true,
"cloudName": "azuremonitor",
"subscriptionId": "44987801-6nn6-49he-9b2d-9106972f9789",
},
"name": "Azure Monitor-10-10",
"orgId": 1,
"password": "",
"readOnly": false,
"secureJsonData": Object {},
"secureJsonFields": Object {},
"type": "grafana-azure-monitor-datasource",
"typeLogoUrl": "",
"typeName": "Azure",
"uid": "y",
"url": "",
"user": "",
"version": 1,
"withCredentials": false,
}
}
/>
</Fragment>
`;

@ -65,6 +65,12 @@ exports[`Render should disable insights api key input 1`] = `
</div>
</div>
</div>
<Alert
severity="info"
title="Application Insights credentials are deprecated"
>
Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
</Alert>
</Fragment>
`;
@ -122,6 +128,12 @@ exports[`Render should enable insights api key input 1`] = `
</div>
</div>
</div>
<Alert
severity="info"
title="Application Insights credentials are deprecated"
>
Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
</Alert>
</Fragment>
`;
@ -179,5 +191,11 @@ exports[`Render should render component 1`] = `
</div>
</div>
</div>
<Alert
severity="info"
title="Application Insights credentials are deprecated"
>
Configure using Azure AD App Registration above and update existing queries to use Metrics or Logs.
</Alert>
</Fragment>
`;

@ -267,3 +267,7 @@ export function updateLogAnalyticsSameAs(options: AzureDataSourceSettings, sameA
return options;
}
export function isAppInsightsConfigured(options: AzureDataSourceSettings) {
return !!(options.jsonData.appInsightsAppId && options.secureJsonFields.appInsightsApiKey);
}

Loading…
Cancel
Save