ConfigEditor.tsx 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. import React, { PureComponent } from 'react';
  2. import { SelectableValue } from '@grafana/data';
  3. import { DataSourcePluginOptionsEditorProps } from '@grafana/ui';
  4. import { MonitorConfig } from './components/MonitorConfig';
  5. import { AnalyticsConfig } from './components/AnalyticsConfig';
  6. import { TemplateSrv } from 'app/features/templating/template_srv';
  7. import { getBackendSrv, BackendSrv } from 'app/core/services/backend_srv';
  8. import AzureMonitorDatasource from './azure_monitor/azure_monitor_datasource';
  9. import AzureLogAnalyticsDatasource from './azure_log_analytics/azure_log_analytics_datasource';
  10. import { InsightsConfig } from './components/InsightsConfig';
  11. export type Props = DataSourcePluginOptionsEditorProps<any>;
  12. export interface State {
  13. config: any;
  14. subscriptions: SelectableValue[];
  15. logAnalyticsSubscriptions: SelectableValue[];
  16. logAnalyticsWorkspaces: SelectableValue[];
  17. }
  18. export class ConfigEditor extends PureComponent<Props, State> {
  19. constructor(props: Props) {
  20. super(props);
  21. const { options } = this.props;
  22. this.state = {
  23. config: ConfigEditor.keyFill(options),
  24. subscriptions: [],
  25. logAnalyticsSubscriptions: [],
  26. logAnalyticsWorkspaces: [],
  27. };
  28. this.backendSrv = getBackendSrv();
  29. this.templateSrv = new TemplateSrv();
  30. if (options.id) {
  31. this.state.config.url = '/api/datasources/proxy/' + options.id;
  32. this.init();
  33. }
  34. this.updateDatasource(this.state.config);
  35. }
  36. static getDerivedStateFromProps(props: Props, state: State) {
  37. return {
  38. ...state,
  39. config: ConfigEditor.keyFill(props.options),
  40. };
  41. }
  42. static keyFill = (options: any) => {
  43. options.jsonData.cloudName = options.jsonData.cloudName || 'azuremonitor';
  44. if (!options.jsonData.hasOwnProperty('azureLogAnalyticsSameAs')) {
  45. options.jsonData.azureLogAnalyticsSameAs = true;
  46. }
  47. if (!options.hasOwnProperty('editorSecureJsonData')) {
  48. options.editorSecureJsonData = {
  49. clientSecret: '',
  50. logAnalyticsClientSecret: '',
  51. appInsightsApiKey: '',
  52. };
  53. }
  54. if (!options.hasOwnProperty('editorJsonData')) {
  55. options.editorJsonData = {
  56. clientId: options.jsonData.clientId || '',
  57. tenantId: options.jsonData.tenantId || '',
  58. subscriptionId: options.jsonData.subscriptionId || '',
  59. logAnalyticsClientId: options.jsonData.logAnalyticsClientId || '',
  60. logAnalyticsDefaultWorkspace: options.jsonData.logAnalyticsDefaultWorkspace || '',
  61. logAnalyticsTenantId: options.jsonData.logAnalyticsTenantId || '',
  62. logAnalyticsSubscriptionId: options.jsonData.logAnalyticsSubscriptionId || '',
  63. appInsightsAppId: options.jsonData.appInsightsAppId || '',
  64. };
  65. }
  66. if (!options.hasOwnProperty('secureJsonFields')) {
  67. options.secureJsonFields = {
  68. clientSecret: false,
  69. logAnalyticsClientSecret: false,
  70. appInsightsApiKey: false,
  71. };
  72. }
  73. return options;
  74. };
  75. backendSrv: BackendSrv = null;
  76. templateSrv: TemplateSrv = null;
  77. init = async () => {
  78. await this.getSubscriptions();
  79. if (!this.state.config.jsonData.azureLogAnalyticsSameAs) {
  80. await this.getLogAnalyticsSubscriptions();
  81. }
  82. };
  83. updateDatasource = async (config: any) => {
  84. for (const j in config.jsonData) {
  85. if (config.jsonData[j].length === 0) {
  86. delete config.jsonData[j];
  87. }
  88. }
  89. for (const k in config.secureJsonData) {
  90. if (config.secureJsonData[k].length === 0) {
  91. delete config.secureJsonData[k];
  92. }
  93. }
  94. for (const m in config.editorJsonData) {
  95. if (!config.hasOwnProperty('jsonData')) {
  96. config.jsonData = {};
  97. }
  98. if (config.editorJsonData[m].length === 0) {
  99. if (config.hasOwnProperty('jsonData') && config.jsonData.hasOwnProperty(m)) {
  100. delete config.jsonData[m];
  101. }
  102. } else {
  103. config.jsonData[m] = config.editorJsonData[m];
  104. }
  105. }
  106. for (const l in config.editorSecureJsonData) {
  107. if (!config.hasOwnProperty('secureJsonData')) {
  108. config.secureJsonData = {};
  109. }
  110. if (config.editorSecureJsonData[l].length === 0) {
  111. if (config.hasOwnProperty('secureJsonData') && config.secureJsonData.hasOwnProperty(l)) {
  112. delete config.secureJsonData[l];
  113. }
  114. } else {
  115. config.secureJsonData[l] = config.editorSecureJsonData[l];
  116. }
  117. }
  118. this.props.onOptionsChange({
  119. ...config,
  120. });
  121. };
  122. hasNecessaryCredentials = () => {
  123. if (!this.state.config.secureJsonFields.clientSecret && !this.state.config.editorSecureJsonData.clientSecret) {
  124. return false;
  125. }
  126. if (!this.state.config.jsonData.clientId || !this.state.config.jsonData.tenantId) {
  127. return false;
  128. }
  129. return true;
  130. };
  131. logAnalyticsHasNecessaryCredentials = () => {
  132. if (
  133. !this.state.config.secureJsonFields.logAnalyticsClientSecret &&
  134. !this.state.config.editorSecureJsonData.logAnalyticsClientSecret
  135. ) {
  136. return false;
  137. }
  138. if (!this.state.config.jsonData.logAnalyticsClientId || !this.state.config.jsonData.logAnalyticsTenantId) {
  139. return false;
  140. }
  141. return true;
  142. };
  143. onConfigUpdate = (config: any) => {
  144. this.updateDatasource(config);
  145. };
  146. onLoadSubscriptions = async (type?: string) => {
  147. await this.backendSrv.put(`/api/datasources/${this.state.config.id}`, this.state.config).then(() => {
  148. this.updateDatasource({
  149. ...this.state.config,
  150. version: this.state.config.version + 1,
  151. });
  152. });
  153. if (type && type === 'workspacesloganalytics') {
  154. this.getLogAnalyticsSubscriptions();
  155. } else {
  156. this.getSubscriptions();
  157. }
  158. };
  159. getSubscriptions = async () => {
  160. if (!this.hasNecessaryCredentials()) {
  161. return;
  162. }
  163. const azureMonitorDatasource = new AzureMonitorDatasource(this.state.config, this.backendSrv, this.templateSrv);
  164. let subscriptions = (await azureMonitorDatasource.getSubscriptions()) || [];
  165. subscriptions = subscriptions.map((subscription: any) => {
  166. return {
  167. value: subscription.value,
  168. label: subscription.text,
  169. };
  170. });
  171. if (subscriptions && subscriptions.length > 0) {
  172. this.setState({ subscriptions });
  173. this.state.config.editorJsonData.subscriptionId =
  174. this.state.config.editorJsonData.subscriptionId || subscriptions[0].value;
  175. }
  176. if (this.state.config.editorJsonData.subscriptionId && this.state.config.jsonData.azureLogAnalyticsSameAs) {
  177. await this.getWorkspaces();
  178. }
  179. };
  180. getLogAnalyticsSubscriptions = async () => {
  181. if (!this.logAnalyticsHasNecessaryCredentials()) {
  182. return;
  183. }
  184. const azureMonitorDatasource = new AzureMonitorDatasource(this.state.config, this.backendSrv, this.templateSrv);
  185. let logAnalyticsSubscriptions = (await azureMonitorDatasource.getSubscriptions('workspacesloganalytics')) || [];
  186. logAnalyticsSubscriptions = logAnalyticsSubscriptions.map((subscription: any) => {
  187. return {
  188. value: subscription.value,
  189. label: subscription.text,
  190. };
  191. });
  192. if (logAnalyticsSubscriptions && logAnalyticsSubscriptions.length > 0) {
  193. this.setState({ logAnalyticsSubscriptions });
  194. this.state.config.editorJsonData.logAnalyticsSubscriptionId =
  195. this.state.config.editorJsonData.logAnalyticsSubscriptionId || logAnalyticsSubscriptions[0].value;
  196. }
  197. if (this.state.config.editorJsonData.logAnalyticsSubscriptionId) {
  198. await this.getWorkspaces();
  199. }
  200. };
  201. getWorkspaces = async () => {
  202. const sameAs =
  203. this.state.config.jsonData.azureLogAnalyticsSameAs && this.state.config.editorJsonData.subscriptionId;
  204. if (!sameAs && !this.state.config.editorJsonData.logAnalyticsSubscriptionId) {
  205. return;
  206. }
  207. const azureLogAnalyticsDatasource = new AzureLogAnalyticsDatasource(
  208. this.state.config,
  209. this.backendSrv,
  210. this.templateSrv
  211. );
  212. let logAnalyticsWorkspaces = await azureLogAnalyticsDatasource.getWorkspaces(
  213. sameAs
  214. ? this.state.config.editorJsonData.subscriptionId
  215. : this.state.config.editorJsonData.logAnalyticsSubscriptionId
  216. );
  217. logAnalyticsWorkspaces = logAnalyticsWorkspaces.map((workspace: any) => {
  218. return {
  219. value: workspace.value,
  220. label: workspace.text,
  221. };
  222. });
  223. if (logAnalyticsWorkspaces.length > 0) {
  224. this.setState({ logAnalyticsWorkspaces });
  225. this.state.config.editorJsonData.logAnalyticsDefaultWorkspace =
  226. this.state.config.editorJsonData.logAnalyticsDefaultWorkspace || logAnalyticsWorkspaces[0].value;
  227. }
  228. };
  229. render() {
  230. const { config, subscriptions, logAnalyticsSubscriptions, logAnalyticsWorkspaces } = this.state;
  231. return (
  232. <>
  233. <MonitorConfig
  234. datasourceConfig={config}
  235. subscriptions={subscriptions}
  236. onLoadSubscriptions={this.onLoadSubscriptions}
  237. onDatasourceUpdate={this.onConfigUpdate}
  238. />
  239. <AnalyticsConfig
  240. datasourceConfig={config}
  241. logAnalyticsWorkspaces={logAnalyticsWorkspaces}
  242. logAnalyticsSubscriptions={logAnalyticsSubscriptions}
  243. onLoadSubscriptions={this.onLoadSubscriptions}
  244. onDatasourceUpdate={this.onConfigUpdate}
  245. onLoadWorkspaces={this.getWorkspaces}
  246. />
  247. <InsightsConfig datasourceConfig={config} onDatasourceUpdate={this.onConfigUpdate} />
  248. </>
  249. );
  250. }
  251. }
  252. export default ConfigEditor;