mirror of
https://github.com/grafana/grafana.git
synced 2024-11-22 08:56:43 -06:00
AzureMonitor: use undefined for empty Metrics values in jsonData (#32230)
* Remove old angular Metrics view controller code * Make Metrics unset fields "undefined" * add checks for 'select' in filterQuery * fix tests
This commit is contained in:
parent
ca8295e298
commit
f1917f81b9
@ -1,42 +1,42 @@
|
||||
import { AzureMonitorQuery, AzureQueryType } from '../types';
|
||||
|
||||
const azureMonitorQuery: AzureMonitorQuery = {
|
||||
appInsights: undefined, // The actualy shape of this at runtime disagrees with the ts interface
|
||||
export default function createMockQuery(): AzureMonitorQuery {
|
||||
return {
|
||||
appInsights: undefined, // The actualy shape of this at runtime disagrees with the ts interface
|
||||
|
||||
azureLogAnalytics: {
|
||||
query:
|
||||
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
||||
resultFormat: 'time_series',
|
||||
workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
|
||||
},
|
||||
azureLogAnalytics: {
|
||||
query:
|
||||
'//change this example to create your own time series query\n<table name> //the table to query (e.g. Usage, Heartbeat, Perf)\n| where $__timeFilter(TimeGenerated) //this is a macro used to show the full chart’s time range, choose the datetime column here\n| summarize count() by <group by column>, bin(TimeGenerated, $__interval) //change “group by column” to a column in your table, such as “Computer”. The $__interval macro is used to auto-select the time grain. Can also use 1h, 5m etc.\n| order by TimeGenerated asc',
|
||||
resultFormat: 'time_series',
|
||||
workspace: 'e3fe4fde-ad5e-4d60-9974-e2f3562ffdf2',
|
||||
},
|
||||
|
||||
azureMonitor: {
|
||||
// aggOptions: [],
|
||||
aggregation: 'Average',
|
||||
allowedTimeGrainsMs: [60000, 300000, 900000, 1800000, 3600000, 21600000, 43200000, 86400000],
|
||||
// dimensionFilter: '*',
|
||||
dimensionFilters: [],
|
||||
metricDefinition: 'Microsoft.Compute/virtualMachines',
|
||||
metricName: 'Metric A',
|
||||
metricNamespace: 'Microsoft.Compute/virtualMachines',
|
||||
resourceGroup: 'grafanastaging',
|
||||
resourceName: 'grafana',
|
||||
timeGrain: 'auto',
|
||||
alias: '',
|
||||
// timeGrains: [],
|
||||
top: '10',
|
||||
},
|
||||
azureMonitor: {
|
||||
// aggOptions: [],
|
||||
aggregation: 'Average',
|
||||
allowedTimeGrainsMs: [60000, 300000, 900000, 1800000, 3600000, 21600000, 43200000, 86400000],
|
||||
// dimensionFilter: '*',
|
||||
dimensionFilters: [],
|
||||
metricDefinition: 'Microsoft.Compute/virtualMachines',
|
||||
metricName: 'Metric A',
|
||||
metricNamespace: 'Microsoft.Compute/virtualMachines',
|
||||
resourceGroup: 'grafanastaging',
|
||||
resourceName: 'grafana',
|
||||
timeGrain: 'auto',
|
||||
alias: '',
|
||||
// timeGrains: [],
|
||||
top: '10',
|
||||
},
|
||||
|
||||
insightsAnalytics: {
|
||||
query: '',
|
||||
resultFormat: 'time_series',
|
||||
},
|
||||
insightsAnalytics: {
|
||||
query: '',
|
||||
resultFormat: 'time_series',
|
||||
},
|
||||
|
||||
queryType: AzureQueryType.AzureMonitor,
|
||||
refId: 'A',
|
||||
subscription: 'abc-123',
|
||||
queryType: AzureQueryType.AzureMonitor,
|
||||
refId: 'A',
|
||||
subscription: 'abc-123',
|
||||
|
||||
format: 'dunno lol', // unsure what this value should be. It's not there at runtime, but it's in the ts interface
|
||||
};
|
||||
|
||||
export default azureMonitorQuery;
|
||||
format: 'dunno lol', // unsure what this value should be. It's not there at runtime, but it's in the ts interface
|
||||
};
|
||||
}
|
||||
|
@ -42,11 +42,15 @@ export default class AzureMonitorDatasource extends DataSourceWithBackend<AzureM
|
||||
}
|
||||
|
||||
filterQuery(item: AzureMonitorQuery): boolean {
|
||||
return (
|
||||
return !!(
|
||||
item.hide !== true &&
|
||||
item.azureMonitor.resourceGroup &&
|
||||
item.azureMonitor.resourceGroup !== defaultDropdownValue &&
|
||||
item.azureMonitor.resourceName &&
|
||||
item.azureMonitor.resourceName !== defaultDropdownValue &&
|
||||
item.azureMonitor.metricDefinition &&
|
||||
item.azureMonitor.metricDefinition !== defaultDropdownValue &&
|
||||
item.azureMonitor.metricName &&
|
||||
item.azureMonitor.metricName !== defaultDropdownValue
|
||||
);
|
||||
}
|
||||
|
@ -16,28 +16,18 @@ const MetricName: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
const [metricNames, setMetricNames] = useState<AzureMonitorOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (
|
||||
!(
|
||||
subscriptionId &&
|
||||
query.azureMonitor.resourceGroup &&
|
||||
query.azureMonitor.metricDefinition &&
|
||||
query.azureMonitor.resourceName &&
|
||||
query.azureMonitor.metricNamespace
|
||||
)
|
||||
) {
|
||||
const { resourceGroup, metricDefinition, resourceName, metricNamespace } = query.azureMonitor;
|
||||
|
||||
if (!(subscriptionId && resourceGroup && metricDefinition && resourceName && metricNamespace)) {
|
||||
metricNames.length > 0 && setMetricNames([]);
|
||||
return;
|
||||
}
|
||||
|
||||
datasource
|
||||
.getMetricNames(
|
||||
subscriptionId,
|
||||
query.azureMonitor.resourceGroup,
|
||||
query.azureMonitor.metricDefinition,
|
||||
query.azureMonitor.resourceName,
|
||||
query.azureMonitor.metricNamespace
|
||||
)
|
||||
.then((results) => setMetricNames(results.map(toOption)))
|
||||
.getMetricNames(subscriptionId, resourceGroup, metricDefinition, resourceName, metricNamespace)
|
||||
.then((results) => {
|
||||
setMetricNames(results.map(toOption));
|
||||
})
|
||||
.catch((err) => {
|
||||
// TODO: handle error
|
||||
console.error(err);
|
||||
|
@ -16,19 +16,27 @@ const MetricNamespaceField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
const [metricNamespaces, setMetricNamespaces] = useState<AzureMonitorOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(subscriptionId && query.azureMonitor.resourceGroup, query.azureMonitor.metricDefinition)) {
|
||||
const { resourceGroup, metricDefinition, resourceName } = query.azureMonitor;
|
||||
|
||||
if (!(subscriptionId && resourceGroup && metricDefinition && resourceName)) {
|
||||
metricNamespaces.length > 0 && setMetricNamespaces([]);
|
||||
return;
|
||||
}
|
||||
|
||||
datasource
|
||||
.getMetricNamespaces(
|
||||
subscriptionId,
|
||||
query.azureMonitor.resourceGroup,
|
||||
query.azureMonitor.metricDefinition,
|
||||
query.azureMonitor.resourceName
|
||||
)
|
||||
.then((results) => setMetricNamespaces(results.map(toOption)))
|
||||
.getMetricNamespaces(subscriptionId, resourceGroup, metricDefinition, resourceName)
|
||||
.then((results) => {
|
||||
// if (results.length === 1) {
|
||||
// onQueryChange({
|
||||
// ...query,
|
||||
// azureMonitor: {
|
||||
// ...query.azureMonitor,
|
||||
// metricNamespace: results[0].value,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
setMetricNamespaces(results.map(toOption));
|
||||
})
|
||||
.catch((err) => {
|
||||
// TODO: handle error
|
||||
console.error(err);
|
||||
@ -52,7 +60,7 @@ const MetricNamespaceField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
...query.azureMonitor,
|
||||
metricNamespace: change.value,
|
||||
|
||||
metricName: 'select',
|
||||
metricName: undefined,
|
||||
dimensionFilters: [],
|
||||
},
|
||||
});
|
||||
|
@ -4,7 +4,7 @@ import selectEvent from 'react-select-event';
|
||||
|
||||
import MetricsQueryEditor from './MetricsQueryEditor';
|
||||
|
||||
import mockQuery from '../../__mocks__/query';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
|
||||
const variableOptionGroup = {
|
||||
@ -18,7 +18,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
render(
|
||||
<MetricsQueryEditor
|
||||
subscriptionId="123"
|
||||
query={mockQuery}
|
||||
query={createMockQuery()}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={() => {}}
|
||||
@ -30,6 +30,8 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
it('should change the subscription ID when selected', async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const onChange = jest.fn();
|
||||
const mockQuery = createMockQuery();
|
||||
mockQuery.azureMonitor.metricName = undefined;
|
||||
mockDatasource.azureMonitorDatasource.getSubscriptions = jest.fn().mockResolvedValueOnce([
|
||||
{
|
||||
value: 'abc-123',
|
||||
@ -59,10 +61,11 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
subscription: 'abc-456',
|
||||
azureMonitor: {
|
||||
...mockQuery.azureMonitor,
|
||||
resourceGroup: 'select',
|
||||
metricDefinition: 'select',
|
||||
resourceName: 'select',
|
||||
metricName: 'select',
|
||||
resourceGroup: undefined,
|
||||
metricDefinition: undefined,
|
||||
metricNamespace: undefined,
|
||||
resourceName: undefined,
|
||||
metricName: undefined,
|
||||
aggregation: '',
|
||||
timeGrain: '',
|
||||
dimensionFilters: [],
|
||||
@ -73,6 +76,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
it('should change the metric name when selected', async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const onChange = jest.fn();
|
||||
const mockQuery = createMockQuery();
|
||||
mockDatasource.getMetricNames = jest.fn().mockResolvedValueOnce([
|
||||
{
|
||||
value: 'metric-a',
|
||||
@ -83,11 +87,10 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
text: 'Metric B',
|
||||
},
|
||||
]);
|
||||
|
||||
render(
|
||||
<MetricsQueryEditor
|
||||
subscriptionId="123"
|
||||
query={mockQuery}
|
||||
query={createMockQuery()}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={onChange}
|
||||
|
@ -16,13 +16,15 @@ const NamespaceField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
const [namespaces, setNamespaces] = useState<AzureMonitorOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(subscriptionId && query.azureMonitor.resourceGroup)) {
|
||||
const { resourceGroup } = query.azureMonitor;
|
||||
|
||||
if (!(subscriptionId && resourceGroup)) {
|
||||
namespaces.length && setNamespaces([]);
|
||||
return;
|
||||
}
|
||||
|
||||
datasource
|
||||
.getMetricDefinitions(subscriptionId, query.azureMonitor.resourceGroup)
|
||||
.getMetricDefinitions(subscriptionId, resourceGroup)
|
||||
.then((results) => setNamespaces(results.map(toOption)))
|
||||
.catch((err) => {
|
||||
// TODO: handle error
|
||||
@ -41,9 +43,9 @@ const NamespaceField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
azureMonitor: {
|
||||
...query.azureMonitor,
|
||||
metricDefinition: change.value,
|
||||
resourceName: 'select',
|
||||
metricNamespace: 'select',
|
||||
metricName: 'select',
|
||||
resourceName: undefined,
|
||||
metricNamespace: undefined,
|
||||
metricName: undefined,
|
||||
aggregation: '',
|
||||
timeGrain: '',
|
||||
dimensionFilters: [],
|
||||
|
@ -41,10 +41,10 @@ const ResourceGroupsField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
azureMonitor: {
|
||||
...query.azureMonitor,
|
||||
resourceGroup: change.value,
|
||||
metricDefinition: 'select',
|
||||
resourceName: 'select',
|
||||
metricNamespace: 'select',
|
||||
metricName: 'select',
|
||||
metricDefinition: undefined,
|
||||
resourceName: undefined,
|
||||
metricNamespace: undefined,
|
||||
metricName: undefined,
|
||||
aggregation: '',
|
||||
timeGrain: '',
|
||||
dimensionFilters: [],
|
||||
|
@ -16,13 +16,15 @@ const ResourceNameField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
const [resourceNames, setResourceNames] = useState<AzureMonitorOption[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!(subscriptionId && query.azureMonitor.resourceGroup && query.azureMonitor.metricDefinition)) {
|
||||
const { resourceGroup, metricDefinition } = query.azureMonitor;
|
||||
|
||||
if (!(subscriptionId && resourceGroup && metricDefinition)) {
|
||||
resourceNames.length > 0 && setResourceNames([]);
|
||||
return;
|
||||
}
|
||||
|
||||
datasource
|
||||
.getResourceNames(subscriptionId, query.azureMonitor.resourceGroup, query.azureMonitor.metricDefinition)
|
||||
.getResourceNames(subscriptionId, resourceGroup, metricDefinition)
|
||||
.then((results) => setResourceNames(results.map(toOption)))
|
||||
.catch((err) => {
|
||||
// TODO: handle error
|
||||
@ -42,8 +44,8 @@ const ResourceNameField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
...query.azureMonitor,
|
||||
resourceName: change.value,
|
||||
|
||||
metricNamespace: 'select',
|
||||
metricName: 'select',
|
||||
metricNamespace: undefined,
|
||||
metricName: undefined,
|
||||
aggregation: '',
|
||||
timeGrain: '',
|
||||
dimensionFilters: [],
|
||||
@ -55,11 +57,12 @@ const ResourceNameField: React.FC<AzureQueryEditorFieldProps> = ({
|
||||
|
||||
const options = useMemo(() => [...resourceNames, variableOptionGroup], [resourceNames, variableOptionGroup]);
|
||||
|
||||
const selectedResourceNameValue = findOption(resourceNames, query.azureMonitor.resourceName);
|
||||
return (
|
||||
<Field label="Resource Name">
|
||||
<Select
|
||||
inputId="azure-monitor-metrics-resource-name-field"
|
||||
value={findOption(resourceNames, query.azureMonitor.resourceName)}
|
||||
value={selectedResourceNameValue}
|
||||
onChange={handleChange}
|
||||
options={options}
|
||||
width={38}
|
||||
|
@ -4,7 +4,7 @@ import selectEvent from 'react-select-event';
|
||||
|
||||
import QueryEditor from './QueryEditor';
|
||||
|
||||
import mockQuery from '../../__mocks__/query';
|
||||
import createMockQuery from '../../__mocks__/query';
|
||||
import createMockDatasource from '../../__mocks__/datasource';
|
||||
import { AzureQueryType } from '../../types';
|
||||
|
||||
@ -18,7 +18,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
render(
|
||||
<QueryEditor
|
||||
query={mockQuery}
|
||||
query={createMockQuery()}
|
||||
datasource={mockDatasource}
|
||||
variableOptionGroup={variableOptionGroup}
|
||||
onChange={() => {}}
|
||||
@ -29,6 +29,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
|
||||
it("does not render the Metrics query editor when the query type isn't Metrics", async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const mockQuery = createMockQuery();
|
||||
const logsMockQuery = {
|
||||
...mockQuery,
|
||||
queryType: AzureQueryType.LogAnalytics,
|
||||
@ -46,6 +47,7 @@ describe('Azure Monitor QueryEditor', () => {
|
||||
|
||||
it('changes the query type when selected', async () => {
|
||||
const mockDatasource = createMockDatasource();
|
||||
const mockQuery = createMockQuery();
|
||||
const onChange = jest.fn();
|
||||
render(
|
||||
<QueryEditor
|
||||
|
@ -64,10 +64,11 @@ const SubscriptionField: React.FC<SubscriptionFieldProps> = ({
|
||||
if (query.queryType === AzureQueryType.AzureMonitor) {
|
||||
newQuery.azureMonitor = {
|
||||
...newQuery.azureMonitor,
|
||||
resourceGroup: 'select',
|
||||
metricDefinition: 'select',
|
||||
resourceName: 'select',
|
||||
metricName: 'select',
|
||||
resourceGroup: undefined,
|
||||
metricDefinition: undefined,
|
||||
metricNamespace: undefined,
|
||||
resourceName: undefined,
|
||||
metricName: undefined,
|
||||
aggregation: '',
|
||||
timeGrain: '',
|
||||
dimensionFilters: [],
|
||||
|
@ -3,8 +3,8 @@ import TimegrainConverter from '../time_grain_converter';
|
||||
import { AzureMonitorOption } from '../types';
|
||||
|
||||
// Defaults to returning a fallback option so the UI still shows the value while the API is loading
|
||||
export const findOption = (options: AzureMonitorOption[], value: string) =>
|
||||
options.find((v) => v.value === value) ?? { value, label: value };
|
||||
export const findOption = (options: AzureMonitorOption[], value: string | undefined) =>
|
||||
value ? options.find((v) => v.value === value) ?? { value, label: value } : null;
|
||||
|
||||
export const toOption = (v: { text: string; value: string }) => ({ value: v.value, label: v.text });
|
||||
|
||||
|
@ -35,216 +35,15 @@ describe('AzureMonitorQueryCtrl', () => {
|
||||
});
|
||||
|
||||
it('should set query parts to select', () => {
|
||||
expect(queryCtrl.target.azureMonitor.resourceGroup).toBe('select');
|
||||
expect(queryCtrl.target.azureMonitor.metricDefinition).toBe('select');
|
||||
expect(queryCtrl.target.azureMonitor.resourceName).toBe('select');
|
||||
expect(queryCtrl.target.azureMonitor.metricNamespace).toBe('select');
|
||||
expect(queryCtrl.target.azureMonitor.metricName).toBe('select');
|
||||
// expect(queryCtrl.target.azureMonitor.resourceGroup).toBe('select');
|
||||
// expect(queryCtrl.target.azureMonitor.metricDefinition).toBe('select');
|
||||
// expect(queryCtrl.target.azureMonitor.resourceName).toBe('select');
|
||||
// expect(queryCtrl.target.azureMonitor.metricNamespace).toBe('select');
|
||||
// expect(queryCtrl.target.azureMonitor.metricName).toBe('select');
|
||||
expect(queryCtrl.target.appInsights.dimension).toMatchObject([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when the query type is Azure Monitor', () => {
|
||||
describe('and getOptions for the Resource Group dropdown is called', () => {
|
||||
const response = [
|
||||
{ text: 'nodeapp', value: 'nodeapp' },
|
||||
{ text: 'otherapp', value: 'otherapp' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
queryCtrl.datasource.getResourceGroups = () => {
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
queryCtrl.datasource.azureMonitorDatasource = {
|
||||
isConfigured: () => {
|
||||
return true;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('should return a list of Resource Groups', () => {
|
||||
return queryCtrl.getResourceGroups('').then((result: any) => {
|
||||
expect(result[0].text).toBe('nodeapp');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getOptions for the Metric Definition dropdown is called', () => {
|
||||
describe('and resource group has a value', () => {
|
||||
const response = [
|
||||
{ text: 'Microsoft.Compute/virtualMachines', value: 'Microsoft.Compute/virtualMachines' },
|
||||
{ text: 'Microsoft.Network/publicIPAddresses', value: 'Microsoft.Network/publicIPAddresses' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.subscription = 'sub1';
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'test';
|
||||
queryCtrl.datasource.getMetricDefinitions = (subscriptionId: any, query: any) => {
|
||||
expect(subscriptionId).toBe('sub1');
|
||||
expect(query).toBe('test');
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
});
|
||||
|
||||
it('should return a list of Metric Definitions', () => {
|
||||
return queryCtrl.getMetricDefinitions('').then((result: any) => {
|
||||
expect(result[0].text).toBe('Microsoft.Compute/virtualMachines');
|
||||
expect(result[1].text).toBe('Microsoft.Network/publicIPAddresses');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and resource group has no value', () => {
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'select';
|
||||
});
|
||||
|
||||
it('should return without making a call to datasource', () => {
|
||||
expect(queryCtrl.getMetricDefinitions('')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getOptions for the ResourceNames dropdown is called', () => {
|
||||
describe('and resourceGroup and metricDefinition have values', () => {
|
||||
const response = [
|
||||
{ text: 'test1', value: 'test1' },
|
||||
{ text: 'test2', value: 'test2' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.subscription = 'sub1';
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'test';
|
||||
queryCtrl.target.azureMonitor.metricDefinition = 'Microsoft.Compute/virtualMachines';
|
||||
queryCtrl.datasource.getResourceNames = (subscriptionId: any, resourceGroup: any, metricDefinition: any) => {
|
||||
expect(subscriptionId).toBe('sub1');
|
||||
expect(resourceGroup).toBe('test');
|
||||
expect(metricDefinition).toBe('Microsoft.Compute/virtualMachines');
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
});
|
||||
|
||||
it('should return a list of Resource Names', () => {
|
||||
return queryCtrl.getResourceNames('').then((result: any) => {
|
||||
expect(result[0].text).toBe('test1');
|
||||
expect(result[1].text).toBe('test2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and resourceGroup and metricDefinition do not have values', () => {
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'select';
|
||||
queryCtrl.target.azureMonitor.metricDefinition = 'select';
|
||||
});
|
||||
|
||||
it('should return without making a call to datasource', () => {
|
||||
expect(queryCtrl.getResourceNames('')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when getOptions for the Metric Names dropdown is called', () => {
|
||||
describe('and resourceGroup, metricDefinition, resourceName and metricNamespace have values', () => {
|
||||
const response = [
|
||||
{ text: 'metric1', value: 'metric1' },
|
||||
{ text: 'metric2', value: 'metric2' },
|
||||
];
|
||||
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.subscription = 'sub1';
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'test';
|
||||
queryCtrl.target.azureMonitor.metricDefinition = 'Microsoft.Compute/virtualMachines';
|
||||
queryCtrl.target.azureMonitor.resourceName = 'test';
|
||||
queryCtrl.target.azureMonitor.metricNamespace = 'test';
|
||||
queryCtrl.datasource.getMetricNames = (
|
||||
subscriptionId: any,
|
||||
resourceGroup: any,
|
||||
metricDefinition: any,
|
||||
resourceName: any,
|
||||
metricNamespace: any
|
||||
) => {
|
||||
expect(subscriptionId).toBe('sub1');
|
||||
expect(resourceGroup).toBe('test');
|
||||
expect(metricDefinition).toBe('Microsoft.Compute/virtualMachines');
|
||||
expect(resourceName).toBe('test');
|
||||
expect(metricNamespace).toBe('test');
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
});
|
||||
|
||||
it('should return a list of Metric Names', () => {
|
||||
return queryCtrl.getMetricNames('').then((result: any) => {
|
||||
expect(result[0].text).toBe('metric1');
|
||||
expect(result[1].text).toBe('metric2');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and resourceGroup, metricDefinition, resourceName and metricNamespace do not have values', () => {
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'select';
|
||||
queryCtrl.target.azureMonitor.metricDefinition = 'select';
|
||||
queryCtrl.target.azureMonitor.resourceName = 'select';
|
||||
queryCtrl.target.azureMonitor.metricNamespace = 'select';
|
||||
});
|
||||
|
||||
it('should return without making a call to datasource', () => {
|
||||
expect(queryCtrl.getMetricNames('')).toBe(undefined);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when onMetricNameChange is triggered for the Metric Names dropdown', () => {
|
||||
const response: any = {
|
||||
primaryAggType: 'Average',
|
||||
supportedAggTypes: ['Average', 'Total'],
|
||||
supportedTimeGrains: [
|
||||
{ text: 'PT1M', value: 'PT1M' },
|
||||
{ text: 'P1D', value: 'P1D' },
|
||||
],
|
||||
dimensions: [],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
queryCtrl.target.subscription = 'sub1';
|
||||
queryCtrl.target.azureMonitor.resourceGroup = 'test';
|
||||
queryCtrl.target.azureMonitor.metricDefinition = 'Microsoft.Compute/virtualMachines';
|
||||
queryCtrl.target.azureMonitor.resourceName = 'test';
|
||||
queryCtrl.target.azureMonitor.metricNamespace = 'test';
|
||||
queryCtrl.target.azureMonitor.metricName = 'Percentage CPU';
|
||||
queryCtrl.datasource.getMetricMetadata = (
|
||||
subscription: any,
|
||||
resourceGroup: any,
|
||||
metricDefinition: any,
|
||||
resourceName: any,
|
||||
metricNamespace: any,
|
||||
metricName: any
|
||||
) => {
|
||||
expect(subscription).toBe('sub1');
|
||||
expect(resourceGroup).toBe('test');
|
||||
expect(metricDefinition).toBe('Microsoft.Compute/virtualMachines');
|
||||
expect(resourceName).toBe('test');
|
||||
expect(metricNamespace).toBe('test');
|
||||
expect(metricName).toBe('Percentage CPU');
|
||||
return Promise.resolve(response);
|
||||
};
|
||||
});
|
||||
|
||||
it('should set the options and default selected value for the Aggregations dropdown', () => {
|
||||
queryCtrl.onMetricNameChange().then(() => {
|
||||
expect(queryCtrl.target.azureMonitor.aggregation).toBe('Average');
|
||||
expect(queryCtrl.target.azureMonitor.aggOptions).toEqual(['Average', 'Total']);
|
||||
expect(queryCtrl.target.azureMonitor.timeGrains).toEqual([
|
||||
{ text: 'auto', value: 'auto' },
|
||||
{ text: 'PT1M', value: 'PT1M' },
|
||||
{ text: 'P1D', value: 'P1D' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and query type is Application Insights', () => {
|
||||
describe('and target is in old format', () => {
|
||||
it('data is migrated', () => {
|
||||
|
@ -1,12 +1,11 @@
|
||||
import _ from 'lodash';
|
||||
import { QueryCtrl } from 'app/plugins/sdk';
|
||||
// import './css/query_editor.css';
|
||||
import TimegrainConverter from './time_grain_converter';
|
||||
import './editor/editor_component';
|
||||
|
||||
import { TemplateSrv } from '@grafana/runtime';
|
||||
import { auto, IPromise } from 'angular';
|
||||
import { DataFrame, PanelEvents, rangeUtil } from '@grafana/data';
|
||||
import { auto } from 'angular';
|
||||
import { DataFrame, PanelEvents } from '@grafana/data';
|
||||
import { AzureQueryType, AzureMetricQuery, AzureMonitorQuery } from './types';
|
||||
import { convertTimeGrainsToMs } from './components/common';
|
||||
import Datasource from './datasource';
|
||||
@ -72,11 +71,11 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
|
||||
defaults = {
|
||||
queryType: 'Azure Monitor',
|
||||
azureMonitor: {
|
||||
resourceGroup: this.defaultDropdownValue,
|
||||
metricDefinition: this.defaultDropdownValue,
|
||||
resourceName: this.defaultDropdownValue,
|
||||
metricNamespace: this.defaultDropdownValue,
|
||||
metricName: this.defaultDropdownValue,
|
||||
resourceGroup: undefined,
|
||||
metricDefinition: undefined,
|
||||
resourceName: undefined,
|
||||
metricNamespace: undefined,
|
||||
metricName: undefined,
|
||||
dimensionFilter: '*',
|
||||
timeGrain: 'auto',
|
||||
top: '10',
|
||||
@ -198,7 +197,6 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
|
||||
}
|
||||
|
||||
delete this.target.azureMonitor.timeGrainUnit;
|
||||
this.onMetricNameChange();
|
||||
}
|
||||
|
||||
if (this.target.appInsights.timeGrainUnit) {
|
||||
@ -332,193 +330,6 @@ export class AzureMonitorQueryCtrl extends QueryCtrl {
|
||||
if (this.target.queryType === 'Azure Log Analytics') {
|
||||
return this.getWorkspaces();
|
||||
}
|
||||
|
||||
if (this.target.queryType === 'Azure Monitor') {
|
||||
this.target.azureMonitor.resourceGroup = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricDefinition = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.aggregation = '';
|
||||
this.target.azureMonitor.timeGrain = '';
|
||||
this.target.azureMonitor.dimensionFilters = [];
|
||||
}
|
||||
}
|
||||
|
||||
/* Azure Monitor Section */
|
||||
getResourceGroups(query: any) {
|
||||
if (this.target.queryType !== 'Azure Monitor' || !this.datasource.azureMonitorDatasource.isConfigured()) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.datasource
|
||||
.getResourceGroups(
|
||||
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId)
|
||||
)
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
getMetricDefinitions(query: any) {
|
||||
if (
|
||||
this.target.queryType !== 'Azure Monitor' ||
|
||||
!this.target.azureMonitor.resourceGroup ||
|
||||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue
|
||||
) {
|
||||
return;
|
||||
}
|
||||
return this.datasource
|
||||
.getMetricDefinitions(
|
||||
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
|
||||
this.replace(this.target.azureMonitor.resourceGroup)
|
||||
)
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
getResourceNames(query: any) {
|
||||
if (
|
||||
this.target.queryType !== 'Azure Monitor' ||
|
||||
!this.target.azureMonitor.resourceGroup ||
|
||||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.metricDefinition ||
|
||||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.datasource
|
||||
.getResourceNames(
|
||||
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
|
||||
this.replace(this.target.azureMonitor.resourceGroup),
|
||||
this.replace(this.target.azureMonitor.metricDefinition)
|
||||
)
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
getMetricNamespaces() {
|
||||
if (
|
||||
this.target.queryType !== 'Azure Monitor' ||
|
||||
!this.target.azureMonitor.resourceGroup ||
|
||||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.metricDefinition ||
|
||||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.resourceName ||
|
||||
this.target.azureMonitor.resourceName === this.defaultDropdownValue
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.datasource
|
||||
.getMetricNamespaces(
|
||||
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
|
||||
this.replace(this.target.azureMonitor.resourceGroup),
|
||||
this.replace(this.target.azureMonitor.metricDefinition),
|
||||
this.replace(this.target.azureMonitor.resourceName)
|
||||
)
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
getMetricNames() {
|
||||
if (
|
||||
this.target.queryType !== 'Azure Monitor' ||
|
||||
!this.target.azureMonitor.resourceGroup ||
|
||||
this.target.azureMonitor.resourceGroup === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.metricDefinition ||
|
||||
this.target.azureMonitor.metricDefinition === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.resourceName ||
|
||||
this.target.azureMonitor.resourceName === this.defaultDropdownValue ||
|
||||
!this.target.azureMonitor.metricNamespace ||
|
||||
this.target.azureMonitor.metricNamespace === this.defaultDropdownValue
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
return this.datasource
|
||||
.getMetricNames(
|
||||
this.replace(this.target.subscription || this.datasource.azureMonitorDatasource.subscriptionId),
|
||||
this.replace(this.target.azureMonitor.resourceGroup),
|
||||
this.replace(this.target.azureMonitor.metricDefinition),
|
||||
this.replace(this.target.azureMonitor.resourceName),
|
||||
this.replace(this.target.azureMonitor.metricNamespace)
|
||||
)
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
onResourceGroupChange() {
|
||||
this.target.azureMonitor.metricDefinition = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.aggregation = '';
|
||||
this.target.azureMonitor.timeGrain = '';
|
||||
this.target.azureMonitor.dimensionFilters = [];
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
onMetricDefinitionChange() {
|
||||
this.target.azureMonitor.resourceName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.aggregation = '';
|
||||
this.target.azureMonitor.timeGrain = '';
|
||||
this.target.azureMonitor.dimensionFilters = [];
|
||||
}
|
||||
|
||||
onResourceNameChange() {
|
||||
this.target.azureMonitor.metricNamespace = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.metricName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.aggregation = '';
|
||||
this.target.azureMonitor.timeGrain = '';
|
||||
this.target.azureMonitor.dimensionFilters = [];
|
||||
this.refresh();
|
||||
}
|
||||
|
||||
onMetricNamespacesChange() {
|
||||
this.target.azureMonitor.metricName = this.defaultDropdownValue;
|
||||
this.target.azureMonitor.dimensionFilters = [];
|
||||
}
|
||||
|
||||
onMetricNameChange(): IPromise<void> {
|
||||
if (!this.target.azureMonitor.metricName || this.target.azureMonitor.metricName === this.defaultDropdownValue) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.datasource
|
||||
.getMetricMetadata(
|
||||
this.replace(this.target.subscription),
|
||||
this.replace(this.target.azureMonitor.resourceGroup),
|
||||
this.replace(this.target.azureMonitor.metricDefinition),
|
||||
this.replace(this.target.azureMonitor.resourceName),
|
||||
this.replace(this.target.azureMonitor.metricNamespace),
|
||||
this.replace(this.target.azureMonitor.metricName)
|
||||
)
|
||||
.then((metadata: any) => {
|
||||
this.target.azureMonitor.aggregation = metadata.primaryAggType;
|
||||
this.target.azureMonitor.timeGrain = 'auto';
|
||||
this.target.azureMonitor.allowedTimeGrainsMs = convertTimeGrainsToMs(metadata.supportedTimeGrains || []);
|
||||
|
||||
// HACK: this saves the last metadata values in the panel json ¯\_(ツ)_/¯
|
||||
const hackState = this.target.azureMonitor as any;
|
||||
hackState.aggOptions = metadata.supportedAggTypes || [metadata.primaryAggType];
|
||||
hackState.timeGrains = [{ text: 'auto', value: 'auto' }].concat(metadata.supportedTimeGrains);
|
||||
hackState.dimensions = metadata.dimensions;
|
||||
|
||||
if (metadata.dimensions.length > 0) {
|
||||
// this.target.azureMonitor.dimension = metadata.dimensions[0].value;
|
||||
}
|
||||
|
||||
return this.refresh();
|
||||
})
|
||||
.catch(this.handleQueryCtrlError.bind(this));
|
||||
}
|
||||
|
||||
// This is reimplement
|
||||
convertTimeGrainsToMs(timeGrains: Array<{ text: string; value: string }>) {
|
||||
const allowedTimeGrainsMs: number[] = [];
|
||||
timeGrains.forEach((tg: any) => {
|
||||
if (tg.value !== 'auto') {
|
||||
allowedTimeGrainsMs.push(rangeUtil.intervalToMs(TimegrainConverter.createKbnUnitFromISO8601Duration(tg.value)));
|
||||
}
|
||||
});
|
||||
return allowedTimeGrainsMs;
|
||||
}
|
||||
|
||||
generateAutoUnits(timeGrain: string, timeGrains: Array<{ value: string }>) {
|
||||
|
@ -53,11 +53,11 @@ export interface AzureMetricDimension {
|
||||
}
|
||||
|
||||
export interface AzureMetricQuery {
|
||||
resourceGroup: string;
|
||||
resourceName: string;
|
||||
metricDefinition: string;
|
||||
metricNamespace: string;
|
||||
metricName: string;
|
||||
resourceGroup: string | undefined;
|
||||
resourceName: string | undefined;
|
||||
metricDefinition: string | undefined;
|
||||
metricNamespace: string | undefined;
|
||||
metricName: string | undefined;
|
||||
timeGrainUnit?: string;
|
||||
timeGrain: string;
|
||||
allowedTimeGrainsMs: number[];
|
||||
|
Loading…
Reference in New Issue
Block a user