From f0fe98fa5790683887a34c126d74ec3d3c701f8d Mon Sep 17 00:00:00 2001 From: rozetko Date: Thu, 19 Jan 2023 23:49:19 +0300 Subject: [PATCH 1/2] auto api key configuration --- .../PluginConfigPage/PluginConfigPage.tsx | 56 ++++++++++--------- .../parts/ConfigurationForm/index.tsx | 4 +- src/plugin_state.ts | 21 ++++--- src/types.ts | 2 +- 4 files changed, 42 insertions(+), 41 deletions(-) diff --git a/src/components/PluginConfigPage/PluginConfigPage.tsx b/src/components/PluginConfigPage/PluginConfigPage.tsx index d352dfa..19dc254 100644 --- a/src/components/PluginConfigPage/PluginConfigPage.tsx +++ b/src/components/PluginConfigPage/PluginConfigPage.tsx @@ -1,15 +1,14 @@ -import React, { FC, useCallback, useEffect, useState } from 'react'; - -import { Legend, LoadingPlaceholder } from '@grafana/ui'; -import { useLocation } from 'react-router-dom'; - -// import logo from '../../img/logo.svg'; import PluginState, { PluginConnectedStatusResponse } from '../../plugin_state'; import ConfigurationForm from './parts/ConfigurationForm'; import RemoveCurrentConfigurationButton from './parts/RemoveCurrentConfigurationButton'; import StatusMessageBlock from './parts/StatusMessageBlock'; -import { DataExporterPluginConfigPageProps } from 'types'; +import { DataExporterPluginConfigPageProps } from '../../types'; + +import { Legend, LoadingPlaceholder } from '@grafana/ui'; +import { useLocation } from 'react-router-dom'; + +import React, { FC, useCallback, useEffect, useState } from 'react'; const PLUGIN_CONFIGURED_QUERY_PARAM = 'pluginConfigured'; const PLUGIN_CONFIGURED_QUERY_PARAM_TRUTHY_VALUE = 'true'; @@ -71,24 +70,30 @@ export const PluginConfigPage: FC = ({ const resetQueryParams = useCallback(() => removePluginConfiguredQueryParams(pluginIsEnabled), [pluginIsEnabled]); - const checkConnection = useCallback(async () => { - setCheckingIfPluginIsConnected(true); - setPluginConnectionCheckError(null); - if (!pluginMetaDataExporterApiUrl) { - setCheckingIfPluginIsConnected(false); - return; - } - const pluginConnectionResponse = await PluginState.checkIfPluginIsConnected(pluginMetaDataExporterApiUrl); + const checkConnection = useCallback( + async (grafanaDataExporterUrl?: string) => { + setCheckingIfPluginIsConnected(true); + setPluginConnectionCheckError(null); - if (typeof pluginConnectionResponse === 'string') { - setPluginConnectionCheckError(pluginConnectionResponse); - } else { - setPluginIsConnected(pluginConnectionResponse); - reloadPageWithPluginConfiguredQueryParams(pluginConnectionResponse, true); - } + const backendUrl = grafanaDataExporterUrl || pluginMetaDataExporterApiUrl; - setCheckingIfPluginIsConnected(false); - }, [pluginMetaDataExporterApiUrl]); + if (!backendUrl) { + setCheckingIfPluginIsConnected(false); + return; + } + const pluginConnectionResponse = await PluginState.checkIfPluginIsConnected(backendUrl); + + if (typeof pluginConnectionResponse === 'string') { + setPluginConnectionCheckError(pluginConnectionResponse); + } else { + setPluginIsConnected(pluginConnectionResponse); + reloadPageWithPluginConfiguredQueryParams(pluginConnectionResponse, true); + } + + setCheckingIfPluginIsConnected(false); + }, + [pluginMetaDataExporterApiUrl] + ); useEffect(resetQueryParams, [resetQueryParams]); @@ -166,10 +171,7 @@ export const PluginConfigPage: FC = ({ Configure DataExporter {pluginIsConnected ? ( <> -

- Plugin is connected! Continue to DataExporter by clicking the{' '} - {/* DataExporter Logo icon over there 👈 */} -

+

