datasource.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. import { DataSourceInstanceSettings, DataSourceJsonData } from '@grafana/data';
  2. import { getDataSourceSrv } from '@grafana/runtime';
  3. import { contextSrv } from 'app/core/services/context_srv';
  4. import { AlertManagerDataSourceJsonData, AlertManagerImplementation } from 'app/plugins/datasource/alertmanager/types';
  5. import { AccessControlAction } from 'app/types';
  6. import { RulesSource } from 'app/types/unified-alerting';
  7. import { instancesPermissions, notificationsPermissions } from './access-control';
  8. import { getAllDataSources } from './config';
  9. export const GRAFANA_RULES_SOURCE_NAME = 'grafana';
  10. export const GRAFANA_DATASOURCE_NAME = '-- Grafana --';
  11. export enum DataSourceType {
  12. Alertmanager = 'alertmanager',
  13. Loki = 'loki',
  14. Prometheus = 'prometheus',
  15. }
  16. export interface AlertManagerDataSource {
  17. name: string;
  18. imgUrl: string;
  19. meta?: DataSourceInstanceSettings['meta'];
  20. }
  21. export const RulesDataSourceTypes: string[] = [DataSourceType.Loki, DataSourceType.Prometheus];
  22. export function getRulesDataSources() {
  23. if (!contextSrv.hasPermission(AccessControlAction.AlertingRuleExternalRead)) {
  24. return [];
  25. }
  26. return getAllDataSources()
  27. .filter((ds) => RulesDataSourceTypes.includes(ds.type) && ds.jsonData.manageAlerts !== false)
  28. .sort((a, b) => a.name.localeCompare(b.name));
  29. }
  30. export function getRulesDataSource(rulesSourceName: string) {
  31. return getRulesDataSources().find((x) => x.name === rulesSourceName);
  32. }
  33. export function getAlertManagerDataSources() {
  34. return getAllDataSources()
  35. .filter((ds) => ds.type === DataSourceType.Alertmanager)
  36. .sort((a, b) => a.name.localeCompare(b.name));
  37. }
  38. const grafanaAlertManagerDataSource: AlertManagerDataSource = {
  39. name: GRAFANA_RULES_SOURCE_NAME,
  40. imgUrl: 'public/img/grafana_icon.svg',
  41. };
  42. // Used only as a fallback for Alert Group plugin
  43. export function getAllAlertManagerDataSources(): AlertManagerDataSource[] {
  44. return [
  45. grafanaAlertManagerDataSource,
  46. ...getAlertManagerDataSources().map<AlertManagerDataSource>((ds) => ({
  47. name: ds.name,
  48. displayName: ds.name,
  49. imgUrl: ds.meta.info.logos.small,
  50. meta: ds.meta,
  51. })),
  52. ];
  53. }
  54. export function getAlertManagerDataSourcesByPermission(
  55. permission: 'instance' | 'notification'
  56. ): AlertManagerDataSource[] {
  57. const availableDataSources: AlertManagerDataSource[] = [];
  58. const permissions = {
  59. instance: instancesPermissions.read,
  60. notification: notificationsPermissions.read,
  61. };
  62. if (contextSrv.hasPermission(permissions[permission].grafana)) {
  63. availableDataSources.push(grafanaAlertManagerDataSource);
  64. }
  65. if (contextSrv.hasPermission(permissions[permission].external)) {
  66. const cloudSources = getAlertManagerDataSources().map<AlertManagerDataSource>((ds) => ({
  67. name: ds.name,
  68. displayName: ds.name,
  69. imgUrl: ds.meta.info.logos.small,
  70. meta: ds.meta,
  71. }));
  72. availableDataSources.push(...cloudSources);
  73. }
  74. return availableDataSources;
  75. }
  76. export function getLotexDataSourceByName(dataSourceName: string): DataSourceInstanceSettings {
  77. const dataSource = getDataSourceByName(dataSourceName);
  78. if (!dataSource) {
  79. throw new Error(`Data source ${dataSourceName} not found`);
  80. }
  81. if (dataSource.type !== DataSourceType.Loki && dataSource.type !== DataSourceType.Prometheus) {
  82. throw new Error(`Unexpected data source type ${dataSource.type}`);
  83. }
  84. return dataSource;
  85. }
  86. export function getAllRulesSourceNames(): string[] {
  87. const availableRulesSources: string[] = getRulesDataSources().map((r) => r.name);
  88. if (contextSrv.hasPermission(AccessControlAction.AlertingRuleRead)) {
  89. availableRulesSources.push(GRAFANA_RULES_SOURCE_NAME);
  90. }
  91. return availableRulesSources;
  92. }
  93. export function getAllRulesSources(): RulesSource[] {
  94. const availableRulesSources: RulesSource[] = getRulesDataSources();
  95. if (contextSrv.hasPermission(AccessControlAction.AlertingRuleRead)) {
  96. availableRulesSources.push(GRAFANA_RULES_SOURCE_NAME);
  97. }
  98. return availableRulesSources;
  99. }
  100. export function getRulesSourceName(rulesSource: RulesSource): string {
  101. return isCloudRulesSource(rulesSource) ? rulesSource.name : rulesSource;
  102. }
  103. export function isCloudRulesSource(rulesSource: RulesSource | string): rulesSource is DataSourceInstanceSettings {
  104. return rulesSource !== GRAFANA_RULES_SOURCE_NAME;
  105. }
  106. export function isVanillaPrometheusAlertManagerDataSource(name: string): boolean {
  107. return (
  108. name !== GRAFANA_RULES_SOURCE_NAME &&
  109. (getDataSourceByName(name)?.jsonData as AlertManagerDataSourceJsonData)?.implementation ===
  110. AlertManagerImplementation.prometheus
  111. );
  112. }
  113. export function isGrafanaRulesSource(
  114. rulesSource: RulesSource | string
  115. ): rulesSource is typeof GRAFANA_RULES_SOURCE_NAME {
  116. return rulesSource === GRAFANA_RULES_SOURCE_NAME;
  117. }
  118. export function getDataSourceByName(name: string): DataSourceInstanceSettings<DataSourceJsonData> | undefined {
  119. return getAllDataSources().find((source) => source.name === name);
  120. }
  121. export function getRulesSourceByName(name: string): RulesSource | undefined {
  122. if (name === GRAFANA_RULES_SOURCE_NAME) {
  123. return GRAFANA_RULES_SOURCE_NAME;
  124. }
  125. return getDataSourceByName(name);
  126. }
  127. export function getDatasourceAPIId(dataSourceName: string) {
  128. if (dataSourceName === GRAFANA_RULES_SOURCE_NAME) {
  129. return GRAFANA_RULES_SOURCE_NAME;
  130. }
  131. const ds = getDataSourceByName(dataSourceName);
  132. if (!ds) {
  133. throw new Error(`Datasource "${dataSourceName}" not found`);
  134. }
  135. return String(ds.id);
  136. }
  137. export function getDatasourceAPIUid(dataSourceName: string) {
  138. if (dataSourceName === GRAFANA_RULES_SOURCE_NAME) {
  139. return GRAFANA_RULES_SOURCE_NAME;
  140. }
  141. const ds = getDataSourceByName(dataSourceName);
  142. if (!ds) {
  143. throw new Error(`Datasource "${dataSourceName}" not found`);
  144. }
  145. return ds.uid;
  146. }
  147. export function getFirstCompatibleDataSource(): DataSourceInstanceSettings<DataSourceJsonData> | undefined {
  148. return getRulesDataSources()[0];
  149. }
  150. export function getDefaultOrFirstCompatibleDataSource(): DataSourceInstanceSettings<DataSourceJsonData> | undefined {
  151. const defaultDataSource = getDataSourceSrv().getInstanceSettings('default');
  152. const defaultIsCompatible = defaultDataSource?.meta.alerting ?? false;
  153. return defaultIsCompatible ? defaultDataSource : getFirstCompatibleDataSource();
  154. }