mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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
This commit is contained in:
parent
6d750c000e
commit
7646246d8c
@ -1,46 +1,63 @@
|
|||||||
|
import { render, screen } from '@testing-library/react';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import ConfigEditor from './ConfigEditor';
|
||||||
import ConfigEditor, { Props } from './ConfigEditor';
|
|
||||||
|
|
||||||
const setup = () => {
|
describe('AppInsights ConfigEditor', () => {
|
||||||
const props: Props = {
|
const baseOptions = {
|
||||||
options: {
|
id: 21,
|
||||||
id: 21,
|
uid: 'y',
|
||||||
uid: 'y',
|
orgId: 1,
|
||||||
orgId: 1,
|
name: 'Azure Monitor-10-10',
|
||||||
name: 'Azure Monitor-10-10',
|
type: 'grafana-azure-monitor-datasource',
|
||||||
type: 'grafana-azure-monitor-datasource',
|
typeLogoUrl: '',
|
||||||
typeLogoUrl: '',
|
typeName: 'Azure',
|
||||||
typeName: 'Azure',
|
access: 'proxy',
|
||||||
access: 'proxy',
|
url: '',
|
||||||
url: '',
|
password: '',
|
||||||
password: '',
|
user: '',
|
||||||
user: '',
|
database: '',
|
||||||
database: '',
|
basicAuth: false,
|
||||||
basicAuth: false,
|
basicAuthUser: '',
|
||||||
basicAuthUser: '',
|
basicAuthPassword: '',
|
||||||
basicAuthPassword: '',
|
withCredentials: false,
|
||||||
withCredentials: false,
|
isDefault: false,
|
||||||
isDefault: false,
|
jsonData: {},
|
||||||
jsonData: {
|
secureJsonFields: {},
|
||||||
subscriptionId: '44987801-6nn6-49he-9b2d-9106972f9789',
|
version: 1,
|
||||||
azureLogAnalyticsSameAs: true,
|
readOnly: false,
|
||||||
cloudName: 'azuremonitor',
|
|
||||||
},
|
|
||||||
secureJsonFields: {},
|
|
||||||
version: 1,
|
|
||||||
readOnly: false,
|
|
||||||
},
|
|
||||||
onOptionsChange: jest.fn(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return shallow(<ConfigEditor {...props} />);
|
const jsonData = {
|
||||||
};
|
subscriptionId: '44987801-6nn6-49he-9b2d-9106972f9789',
|
||||||
|
azureLogAnalyticsSameAs: true,
|
||||||
|
cloudName: 'azuremonitor',
|
||||||
|
};
|
||||||
|
|
||||||
describe('Render', () => {
|
const onOptionsChange = jest.fn();
|
||||||
it('should render component', () => {
|
|
||||||
const wrapper = setup();
|
|
||||||
|
|
||||||
expect(wrapper).toMatchSnapshot();
|
it('should not render application insights config for new data sources', () => {
|
||||||
|
const options = {
|
||||||
|
...baseOptions,
|
||||||
|
jsonData,
|
||||||
|
};
|
||||||
|
render(<ConfigEditor options={options} onOptionsChange={onOptionsChange} />);
|
||||||
|
|
||||||
|
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(screen.queryByText('Azure Application Insights')).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -13,13 +13,14 @@ import { getBackendSrv, getTemplateSrv, TemplateSrv } from '@grafana/runtime';
|
|||||||
import { InsightsConfig } from './InsightsConfig';
|
import { InsightsConfig } from './InsightsConfig';
|
||||||
import ResponseParser from '../azure_monitor/response_parser';
|
import ResponseParser from '../azure_monitor/response_parser';
|
||||||
import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData, AzureDataSourceSettings } from '../types';
|
import { AzureDataSourceJsonData, AzureDataSourceSecureJsonData, AzureDataSourceSettings } from '../types';
|
||||||
import { getAzureCloud } from '../credentials';
|
import { getAzureCloud, isAppInsightsConfigured } from '../credentials';
|
||||||
import { getLogAnalyticsManagementApiRoute, getManagementApiRoute } from '../api/routes';
|
import { getLogAnalyticsManagementApiRoute, getManagementApiRoute } from '../api/routes';
|
||||||
|
|
||||||
export type Props = DataSourcePluginOptionsEditorProps<AzureDataSourceJsonData, AzureDataSourceSecureJsonData>;
|
export type Props = DataSourcePluginOptionsEditorProps<AzureDataSourceJsonData, AzureDataSourceSecureJsonData>;
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
unsaved: boolean;
|
unsaved: boolean;
|
||||||
|
appInsightsInitiallyConfigured: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class ConfigEditor extends PureComponent<Props, State> {
|
export class ConfigEditor extends PureComponent<Props, State> {
|
||||||
@ -30,6 +31,7 @@ export class ConfigEditor extends PureComponent<Props, State> {
|
|||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
unsaved: false,
|
unsaved: false,
|
||||||
|
appInsightsInitiallyConfigured: isAppInsightsConfigured(props.options),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (this.props.options.id) {
|
if (this.props.options.id) {
|
||||||
@ -138,12 +140,14 @@ export class ConfigEditor extends PureComponent<Props, State> {
|
|||||||
getWorkspaces={this.getWorkspaces}
|
getWorkspaces={this.getWorkspaces}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<InsightsConfig
|
{this.state.appInsightsInitiallyConfigured && (
|
||||||
options={options}
|
<InsightsConfig
|
||||||
onUpdateJsonDataOption={this.onUpdateJsonDataOption}
|
options={options}
|
||||||
onUpdateSecureJsonDataOption={this.onUpdateSecureJsonDataOption}
|
onUpdateJsonDataOption={this.onUpdateJsonDataOption}
|
||||||
onResetOptionKey={this.resetSecureKey}
|
onUpdateSecureJsonDataOption={this.onUpdateSecureJsonDataOption}
|
||||||
/>
|
onResetOptionKey={this.resetSecureKey}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { PureComponent } from 'react';
|
||||||
import { InlineFormLabel, Button, LegacyForms } from '@grafana/ui';
|
import { InlineFormLabel, Button, LegacyForms, Alert } from '@grafana/ui';
|
||||||
const { Input } = LegacyForms;
|
const { Input } = LegacyForms;
|
||||||
import { AzureDataSourceSettings, AzureDataSourceJsonData, AzureDataSourceSecureJsonData } from '../types';
|
import { AzureDataSourceSettings, AzureDataSourceJsonData, AzureDataSourceSecureJsonData } from '../types';
|
||||||
|
|
||||||
@ -66,6 +66,10 @@ export class InsightsConfig extends PureComponent<Props> {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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();
|
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 { Select } from '@grafana/ui';
|
||||||
import { Field } from '../Field';
|
import { Field } from '../Field';
|
||||||
import { AzureMonitorQuery, AzureQueryType } from '../../types';
|
import { AzureMonitorQuery, AzureQueryType } from '../../types';
|
||||||
import { SelectableValue } from '@grafana/data';
|
import { SelectableValue } from '@grafana/data';
|
||||||
import { findOption } from '../../utils/common';
|
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 {
|
interface QueryTypeFieldProps {
|
||||||
query: AzureMonitorQuery;
|
query: AzureMonitorQuery;
|
||||||
onQueryChange: (newQuery: AzureMonitorQuery) => void;
|
onQueryChange: (newQuery: AzureMonitorQuery) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QueryTypeField: React.FC<QueryTypeFieldProps> = ({ query, onQueryChange }) => {
|
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(
|
const handleChange = useCallback(
|
||||||
(change: SelectableValue<AzureQueryType>) => {
|
(change: SelectableValue<AzureQueryType>) => {
|
||||||
change.value &&
|
change.value &&
|
||||||
@ -34,8 +45,8 @@ const QueryTypeField: React.FC<QueryTypeFieldProps> = ({ query, onQueryChange })
|
|||||||
<Field label="Service">
|
<Field label="Service">
|
||||||
<Select
|
<Select
|
||||||
inputId="azure-monitor-query-type-field"
|
inputId="azure-monitor-query-type-field"
|
||||||
value={findOption(QUERY_TYPES, query.queryType)}
|
value={findOption(queryTypes, query.queryType)}
|
||||||
options={QUERY_TYPES}
|
options={queryTypes}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
width={38}
|
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>
|
</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>
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -122,6 +128,12 @@ exports[`Render should enable insights api key input 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
@ -179,5 +191,11 @@ exports[`Render should render component 1`] = `
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</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>
|
</Fragment>
|
||||||
`;
|
`;
|
||||||
|
@ -267,3 +267,7 @@ export function updateLogAnalyticsSameAs(options: AzureDataSourceSettings, sameA
|
|||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isAppInsightsConfigured(options: AzureDataSourceSettings) {
|
||||||
|
return !!(options.jsonData.appInsightsAppId && options.secureJsonFields.appInsightsApiKey);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user