The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/plugins/datasource/cloudwatch/migrations/variableQueryMigrations.ts

170 lines
5.9 KiB

import { omit } from 'lodash';
import { Dimensions, VariableQuery, VariableQueryType, OldVariableQuery, MultiFilters } from '../types';
const jsonVariable = /\${(\w+):json}/g;
function isVariableQuery(rawQuery: string | VariableQuery | OldVariableQuery): rawQuery is VariableQuery {
return typeof rawQuery !== 'string' && typeof rawQuery.ec2Filters !== 'string' && typeof rawQuery.tags !== 'string';
}
function migrateMultiFilters(oldFilters: string): MultiFilters {
const tempFilters = oldFilters.replace(jsonVariable, '"$$$1"');
const parsedFilters: Dimensions = JSON.parse(tempFilters);
const newFilters: MultiFilters = {};
// if the old filter was {key:value} transform it to {key:[value]}
Object.keys(parsedFilters).forEach((key) => {
const value = parsedFilters[key];
if (typeof value === 'string') {
newFilters[key] = [value];
} else if (value !== undefined) {
newFilters[key] = value;
}
});
return newFilters;
}
export function migrateVariableQuery(rawQuery: string | VariableQuery | OldVariableQuery): VariableQuery {
if (isVariableQuery(rawQuery)) {
return rawQuery;
}
// rawQuery is OldVariableQuery
if (typeof rawQuery !== 'string') {
const newQuery: VariableQuery = omit(rawQuery, ['dimensionFilters', 'ec2Filters', 'tags']);
newQuery.dimensionFilters = {};
newQuery.ec2Filters = {};
newQuery.tags = {};
if (rawQuery.dimensionFilters !== '' && rawQuery.ec2Filters !== '[]') {
const tempFilters = rawQuery.dimensionFilters.replace(jsonVariable, '"$$$1"');
try {
newQuery.dimensionFilters = JSON.parse(tempFilters);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${rawQuery.dimensionFilters}`);
}
}
if (rawQuery.ec2Filters !== '' && rawQuery.ec2Filters !== '[]') {
try {
newQuery.ec2Filters = migrateMultiFilters(rawQuery.ec2Filters);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${rawQuery.ec2Filters}`);
}
}
if (rawQuery.tags !== '' && rawQuery.tags !== '[]') {
try {
newQuery.tags = migrateMultiFilters(rawQuery.tags);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${rawQuery.tags}`);
}
}
return newQuery;
}
const newQuery: VariableQuery = {
refId: 'CloudWatchVariableQueryEditor-VariableQuery',
queryType: VariableQueryType.Regions,
namespace: '',
region: '',
metricName: '',
dimensionKey: '',
dimensionFilters: {},
ec2Filters: {},
instanceID: '',
attributeName: '',
resourceType: '',
tags: {},
};
if (rawQuery === '') {
return newQuery;
}
if (rawQuery.match(/^regions\(\)/)) {
return newQuery;
}
if (rawQuery.match(/^namespaces\(\)/)) {
newQuery.queryType = VariableQueryType.Namespaces;
return newQuery;
}
const metricNameQuery = rawQuery.match(/^metrics\(([^\)]+?)(,\s?([^,]+?))?\)/);
if (metricNameQuery) {
newQuery.queryType = VariableQueryType.Metrics;
newQuery.namespace = metricNameQuery[1];
newQuery.region = metricNameQuery[3] || '';
return newQuery;
}
const dimensionKeysQuery = rawQuery.match(/^dimension_keys\(([^\)]+?)(,\s?([^,]+?))?\)/);
if (dimensionKeysQuery) {
newQuery.queryType = VariableQueryType.DimensionKeys;
newQuery.namespace = dimensionKeysQuery[1];
newQuery.region = dimensionKeysQuery[3] || '';
return newQuery;
}
const dimensionValuesQuery = rawQuery.match(
/^dimension_values\(([^,]+?),\s?([^,]+?),\s?([^,]+?),\s?([^,]+?)(,\s?(.+))?\)/
);
if (dimensionValuesQuery) {
newQuery.queryType = VariableQueryType.DimensionValues;
newQuery.region = dimensionValuesQuery[1];
newQuery.namespace = dimensionValuesQuery[2];
newQuery.metricName = dimensionValuesQuery[3];
newQuery.dimensionKey = dimensionValuesQuery[4];
newQuery.dimensionFilters = {};
if (!!dimensionValuesQuery[6] && dimensionValuesQuery[6] !== '[]') {
const tempFilters = dimensionValuesQuery[6].replace(jsonVariable, '"$$$1"');
try {
newQuery.dimensionFilters = JSON.parse(tempFilters);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${dimensionValuesQuery[6]}`);
}
}
return newQuery;
}
const ebsVolumeIdsQuery = rawQuery.match(/^ebs_volume_ids\(([^,]+?),\s?([^,]+?)\)/);
if (ebsVolumeIdsQuery) {
newQuery.queryType = VariableQueryType.EBSVolumeIDs;
newQuery.region = ebsVolumeIdsQuery[1];
newQuery.instanceID = ebsVolumeIdsQuery[2];
return newQuery;
}
const ec2InstanceAttributeQuery = rawQuery.match(/^ec2_instance_attribute\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/);
if (ec2InstanceAttributeQuery) {
newQuery.queryType = VariableQueryType.EC2InstanceAttributes;
newQuery.region = ec2InstanceAttributeQuery[1];
newQuery.attributeName = ec2InstanceAttributeQuery[2];
if (ec2InstanceAttributeQuery[3] && ec2InstanceAttributeQuery[3] !== '[]') {
try {
newQuery.ec2Filters = migrateMultiFilters(ec2InstanceAttributeQuery[3]);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${ec2InstanceAttributeQuery[3]}`);
}
}
return newQuery;
}
const resourceARNsQuery = rawQuery.match(/^resource_arns\(([^,]+?),\s?([^,]+?),\s?(.+?)\)/);
if (resourceARNsQuery) {
newQuery.queryType = VariableQueryType.ResourceArns;
newQuery.region = resourceARNsQuery[1];
newQuery.resourceType = resourceARNsQuery[2];
if (resourceARNsQuery[3] && resourceARNsQuery[3] !== '[]') {
try {
newQuery.tags = migrateMultiFilters(resourceARNsQuery[3]);
} catch {
throw new Error(`unable to migrate poorly formed filters: ${resourceARNsQuery[3]}`);
}
}
return newQuery;
}
const statsQuery = rawQuery.match(/^statistics\(\)/);
if (statsQuery) {
newQuery.queryType = VariableQueryType.Statistics;
return newQuery;
}
throw new Error('unable to parse old variable query');
}