variables.ts 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. import { from, Observable } from 'rxjs';
  2. import { map } from 'rxjs/operators';
  3. import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data';
  4. import { VariableQueryEditor } from './components/VariableQueryEditor/VariableQueryEditor';
  5. import { CloudWatchDatasource } from './datasource';
  6. import { migrateVariableQuery } from './migrations/variableQueryMigrations';
  7. import { VariableQuery, VariableQueryType } from './types';
  8. export class CloudWatchVariableSupport extends CustomVariableSupport<CloudWatchDatasource, VariableQuery> {
  9. private readonly datasource: CloudWatchDatasource;
  10. constructor(datasource: CloudWatchDatasource) {
  11. super();
  12. this.datasource = datasource;
  13. this.query = this.query.bind(this);
  14. }
  15. editor = VariableQueryEditor;
  16. query(request: DataQueryRequest<VariableQuery>): Observable<DataQueryResponse> {
  17. const queryObj = migrateVariableQuery(request.targets[0]);
  18. return from(this.execute(queryObj)).pipe(map((data) => ({ data })));
  19. }
  20. async execute(query: VariableQuery) {
  21. try {
  22. switch (query.queryType) {
  23. case VariableQueryType.Regions:
  24. return this.handleRegionsQuery();
  25. case VariableQueryType.Namespaces:
  26. return this.handleNamespacesQuery();
  27. case VariableQueryType.Metrics:
  28. return this.handleMetricsQuery(query);
  29. case VariableQueryType.DimensionKeys:
  30. return this.handleDimensionKeysQuery(query);
  31. case VariableQueryType.DimensionValues:
  32. return this.handleDimensionValuesQuery(query);
  33. case VariableQueryType.EBSVolumeIDs:
  34. return this.handleEbsVolumeIdsQuery(query);
  35. case VariableQueryType.EC2InstanceAttributes:
  36. return this.handleEc2InstanceAttributeQuery(query);
  37. case VariableQueryType.ResourceArns:
  38. return this.handleResourceARNsQuery(query);
  39. case VariableQueryType.Statistics:
  40. return this.handleStatisticsQuery();
  41. }
  42. } catch (error) {
  43. console.error(`Could not run CloudWatchMetricFindQuery ${query}`, error);
  44. return [];
  45. }
  46. }
  47. async handleRegionsQuery() {
  48. const regions = await this.datasource.getRegions();
  49. return regions.map((s: { label: string; value: string }) => ({
  50. text: s.label,
  51. value: s.value,
  52. expandable: true,
  53. }));
  54. }
  55. async handleNamespacesQuery() {
  56. const namespaces = await this.datasource.getNamespaces();
  57. return namespaces.map((s: { label: string; value: string }) => ({
  58. text: s.label,
  59. value: s.value,
  60. expandable: true,
  61. }));
  62. }
  63. async handleMetricsQuery({ namespace, region }: VariableQuery) {
  64. const metrics = await this.datasource.getMetrics(namespace, region);
  65. return metrics.map((s: { label: string; value: string }) => ({
  66. text: s.label,
  67. value: s.value,
  68. expandable: true,
  69. }));
  70. }
  71. async handleDimensionKeysQuery({ namespace, region }: VariableQuery) {
  72. const keys = await this.datasource.getDimensionKeys(namespace, region);
  73. return keys.map((s: { label: string; value: string }) => ({
  74. text: s.label,
  75. value: s.value,
  76. expandable: true,
  77. }));
  78. }
  79. async handleDimensionValuesQuery({ namespace, region, dimensionKey, metricName, dimensionFilters }: VariableQuery) {
  80. if (!dimensionKey || !metricName) {
  81. return [];
  82. }
  83. const keys = await this.datasource.getDimensionValues(
  84. region,
  85. namespace,
  86. metricName,
  87. dimensionKey,
  88. dimensionFilters ?? {}
  89. );
  90. return keys.map((s: { label: string; value: string }) => ({
  91. text: s.label,
  92. value: s.value,
  93. expandable: true,
  94. }));
  95. }
  96. async handleEbsVolumeIdsQuery({ region, instanceID }: VariableQuery) {
  97. if (!instanceID) {
  98. return [];
  99. }
  100. const ids = await this.datasource.getEbsVolumeIds(region, instanceID);
  101. return ids.map((s: { label: string; value: string }) => ({
  102. text: s.label,
  103. value: s.value,
  104. expandable: true,
  105. }));
  106. }
  107. async handleEc2InstanceAttributeQuery({ region, attributeName, ec2Filters }: VariableQuery) {
  108. if (!attributeName) {
  109. return [];
  110. }
  111. const values = await this.datasource.getEc2InstanceAttribute(region, attributeName, ec2Filters ?? {});
  112. return values.map((s: { label: string; value: string }) => ({
  113. text: s.label,
  114. value: s.value,
  115. expandable: true,
  116. }));
  117. }
  118. async handleResourceARNsQuery({ region, resourceType, tags }: VariableQuery) {
  119. if (!resourceType) {
  120. return [];
  121. }
  122. const keys = await this.datasource.getResourceARNs(region, resourceType, tags ?? {});
  123. return keys.map((s: { label: string; value: string }) => ({
  124. text: s.label,
  125. value: s.value,
  126. expandable: true,
  127. }));
  128. }
  129. async handleStatisticsQuery() {
  130. return this.datasource.standardStatistics.map((s: string) => ({
  131. text: s,
  132. value: s,
  133. expandable: true,
  134. }));
  135. }
  136. }