Plugin is connected! You can now go to a dashboard and add the DataExporter panel there.

) : ( diff --git a/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx b/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx index 7ed24e4..7e499d2 100644 --- a/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx +++ b/src/components/PluginConfigPage/parts/ConfigurationForm/index.tsx @@ -16,7 +16,7 @@ import { isEmpty } from 'lodash-es'; const cx = cn.bind(styles); type Props = { - onSuccessfulSetup: () => void; + onSuccessfulSetup: (grafanaDataExporterUrl: string) => void; defaultDataExporterApiUrl: string; }; @@ -68,7 +68,7 @@ const ConfigurationForm: FC = ({ onSuccessfulSetup, defaultDataExporterAp const errorMsg = await PluginState.installPlugin(dataExporterApiUrl); if (!errorMsg) { - onSuccessfulSetup(); + onSuccessfulSetup(dataExporterApiUrl); } else { setSetupErrorMsg(errorMsg); setFormLoading(false); diff --git a/src/plugin_state.ts b/src/plugin_state.ts index 3aa8344..eccf9d5 100644 --- a/src/plugin_state.ts +++ b/src/plugin_state.ts @@ -14,10 +14,7 @@ export type UpdateGrafanaPluginSettingsProps = { secureJsonData?: Partial; }; -type InstallPluginResponse = Pick< - DataExporterPluginMetaSecureJSONData, - 'grafanaToken' -> & { +type InstallPluginResponse = Pick & { dataExporterAPIResponse: DataExporterAPIResponse; }; @@ -125,13 +122,14 @@ class PluginState { static timeout = (pollCount: number) => new Promise((resolve) => setTimeout(resolve, 10 * 2 ** pollCount)); static connectBackend = async (): Promise> => { - // TODO: try to disable success alerts from Grafana API - const { key: grafanaToken } = await this.createGrafanaToken(); - await this.updateGrafanaPluginSettings({ secureJsonData: { grafanaToken } }); + const { key: apiToken } = await this.createGrafanaToken(); + await this.updateGrafanaPluginSettings({ secureJsonData: { apiToken } }); + // TODO: display alert on error const dataExporterAPIResponse = await queryApi(`/connect`, { method: 'POST', + data: { apiToken, url: window.location.toString() }, }); - return { grafanaToken, dataExporterAPIResponse }; + return { apiToken, dataExporterAPIResponse }; }; static installPlugin = async (dataExporterApiUrl: string): Promise => { @@ -158,14 +156,14 @@ class PluginState { // Step 3. reprovision the Grafana plugin settings, storing information that we get back from DataExporter's backend try { - const { grafanaToken } = pluginInstallationDataExporterResponse; + const { apiToken } = pluginInstallationDataExporterResponse; await this.updateGrafanaPluginSettings({ jsonData: { dataExporterApiUrl, }, secureJsonData: { - grafanaToken, + apiToken, }, }); } catch (e) { @@ -181,6 +179,7 @@ class PluginState { try { const resp = await queryApi(`/status`, { method: 'GET', + params: { url: window.location.toString() }, }); // TODO: check if the server version is compatible with the plugin @@ -204,7 +203,7 @@ class PluginState { dataExporterApiUrl: null, }; const secureJsonData: Required = { - grafanaToken: null, + apiToken: null, }; return this.updateGrafanaPluginSettings({ jsonData, secureJsonData }, false); diff --git a/src/types.ts b/src/types.ts index a648e0c..126f81c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -5,7 +5,7 @@ export type DataExporterPluginMetaJSONData = { }; export type DataExporterPluginMetaSecureJSONData = { - grafanaToken: string | null; + apiToken: string | null; }; export type AppRootProps = BaseAppRootProps; -- 2.34.1 From 45c2e23dbc4da8ad10ba9b8cf792be2baf5068e6 Mon Sep 17 00:00:00 2001 From: rozetko Date: Fri, 20 Jan 2023 00:00:26 +0300 Subject: [PATCH 2/2] hotfix --- src/plugin_state.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugin_state.ts b/src/plugin_state.ts index eccf9d5..0d7fae6 100644 --- a/src/plugin_state.ts +++ b/src/plugin_state.ts @@ -177,12 +177,13 @@ class PluginState { dataExporterApiUrl: string ): Promise => { try { - const resp = await queryApi(`/status`, { + const resp = await queryApi(`/connect`, { method: 'GET', params: { url: window.location.toString() }, }); // TODO: check if the server version is compatible with the plugin + // TODO: remove configuration if backend says that api key doesn't work if (resp.version) { return resp; } else { -- 2.34.1