exporter.ts 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. ///<reference path="../../../headers/common.d.ts" />
  2. import config from 'app/core/config';
  3. import _ from 'lodash';
  4. import {DynamicDashboardSrv} from '../dynamic_dashboard_srv';
  5. export class DashboardExporter {
  6. constructor(private datasourceSrv) {
  7. }
  8. makeExportable(dashboard) {
  9. var dynSrv = new DynamicDashboardSrv();
  10. // clean up repeated rows and panels,
  11. // this is done on the live real dashboard instance, not on a clone
  12. // so we need to undo this
  13. // this is pretty hacky and needs to be changed
  14. dynSrv.init(dashboard);
  15. dynSrv.process({cleanUpOnly: true});
  16. var saveModel = dashboard.getSaveModelClone();
  17. saveModel.id = null;
  18. // undo repeat cleanup
  19. dynSrv.process();
  20. var inputs = [];
  21. var requires = {};
  22. var datasources = {};
  23. var promises = [];
  24. var variableLookup: any = {};
  25. for (let variable of saveModel.templating.list) {
  26. variableLookup[variable.name] = variable;
  27. }
  28. var templateizeDatasourceUsage = obj => {
  29. // ignore data source properties that contain a variable
  30. if (obj.datasource && obj.datasource.indexOf('$') === 0) {
  31. if (variableLookup[obj.datasource.substring(1)]){
  32. return;
  33. }
  34. }
  35. promises.push(this.datasourceSrv.get(obj.datasource).then(ds => {
  36. if (ds.meta.builtIn) {
  37. return;
  38. }
  39. var refName = 'DS_' + ds.name.replace(' ', '_').toUpperCase();
  40. datasources[refName] = {
  41. name: refName,
  42. label: ds.name,
  43. description: '',
  44. type: 'datasource',
  45. pluginId: ds.meta.id,
  46. pluginName: ds.meta.name,
  47. };
  48. obj.datasource = '${' + refName +'}';
  49. requires['datasource' + ds.meta.id] = {
  50. type: 'datasource',
  51. id: ds.meta.id,
  52. name: ds.meta.name,
  53. version: ds.meta.info.version || "1.0.0",
  54. };
  55. }));
  56. };
  57. // check up panel data sources
  58. for (let row of saveModel.rows) {
  59. for (let panel of row.panels) {
  60. if (panel.datasource !== undefined) {
  61. templateizeDatasourceUsage(panel);
  62. }
  63. if (panel.targets) {
  64. for (let target of panel.targets) {
  65. if (target.datasource !== undefined) {
  66. templateizeDatasourceUsage(target);
  67. }
  68. }
  69. }
  70. var panelDef = config.panels[panel.type];
  71. if (panelDef) {
  72. requires['panel' + panelDef.id] = {
  73. type: 'panel',
  74. id: panelDef.id,
  75. name: panelDef.name,
  76. version: panelDef.info.version,
  77. };
  78. }
  79. }
  80. }
  81. // templatize template vars
  82. for (let variable of saveModel.templating.list) {
  83. if (variable.type === 'query') {
  84. templateizeDatasourceUsage(variable);
  85. variable.options = [];
  86. variable.current = {};
  87. variable.refresh = variable.refresh > 0 ? variable.refresh : 1;
  88. }
  89. }
  90. // templatize annotations vars
  91. for (let annotationDef of saveModel.annotations.list) {
  92. templateizeDatasourceUsage(annotationDef);
  93. }
  94. // add grafana version
  95. requires['grafana'] = {
  96. type: 'grafana',
  97. id: 'grafana',
  98. name: 'Grafana',
  99. version: config.buildInfo.version
  100. };
  101. return Promise.all(promises).then(() => {
  102. _.each(datasources, (value, key) => {
  103. inputs.push(value);
  104. });
  105. // templatize constants
  106. for (let variable of saveModel.templating.list) {
  107. if (variable.type === 'constant') {
  108. var refName = 'VAR_' + variable.name.replace(' ', '_').toUpperCase();
  109. inputs.push({
  110. name: refName,
  111. type: 'constant',
  112. label: variable.label || variable.name,
  113. value: variable.current.value,
  114. description: '',
  115. });
  116. // update current and option
  117. variable.query = '${' + refName + '}';
  118. variable.options[0] = variable.current = {
  119. value: variable.query,
  120. text: variable.query,
  121. };
  122. }
  123. }
  124. // make inputs and requires a top thing
  125. var newObj = {};
  126. newObj["__inputs"] = inputs;
  127. newObj["__requires"] = _.sortBy(requires, ['id']);
  128. _.defaults(newObj, saveModel);
  129. return newObj;
  130. }).catch(err => {
  131. console.log('Export failed:', err);
  132. return {
  133. error: err
  134. };
  135. });
  136. }
  137. }