@grafana/data#PluginMeta TypeScript Examples

The following examples show how to use @grafana/data#PluginMeta. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: config.ts    From grafana-starter-app with Apache License 2.0 6 votes vote down vote up
/** @ngInject */
  constructor($scope: any, $injector: any) {
    this.appEditCtrl.setPostUpdateHook(this.postUpdate.bind(this));

    // Make sure it has a JSON Data spot
    if (!this.appModel) {
      this.appModel = {} as PluginMeta;
    }

    // Required until we get the types sorted on appModel :(
    const appModel = this.appModel as any;
    if (!appModel.jsonData) {
      appModel.jsonData = {};
    }

    console.log('ExampleConfigCtrl', this);
  }
Example #2
Source File: pluginValidation.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getPluginJson = (path: string): PluginMeta => {
  let pluginJson;
  try {
    pluginJson = require(path);
  } catch (e) {
    throw new Error('Unable to find: ' + path);
  }

  validatePluginJson(pluginJson);

  return pluginJson as PluginMeta;
}
Example #3
Source File: settings.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function getEndToEndSettings() {
  if (env) {
    return env;
  }

  let f = path.resolve(process.cwd(), 'ci', 'dist', 'plugin.json');
  if (!fs.existsSync(f)) {
    f = path.resolve(process.cwd(), 'dist', 'plugin.json');
    if (!fs.existsSync(f)) {
      f = path.resolve(process.cwd(), 'src', 'plugin.json');
    }
  }
  const outputFolder = path.resolve(process.cwd(), 'e2e-results');
  if (!fs.existsSync(outputFolder)) {
    fs.mkdirSync(outputFolder, { recursive: true });
  }
  constants.screenShotsTruthDir = path.resolve(process.cwd(), 'e2e', 'truth');
  constants.screenShotsOutputDir = outputFolder;

  return (env = {
    plugin: require(f) as PluginMeta,
    outputFolder,
  });
}
Example #4
Source File: reducers.test.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
mockPlugin = () =>
  ({
    defaultNavUrl: 'defaultNavUrl',
    enabled: true,
    hasUpdate: true,
    id: 'id',
    info: {} as PluginMetaInfo,
    latestVersion: 'latestVersion',
    name: 'name',
    pinned: true,
    type: PluginType.datasource,
    module: 'path/to/module',
  } as PluginMeta)
Example #5
Source File: PluginListPage.test.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
setup = (propOverrides?: object) => {
  const props: Props = {
    navModel: {
      main: {
        text: 'Configuration',
      },
      node: {
        text: 'Plugins',
      },
    } as NavModel,
    plugins: [] as PluginMeta[],
    searchQuery: '',
    setPluginsSearchQuery: mockToolkitActionCreator(setPluginsSearchQuery),
    setPluginsLayoutMode: mockToolkitActionCreator(setPluginsLayoutMode),
    layoutMode: LayoutModes.Grid,
    loadPlugins: jest.fn(),
    hasFetched: false,
  };

  Object.assign(props, propOverrides);

  return shallow(<PluginListPage {...props} />);
}
Example #6
Source File: PluginPage.tsx    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
renderVersionInfo(meta: PluginMeta) {
    if (!meta.info.version) {
      return null;
    }

    return (
      <section className="page-sidebar-section">
        <h4>Version</h4>
        <span>{meta.info.version}</span>
        {meta.hasUpdate && (
          <div>
            <Tooltip content={meta.latestVersion} theme="info" placement="top">
              <a href="#" onClick={this.showUpdateInfo}>
                Update Available!
              </a>
            </Tooltip>
          </div>
        )}
      </section>
    );
  }
