2022-04-04 09:39:31 -05:00
|
|
|
import { from, Observable } from 'rxjs';
|
|
|
|
import { map } from 'rxjs/operators';
|
2022-04-22 08:33:13 -05:00
|
|
|
|
2022-04-04 09:39:31 -05:00
|
|
|
import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data';
|
|
|
|
|
2022-09-20 00:50:54 -05:00
|
|
|
import { CloudWatchAPI } from './api';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor';
|
2022-04-04 09:39:31 -05:00
|
|
|
import { CloudWatchDatasource } from './datasource';
|
2022-05-03 06:52:17 -05:00
|
|
|
import { migrateVariableQuery } from './migrations/variableQueryMigrations';
|
2022-09-20 00:50:54 -05:00
|
|
|
import { CloudWatchLogsQueryRunner } from './query-runner/CloudWatchLogsQueryRunner';
|
|
|
|
import { standardStatistics } from './standardStatistics';
|
2022-04-22 08:33:13 -05:00
|
|
|
import { VariableQuery, VariableQueryType } from './types';
|
2022-04-04 09:39:31 -05:00
|
|
|
|
|
|
|
export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchDatasource, VariableQuery> {
|
2022-09-20 00:50:54 -05:00
|
|
|
constructor(private readonly api: CloudWatchAPI, private readonly logsQueryRunner: CloudWatchLogsQueryRunner) {
|
2022-04-04 09:39:31 -05:00
|
|
|
super();
|
|
|
|
this.query = this.query.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
editor = VariableQueryEditor;
|
|
|
|
|
|
|
|
query(request: DataQueryRequest<VariableQuery>): Observable<DataQueryResponse> {
|
|
|
|
const queryObj = migrateVariableQuery(request.targets[0]);
|
|
|
|
return from(this.execute(queryObj)).pipe(map((data) => ({ data })));
|
|
|
|
}
|
|
|
|
|
|
|
|
async execute(query: VariableQuery) {
|
|
|
|
try {
|
|
|
|
switch (query.queryType) {
|
|
|
|
case VariableQueryType.Regions:
|
|
|
|
return this.handleRegionsQuery();
|
|
|
|
case VariableQueryType.Namespaces:
|
|
|
|
return this.handleNamespacesQuery();
|
|
|
|
case VariableQueryType.Metrics:
|
|
|
|
return this.handleMetricsQuery(query);
|
|
|
|
case VariableQueryType.DimensionKeys:
|
|
|
|
return this.handleDimensionKeysQuery(query);
|
|
|
|
case VariableQueryType.DimensionValues:
|
|
|
|
return this.handleDimensionValuesQuery(query);
|
|
|
|
case VariableQueryType.EBSVolumeIDs:
|
|
|
|
return this.handleEbsVolumeIdsQuery(query);
|
|
|
|
case VariableQueryType.EC2InstanceAttributes:
|
|
|
|
return this.handleEc2InstanceAttributeQuery(query);
|
|
|
|
case VariableQueryType.ResourceArns:
|
|
|
|
return this.handleResourceARNsQuery(query);
|
|
|
|
case VariableQueryType.Statistics:
|
|
|
|
return this.handleStatisticsQuery();
|
2022-06-03 02:26:57 -05:00
|
|
|
case VariableQueryType.LogGroups:
|
|
|
|
return this.handleLogGroupsQuery(query);
|
2022-04-04 09:39:31 -05:00
|
|
|
}
|
|
|
|
} catch (error) {
|
|
|
|
console.error(`Could not run CloudWatchMetricFindQuery ${query}`, error);
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-06-03 02:26:57 -05:00
|
|
|
async handleLogGroupsQuery({ region, logGroupPrefix }: VariableQuery) {
|
2022-09-20 00:50:54 -05:00
|
|
|
const logGroups: string[] = await this.logsQueryRunner.describeAllLogGroups({
|
2022-09-19 01:50:41 -05:00
|
|
|
region,
|
|
|
|
logGroupNamePrefix: logGroupPrefix,
|
|
|
|
});
|
2022-06-03 02:26:57 -05:00
|
|
|
return logGroups.map((s) => ({
|
|
|
|
text: s,
|
|
|
|
value: s,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
2022-04-04 09:39:31 -05:00
|
|
|
async handleRegionsQuery() {
|
2022-09-20 00:50:54 -05:00
|
|
|
const regions = await this.api.getRegions();
|
2022-09-21 03:55:54 -05:00
|
|
|
return regions.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleNamespacesQuery() {
|
2022-09-20 00:50:54 -05:00
|
|
|
const namespaces = await this.api.getNamespaces();
|
2022-09-21 03:55:54 -05:00
|
|
|
return namespaces.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleMetricsQuery({ namespace, region }: VariableQuery) {
|
2022-09-20 00:50:54 -05:00
|
|
|
const metrics = await this.api.getMetrics(namespace, region);
|
2022-09-21 03:55:54 -05:00
|
|
|
return metrics.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleDimensionKeysQuery({ namespace, region }: VariableQuery) {
|
2022-09-20 00:50:54 -05:00
|
|
|
const keys = await this.api.getDimensionKeys(namespace, region);
|
2022-09-21 03:55:54 -05:00
|
|
|
return keys.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleDimensionValuesQuery({ namespace, region, dimensionKey, metricName, dimensionFilters }: VariableQuery) {
|
|
|
|
if (!dimensionKey || !metricName) {
|
|
|
|
return [];
|
|
|
|
}
|
2022-09-20 00:50:54 -05:00
|
|
|
const keys = await this.api.getDimensionValues(region, namespace, metricName, dimensionKey, dimensionFilters ?? {});
|
2022-09-21 03:55:54 -05:00
|
|
|
return keys.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleEbsVolumeIdsQuery({ region, instanceID }: VariableQuery) {
|
|
|
|
if (!instanceID) {
|
|
|
|
return [];
|
|
|
|
}
|
2022-09-20 00:50:54 -05:00
|
|
|
const ids = await this.api.getEbsVolumeIds(region, instanceID);
|
2022-09-21 03:55:54 -05:00
|
|
|
return ids.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleEc2InstanceAttributeQuery({ region, attributeName, ec2Filters }: VariableQuery) {
|
|
|
|
if (!attributeName) {
|
|
|
|
return [];
|
|
|
|
}
|
2022-09-20 00:50:54 -05:00
|
|
|
const values = await this.api.getEc2InstanceAttribute(region, attributeName, ec2Filters ?? {});
|
2022-09-21 03:55:54 -05:00
|
|
|
return values.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleResourceARNsQuery({ region, resourceType, tags }: VariableQuery) {
|
|
|
|
if (!resourceType) {
|
|
|
|
return [];
|
|
|
|
}
|
2022-09-20 00:50:54 -05:00
|
|
|
const keys = await this.api.getResourceARNs(region, resourceType, tags ?? {});
|
2022-09-21 03:55:54 -05:00
|
|
|
return keys.map((s) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s.label,
|
|
|
|
value: s.value,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
async handleStatisticsQuery() {
|
2022-09-20 00:50:54 -05:00
|
|
|
return standardStatistics.map((s: string) => ({
|
2022-04-04 09:39:31 -05:00
|
|
|
text: s,
|
|
|
|
value: s,
|
|
|
|
expandable: true,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|