You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by qi...@apache.org on 2023/05/12 11:21:51 UTC
[skywalking-grafana-plugins] branch main updated: feat: add username and password (#8)
This is an automated email from the ASF dual-hosted git repository.
qiuxiafan pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-grafana-plugins.git
The following commit(s) were added to refs/heads/main by this push:
new 71b60de feat: add username and password (#8)
71b60de is described below
commit 71b60dee410ca37bc6c6a949b08b321d774071b6
Author: Fine0830 <fa...@gmail.com>
AuthorDate: Fri May 12 19:21:45 2023 +0800
feat: add username and password (#8)
---
src/components/ConfigEditor.tsx | 101 ++++++++++++++++++++++++----------------
src/constant.ts | 4 ++
src/datasource.ts | 18 +++++--
src/plugin.json | 8 +++-
src/types.ts | 4 ++
5 files changed, 89 insertions(+), 46 deletions(-)
diff --git a/src/components/ConfigEditor.tsx b/src/components/ConfigEditor.tsx
index cecc99d..153d556 100644
--- a/src/components/ConfigEditor.tsx
+++ b/src/components/ConfigEditor.tsx
@@ -15,61 +15,70 @@
* limitations under the License.
*/
import React, { ChangeEvent } from 'react';
-import { InlineField, Input, SecretInput } from '@grafana/ui';
+import { InlineField, Input, Select } from '@grafana/ui';
import { DataSourcePluginOptionsEditorProps } from '@grafana/data';
-import { MyDataSourceOptions, MySecureJsonData } from '../types';
+import { MyDataSourceOptions } from '../types';
+import {AuthenticationType} from "../constant";
interface Props extends DataSourcePluginOptionsEditorProps<MyDataSourceOptions> {}
export function ConfigEditor(props: Props) {
- const { onOptionsChange, options } = props;
- const onPathChange = (event: ChangeEvent<HTMLInputElement>) => {
+ const { options } = props;
+
+ const onURLChange = (event: ChangeEvent<HTMLInputElement>) => {
+ const { onOptionsChange, options } = props;
const jsonData = {
...options.jsonData,
- path: event.target.value,
+ URL: event.target.value,
};
onOptionsChange({ ...options, jsonData });
};
- // Secure field (only sent to the backend)
- const onAPIKeyChange = (event: ChangeEvent<HTMLInputElement>) => {
- onOptionsChange({
- ...options,
- secureJsonData: {
- apiKey: event.target.value,
- },
- });
+ const onTypeChange = (v: any) => {
+ const { onOptionsChange, options } = props;
+ const jsonData = {
+ ...options.jsonData,
+ type: v.value,
+ username: v.value === AuthenticationType[1].value ? '' : options.jsonData.username,
+ password: v.value === AuthenticationType[1].value ? '' : options.jsonData.password,
+ };
+ onOptionsChange({ ...options, jsonData });
};
- const onResetAPIKey = () => {
- onOptionsChange({
+ const onUserChange = (event: ChangeEvent<HTMLInputElement>) => {
+ const { onOptionsChange, options } = props;
+ const basicAuth = btoa(encodeURI(`${event.target.value}:${options.jsonData.password}`));
+ const jsonData = {
+ ...options.jsonData,
+ username: event.target.value,
+ basicAuth,
+ };
+
+ onOptionsChange({
...options,
- secureJsonFields: {
- ...options.secureJsonFields,
- apiKey: false,
- },
- secureJsonData: {
- ...options.secureJsonData,
- apiKey: '',
- },
+ jsonData,
});
};
- const onURLChange = (event: ChangeEvent<HTMLInputElement>) => {
+ const onPasswordChange = (event: ChangeEvent<HTMLInputElement>) => {
const { onOptionsChange, options } = props;
+ const basicAuth = btoa(encodeURI(`${options.jsonData.username}:${event.target.value}`));
const jsonData = {
...options.jsonData,
- URL: event.target.value,
+ password: event.target.value,
+ basicAuth,
};
- onOptionsChange({ ...options, jsonData });
+ onOptionsChange({
+ ...options,
+ jsonData,
+ });
};
- const { jsonData, secureJsonFields } = options;
- const secureJsonData = (options.secureJsonData || {}) as MySecureJsonData;
+ const { jsonData } = options;
return (
<div className="gf-form-group">
- <InlineField label="URL" labelWidth={12}>
+ <InlineField label="URL" labelWidth={18}>
<Input
onChange={onURLChange}
value={jsonData.URL || ''}
@@ -77,24 +86,36 @@ export function ConfigEditor(props: Props) {
width={40}
/>
</InlineField>
- <InlineField label="Path" labelWidth={12}>
+ <InlineField label="Authentication Type" labelWidth={18} >
+ <Select
+ options={AuthenticationType}
+ value={jsonData.type || AuthenticationType[1].value}
+ onChange={onTypeChange}
+ width={40}
+ placeholder="Choose an authentication type"
+ menuPlacement="bottom"
+ />
+ </InlineField>
+ {jsonData.type === AuthenticationType[0].value &&
+ <div>
+ <InlineField label="User Name" labelWidth={18}>
<Input
- onChange={onPathChange}
- value={jsonData.path || ''}
- placeholder="json field returned to frontend"
+ onChange={onUserChange}
+ value={jsonData.username || ''}
+ placeholder="Please input username"
width={40}
/>
</InlineField>
- <InlineField label="API Key" labelWidth={12}>
- <SecretInput
- isConfigured={(secureJsonFields && secureJsonFields.apiKey) as boolean}
- value={secureJsonData.apiKey || ''}
- placeholder="secure json field (backend only)"
+ <InlineField label="Password" labelWidth={18}>
+ <Input
+ onChange={onPasswordChange}
+ value={jsonData.password || ''}
+ placeholder="Please input password"
width={40}
- onReset={onResetAPIKey}
- onChange={onAPIKeyChange}
+ type="password"
/>
</InlineField>
+ </div>}
</div>
);
}
diff --git a/src/constant.ts b/src/constant.ts
index 79f1658..6731f8e 100644
--- a/src/constant.ts
+++ b/src/constant.ts
@@ -66,3 +66,7 @@ export const EdgeMetrics = `{
"unit": "cpm",
"type": "CLINET"
}`
+export const AuthenticationType = [
+ {label: 'BASIC', value: 'BASIC', text: 'BASIC'},
+ {label: 'None', value: 'NONE', text: 'None'},
+]
diff --git a/src/datasource.ts b/src/datasource.ts
index f7835cb..afba49d 100644
--- a/src/datasource.ts
+++ b/src/datasource.ts
@@ -41,14 +41,18 @@ import {
Node,
Recordable
} from './types';
-import { Fragments, RoutePath, TimeType, Calculations } from "./constant";
+import { Fragments, RoutePath, TimeType, Calculations, AuthenticationType } from "./constant";
export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
URL: string;
+ type: string;
+ basicAuth: string
constructor(instanceSettings: DataSourceInstanceSettings<MyDataSourceOptions>) {
super(instanceSettings);
// proxy url
this.URL = instanceSettings.url || '';
+ this.type = instanceSettings.jsonData.type || '';
+ this.basicAuth = instanceSettings.jsonData.basicAuth || '';
dayjs.extend(utc)
dayjs.extend(timezone)
}
@@ -156,10 +160,14 @@ export class DataSource extends DataSourceApi<MyQuery, MyDataSourceOptions> {
async doRequest(params?: Recordable) {
// Do the request on proxy; the server will replace url + routePath with the url
// defined in plugin.json
- const result = getBackendSrv().post(`${this.URL}${RoutePath}`, params, { headers: {
- 'Content-Type': 'application/json',
- 'Authorization': 'Basic c2t5d2Fsa2luZzpza3l3YWxraW5n',
- } });
+ let headers = {};
+
+ if (this.type === AuthenticationType[0].value) {
+ headers = {
+ 'Authorization': `Basic ${this.basicAuth}`, // 'Basic c2t5d2Fsa2luZzpza3l3YWxraW5n'
+ };
+ }
+ const result = getBackendSrv().post(`${this.URL}${RoutePath}`, params, {headers});
return result;
}
diff --git a/src/plugin.json b/src/plugin.json
index 5f3c761..7e29163 100644
--- a/src/plugin.json
+++ b/src/plugin.json
@@ -26,7 +26,13 @@
"routes": [
{
"path": "graphql",
- "url": "{{ .JsonData.URL }}"
+ "url": "{{ .JsonData.URL }}",
+ "headers": [
+ {
+ "name": "Content-Type",
+ "content": "application/json"
+ }
+ ]
}
]
}
diff --git a/src/types.ts b/src/types.ts
index c85b38a..87601e9 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -33,6 +33,10 @@ export const DEFAULT_QUERY: Partial<MyQuery> = {};
export interface MyDataSourceOptions extends DataSourceJsonData {
path?: string;
URL: string;
+ username: string;
+ password: string;
+ basicAuth: string;
+ type: string;
}
/**