Example #7
Source File: PluginSettingsCache.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function getPluginSettings(pluginId: string): Promise<PluginMeta> {
  const v = pluginInfoCache[pluginId];
  if (v) {
    return Promise.resolve(v);
  }
  return getBackendSrv()
    .get(`/api/plugins/${pluginId}/settings`)
    .then((settings: any) => {
      pluginInfoCache[pluginId] = settings;
      return settings;
    })
    .catch((err: any) => {
      // err.isHandled = true;
      return Promise.reject('Unknown Plugin');
    });
}
Example #8
Source File: pluginMocks.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function getMockPlugin(overrides?: Partial<PluginMeta>): PluginMeta {
  const defaults: PluginMeta = {
    defaultNavUrl: 'some/url',
    enabled: false,
    hasUpdate: false,
    id: '1',
    info: {
      author: {
        name: 'Grafana Labs',
        url: 'url/to/GrafanaLabs',
      },
      description: 'pretty decent plugin',
      links: [{ name: 'project', url: 'one link' }],
      logos: { small: 'small/logo', large: 'large/logo' },
      screenshots: [{ path: `screenshot`, name: 'test' }],
      updated: '2018-09-26',
      version: '1',
    },
    latestVersion: '1',
    name: 'pretty cool plugin 1',
    baseUrl: 'path/to/plugin',
    pinned: false,
    type: PluginType.panel,
    module: 'path/to/module',
  };

  return defaultsDeep(overrides || {}, defaults) as PluginMeta;
}
Example #9
Source File: pluginMocks.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
getMockPlugins = (amount: number): PluginMeta[] => {
  const plugins = [];

  for (let i = 0; i <= amount; i++) {
    plugins.push({
      defaultNavUrl: 'some/url',
      enabled: false,
      hasUpdate: false,
      id: `${i}`,
      info: {
        author: {
          name: 'Grafana Labs',
          url: 'url/to/GrafanaLabs',
        },
        description: 'pretty decent plugin',
        links: ['one link'],
        logos: { small: 'small/logo', large: 'large/logo' },
        screenshots: [{ path: `screenshot/${i}` }],
        updated: '2018-09-26',
        version: '1',
      },
      latestVersion: `1.${i}`,
      name: `pretty cool plugin-${i}`,
      pinned: false,
      state: '',
      type: '',
      module: {},
    });
  }

  return plugins as any;
}
Example #10
Source File: plugin_loader.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
export function importAppPlugin(meta: PluginMeta): Promise<AppPlugin> {
  return importPluginModule(meta.module).then(pluginExports => {
    const plugin = pluginExports.plugin ? (pluginExports.plugin as AppPlugin) : new AppPlugin();
    plugin.init(meta);
    plugin.meta = meta;
    plugin.setComponentsFromLegacyExports(pluginExports);
    return plugin;
  });
}
Example #11
Source File: plugin_page_ctrl.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
initPage(app: PluginMeta) {
    this.appModel = app;
    this.page = _.find(app.includes, { slug: this.$routeParams.slug });

    if (!this.page) {
      this.$rootScope.appEvent(AppEvents.alertError, ['App Page Not Found']);
      this.navModel = this.navModelSrv.getNotFoundNav();
      return;
    }
    if (app.type !== 'app' || !app.enabled) {
      this.$rootScope.appEvent(AppEvents.alertError, ['Application Not Enabled']);
      this.navModel = this.navModelSrv.getNotFoundNav();
      return;
    }

    const pluginNav = this.navModelSrv.getNav('plugin-page-' + app.id);

    this.navModel = {
      main: {
        img: app.info.logos.large,
        subTitle: app.name,
        url: '',
        text: this.page.name,
        breadcrumbs: [{ title: app.name, url: pluginNav.main.url }],
      },
    };
  }
Example #12
Source File: reducers.ts    From grafana-chinese with Apache License 2.0 6 votes vote down vote up
pluginsSlice = createSlice({
  name: 'plugins',
  initialState,
  reducers: {
    pluginsLoaded: (state, action: PayloadAction<PluginMeta[]>) => {
      state.hasFetched = true;
      state.plugins = action.payload;
    },
    setPluginsSearchQuery: (state, action: PayloadAction<string>) => {
      state.searchQuery = action.payload;
    },
    setPluginsLayoutMode: (state, action: PayloadAction<LayoutMode>) => {
      state.layoutMode = action.payload;
    },
    pluginDashboardsLoad: (state, action: PayloadAction<undefined>) => {
      state.isLoadingPluginDashboards = true;
      state.dashboards = [];
    },
    pluginDashboardsLoaded: (state, action: PayloadAction<PluginDashboard[]>) => {
      state.isLoadingPluginDashboards = false;
      state.dashboards = action.payload;
    },
    panelPluginLoaded: (state, action: PayloadAction<PanelPlugin>) => {
      state.panels[action.payload.meta!.id] = action.payload;
    },
  },
})
Example #13
Source File: datasource.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
async importQueries(queries: LokiQuery[], originMeta: PluginMeta): Promise<LokiQuery[]> {
    return this.languageProvider.importQueries(queries, originMeta.id);
  }
