From dac2b7ef73dcb956c0881677e8764363210c73da Mon Sep 17 00:00:00 2001 From: Isabella Siu Date: Thu, 17 Feb 2022 09:04:59 -0500 Subject: [PATCH] Cloudwatch: Fix resource variables (#45496) --- .../datasource/cloudwatch/datasource.ts | 77 +++++++++++++++++++ .../cloudwatch/specs/datasource.test.ts | 29 +++++++ 2 files changed, 106 insertions(+) diff --git a/public/app/plugins/datasource/cloudwatch/datasource.ts b/public/app/plugins/datasource/cloudwatch/datasource.ts index f92756527f4..91881025ddc 100644 --- a/public/app/plugins/datasource/cloudwatch/datasource.ts +++ b/public/app/plugins/datasource/cloudwatch/datasource.ts @@ -736,6 +736,83 @@ export class CloudWatchDatasource }); } + async metricFindQuery(query: string) { + let region; + let namespace; + let metricName; + let filterJson; + + const regionQuery = query.match(/^regions\(\)/); + if (regionQuery) { + return this.getRegions(); + } + + const namespaceQuery = query.match(/^namespaces\(\)/); + if (namespaceQuery) { + return this.getNamespaces(); + } + + const metricNameQuery = query.match(/^metrics\(([^\)]+?)(,\s?([^,]+?))?\)/); + if (metricNameQuery) { + namespace = metricNameQuery[1]; + region = metricNameQuery[3]; + return this.getMetrics(namespace, region); + } + + const dimensionKeysQuery = query.match(/^dimension_keys\(([^\)]+?)(,\s?([^,]+?))?\)/); + if (dimensionKeysQuery) { + namespace = dimensionKeysQuery[1]; + region = dimensionKeysQuery[3]; + return this.getDimensionKeys(namespace, region); + } + + const dimensionValuesQuery = query.match( + /^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?(.+))?\)/ + ); + if (dimensionValuesQuery) { + region = dimensionValuesQuery[1]; + namespace = dimensionValuesQuery[2]; + metricName = dimensionValuesQuery[3]; + const dimensionKey = dimensionValuesQuery[4]; + filterJson = {}; + if (dimensionValuesQuery[6]) { + filterJson = JSON.parse(this.templateSrv.replace(dimensionValuesQuery[6])); + } + + return this.getDimensionValues(region, namespace, metricName, dimensionKey, filterJson); + } + + const ebsVolumeIdsQuery = query.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/); + if (ebsVolumeIdsQuery) { + region = ebsVolumeIdsQuery[1]; + const instanceId = ebsVolumeIdsQuery[2]; + return this.getEbsVolumeIds(region, instanceId); + } + + const ec2InstanceAttributeQuery = query.match(/^ec2_instance_attribute\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/); + if (ec2InstanceAttributeQuery) { + region = ec2InstanceAttributeQuery[1]; + const targetAttributeName = ec2InstanceAttributeQuery[2]; + filterJson = JSON.parse(this.templateSrv.replace(ec2InstanceAttributeQuery[3])); + return this.getEc2InstanceAttribute(region, targetAttributeName, filterJson); + } + + const resourceARNsQuery = query.match(/^resource_arns\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/); + if (resourceARNsQuery) { + region = resourceARNsQuery[1]; + const resourceType = resourceARNsQuery[2]; + const tagsJSON = JSON.parse(this.templateSrv.replace(resourceARNsQuery[3])); + return this.getResourceARNs(region, resourceType, tagsJSON); + } + + const statsQuery = query.match(/^statistics\(\)/); + if (statsQuery) { + return this.standardStatistics.map((s: string) => ({ value: s, label: s, text: s })); + } + + return Promise.resolve([]); + } + annotationQuery(options: any) { const annotation = options.annotation; const statistic = this.templateSrv.replace(annotation.statistic); diff --git a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts index 6c608fcdf7b..d8d06ff56ec 100644 --- a/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts +++ b/public/app/plugins/datasource/cloudwatch/specs/datasource.test.ts @@ -506,6 +506,35 @@ describe('CloudWatchDatasource', () => { }); }); }); + describe('when regions query is used', () => { + describe('and region param is left out', () => { + it('should use the default region', async () => { + const { ds, instanceSettings } = getTestContext(); + ds.doMetricResourceRequest = jest.fn().mockResolvedValue([]); + + await ds.metricFindQuery('metrics(testNamespace)'); + + expect(ds.doMetricResourceRequest).toHaveBeenCalledWith('metrics', { + namespace: 'testNamespace', + region: instanceSettings.jsonData.defaultRegion, + }); + }); + }); + + describe('and region param is defined by user', () => { + it('should use the user defined region', async () => { + const { ds } = getTestContext(); + ds.doMetricResourceRequest = jest.fn().mockResolvedValue([]); + + await ds.metricFindQuery('metrics(testNamespace2, custom-region)'); + + expect(ds.doMetricResourceRequest).toHaveBeenCalledWith('metrics', { + namespace: 'testNamespace2', + region: 'custom-region', + }); + }); + }); + }); }); describe('When query region is "default"', () => {