Example #14
Source File: InputDatasource.test.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
describe('InputDatasource', () => {
  const data = readCSV('a,b,c\n1,2,3\n4,5,6');
  const instanceSettings: DataSourceInstanceSettings<InputOptions> = {
    id: 1,
    type: 'x',
    name: 'xxx',
    meta: {} as PluginMeta,
    jsonData: {
      data,
    },
  };

  describe('when querying', () => {
    test('should return the saved data with a query', () => {
      const ds = new InputDatasource(instanceSettings);
      const options = getQueryOptions<InputQuery>({
        targets: [{ refId: 'Z' }],
      });

      return ds.query(options).then(rsp => {
        expect(rsp.data.length).toBe(1);

        const series: DataFrame = rsp.data[0];
        expect(series.refId).toBe('Z');
        expect(series.fields[0].values).toEqual(data[0].fields[0].values);
      });
    });
  });

  test('DataFrame descriptions', () => {
    expect(describeDataFrame([])).toEqual('');
    expect(describeDataFrame(null)).toEqual('');
    expect(
      describeDataFrame([
        new MutableDataFrame({
          name: 'x',
          fields: [{ name: 'a' }],
        }),
      ])
    ).toEqual('1 Fields, 0 Rows');
  });
});
Example #15
Source File: AppConfigWrapper.tsx    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
model: PluginMeta;
Example #16
Source File: plugin.ci.ts    From grafana-chinese with Apache License 2.0 5 votes vote down vote up
testPluginRunner: TaskRunner<PluginCIOptions> = async ({}) => {
  const start = Date.now();
  const workDir = getJobFolder();
  const results: TestResultsInfo = { job, passed: 0, failed: 0, screenshots: [] };
  const args = {
    withCredentials: true,
    baseURL: process.env.BASE_URL || 'http://localhost:3000/',
    responseType: 'json',
    auth: {
      username: 'admin',
      password: 'admin',
    },
  };

  const settings = getEndToEndSettings();
  await execa('rimraf', [settings.outputFolder]);
  fs.mkdirSync(settings.outputFolder);

  const tempDir = path.resolve(process.cwd(), 'e2e-temp');
  await execa('rimraf', [tempDir]);
  fs.mkdirSync(tempDir);

  try {
    const axios = require('axios');
    const frontendSettings = await axios.get('api/frontend/settings', args);
    results.grafana = frontendSettings.data.buildInfo;

    console.log('Grafana: ' + JSON.stringify(results.grafana, null, 2));

    const loadedMetaRsp = await axios.get(`api/plugins/${settings.plugin.id}/settings`, args);
    const loadedMeta: PluginMeta = loadedMetaRsp.data;
    console.log('Plugin Info: ' + JSON.stringify(loadedMeta, null, 2));
    if (loadedMeta.info.build) {
      const currentHash = settings.plugin.info.build!.hash;
      console.log('Check version: ', settings.plugin.info.build);
      if (loadedMeta.info.build.hash !== currentHash) {
        console.warn(`Testing wrong plugin version.  Expected: ${currentHash}, found: ${loadedMeta.info.build.hash}`);
        throw new Error('Wrong plugin version');
      }
    }

    if (!fs.existsSync('e2e-temp')) {
      fs.mkdirSync(tempDir);
    }

    await execa('cp', [
      'node_modules/@grafana/toolkit/src/plugins/e2e/commonPluginTests.ts',
      path.resolve(tempDir, 'common.test.ts'),
    ]);

    await runEndToEndTests(settings.outputFolder, results);
  } catch (err) {
    results.error = err;
    console.log('Test Error', err);
  }
  await execa('rimraf', [tempDir]);

  // Now copy everything to work folder
  await execa('cp', ['-rv', settings.outputFolder + '/.', workDir]);
  results.screenshots = findImagesInFolder(workDir);

  const f = path.resolve(workDir, 'results.json');
  fs.writeFile(f, JSON.stringify(results, null, 2), err => {
    if (err) {
      throw new Error('Error saving: ' + f);
    }
  });

  writeJobStats(start, workDir);
}
Example #17
Source File: config.ts    From grafana-starter-app with Apache License 2.0 5 votes vote down vote up
appModel?: PluginMeta;
Example #18
Source File: datasource_srv.test.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
describe('datasource_srv', () => {
  const _datasourceSrv = new DatasourceSrv({} as any, {} as any, templateSrv);

  describe('when loading external datasources', () => {
    beforeEach(() => {
      config.datasources = {
        buildInDs: {
          id: 1,
          type: 'b',
          name: 'buildIn',
          meta: { builtIn: true } as DataSourcePluginMeta,
          jsonData: {},
        },
        nonBuildIn: {
          id: 2,
          type: 'e',
          name: 'external1',
          meta: { builtIn: false } as DataSourcePluginMeta,
          jsonData: {},
        },
        nonExplore: {
          id: 3,
          type: 'e2',
          name: 'external2',
          meta: {} as PluginMeta,
          jsonData: {},
        },
      };
    });

    it('should return list of explore sources', () => {
      const externalSources = _datasourceSrv.getExternal();
      expect(externalSources.length).toBe(2);
      expect(externalSources[0].name).toBe('external1');
      expect(externalSources[1].name).toBe('external2');
    });
  });

  describe('when loading metric sources', () => {
    let metricSources: any;
    const unsortedDatasources = {
      mmm: {
        type: 'test-db',
        meta: { metrics: { m: 1 } },
      },
      '--Grafana--': {
        type: 'grafana',
        meta: { builtIn: true, metrics: { m: 1 }, id: 'grafana' },
      },
      '--Mixed--': {
        type: 'test-db',
        meta: { builtIn: true, metrics: { m: 1 }, id: 'mixed' },
      },
      ZZZ: {
        type: 'test-db',
        meta: { metrics: { m: 1 } },
      },
      aaa: {
        type: 'test-db',
        meta: { metrics: { m: 1 } },
      },
      BBB: {
        type: 'test-db',
        meta: { metrics: { m: 1 } },
      },
    };
    beforeEach(() => {
      config.datasources = unsortedDatasources as any;
      metricSources = _datasourceSrv.getMetricSources({});
      config.defaultDatasource = 'BBB';
    });

    it('should return a list of sources sorted case insensitively with builtin sources last', () => {
      expect(metricSources[1].name).toBe('aaa');
      expect(metricSources[2].name).toBe('BBB');
      expect(metricSources[3].name).toBe('mmm');
      expect(metricSources[4].name).toBe('ZZZ');
      expect(metricSources[5].name).toBe('--Grafana--');
      expect(metricSources[6].name).toBe('--Mixed--');
    });

    it('should set default data source', () => {
      expect(metricSources[3].name).toBe('default');
      expect(metricSources[3].sort).toBe('BBB');
    });

    it('should set default inject the variable datasources', () => {
      expect(metricSources[0].name).toBe('$datasource');
      expect(metricSources[0].sort).toBe('$datasource');
    });
  });
});
Example #19
Source File: getAlertingValidationMessage.test.ts    From grafana-chinese with Apache License 2.0 4 votes vote down vote up
describe('getAlertingValidationMessage', () => {
  describe('when called with some targets containing template variables', () => {
    it('then it should return false', async () => {
      let call = 0;
      const datasource: DataSourceApi = ({
        meta: ({ alerting: true } as any) as PluginMeta,
        targetContainsTemplate: () => {
          if (call === 0) {
            call++;
            return true;
          }
          return false;
        },
        name: 'some name',
      } as any) as DataSourceApi;
      const getMock = jest.fn().mockResolvedValue(datasource);
      const datasourceSrv: DataSourceSrv = {
        get: getMock,
      };
      const targets: ElasticsearchQuery[] = [
        { refId: 'A', query: '@hostname:$hostname', isLogsQuery: false },
        { refId: 'B', query: '@instance:instance', isLogsQuery: false },
      ];
      const transformations: DataTransformerConfig[] = [];

      const result = await getAlertingValidationMessage(transformations, targets, datasourceSrv, datasource.name);

      expect(result).toBe('');
      expect(getMock).toHaveBeenCalledTimes(2);
      expect(getMock).toHaveBeenCalledWith(datasource.name);
    });
  });

  describe('when called with some targets using a datasource that does not support alerting', () => {
    it('then it should return false', async () => {
      const alertingDatasource: DataSourceApi = ({
        meta: ({ alerting: true } as any) as PluginMeta,
        targetContainsTemplate: () => false,
        name: 'alertingDatasource',
      } as any) as DataSourceApi;
      const datasource: DataSourceApi = ({
        meta: ({ alerting: false } as any) as PluginMeta,
        targetContainsTemplate: () => false,
        name: 'datasource',
      } as any) as DataSourceApi;

      const datasourceSrv: DataSourceSrv = {
        get: (name: string) => {
          if (name === datasource.name) {
            return Promise.resolve(datasource);
          }

          return Promise.resolve(alertingDatasource);
        },
      };
      const targets: any[] = [
        { refId: 'A', query: 'some query', datasource: 'alertingDatasource' },
        { refId: 'B', query: 'some query', datasource: 'datasource' },
      ];
      const transformations: DataTransformerConfig[] = [];

      const result = await getAlertingValidationMessage(transformations, targets, datasourceSrv, datasource.name);

      expect(result).toBe('');
    });
  });

  describe('when called with all targets containing template variables', () => {
    it('then it should return false', async () => {
      const datasource: DataSourceApi = ({
        meta: ({ alerting: true } as any) as PluginMeta,
        targetContainsTemplate: () => true,
        name: 'some name',
      } as any) as DataSourceApi;
      const getMock = jest.fn().mockResolvedValue(datasource);
      const datasourceSrv: DataSourceSrv = {
        get: getMock,
      };
      const targets: ElasticsearchQuery[] = [
        { refId: 'A', query: '@hostname:$hostname', isLogsQuery: false },
        { refId: 'B', query: '@instance:$instance', isLogsQuery: false },
      ];
      const transformations: DataTransformerConfig[] = [];

      const result = await getAlertingValidationMessage(transformations, targets, datasourceSrv, datasource.name);

      expect(result).toBe('Template variables are not supported in alert queries');
      expect(getMock).toHaveBeenCalledTimes(2);
      expect(getMock).toHaveBeenCalledWith(datasource.name);
    });
  });

  describe('when called with all targets using a datasource that does not support alerting', () => {
    it('then it should return false', async () => {
      const datasource: DataSourceApi = ({
        meta: ({ alerting: false } as any) as PluginMeta,
        targetContainsTemplate: () => false,
        name: 'some name',
      } as any) as DataSourceApi;
      const getMock = jest.fn().mockResolvedValue(datasource);
      const datasourceSrv: DataSourceSrv = {
        get: getMock,
      };
      const targets: ElasticsearchQuery[] = [
        { refId: 'A', query: '@hostname:hostname', isLogsQuery: false },
        { refId: 'B', query: '@instance:instance', isLogsQuery: false },
      ];
      const transformations: DataTransformerConfig[] = [];

      const result = await getAlertingValidationMessage(transformations, targets, datasourceSrv, datasource.name);

      expect(result).toBe('The datasource does not support alerting queries');
      expect(getMock).toHaveBeenCalledTimes(2);
      expect(getMock).toHaveBeenCalledWith(datasource.name);
    });
  });

  describe('when called with transformations', () => {
    it('then it should return false', async () => {
      const datasource: DataSourceApi = ({
        meta: ({ alerting: true } as any) as PluginMeta,
        targetContainsTemplate: () => false,
        name: 'some name',
      } as any) as DataSourceApi;
      const getMock = jest.fn().mockResolvedValue(datasource);
      const datasourceSrv: DataSourceSrv = {
        get: getMock,
      };
      const targets: ElasticsearchQuery[] = [
        { refId: 'A', query: '@hostname:hostname', isLogsQuery: false },
        { refId: 'B', query: '@instance:instance', isLogsQuery: false },
      ];
      const transformations: DataTransformerConfig[] = [{ id: 'A', options: null }];

      const result = await getAlertingValidationMessage(transformations, targets, datasourceSrv, datasource.name);

      expect(result).toBe('Transformations are not supported in alert queries');
      expect(getMock).toHaveBeenCalledTimes(0);
    });
  });
});