From 22d31136ee83dc6fc509897ca6b84530b448aefd Mon Sep 17 00:00:00 2001 From: Erik Sundell Date: Tue, 30 Mar 2021 13:25:32 +0200 Subject: [PATCH] SigV4: Add support EC2 IAM role auth and possibility to toggle auth providers (#32444) (#32488) * wip: consume aws-sdk config in auth http settings * fix typings * use sdk regions * use latest version of grafana/aws-sdk * use newest sdk * add comment * bump sdk * fix yarn lock file * fix storybook issue * upgrade aws-sdk. also use it in grafana ui * remove not used config * add aws-sdk as an external dep for grafana in the grafana ui rollup Co-authored-by: Will Browne (cherry picked from commit f0d6f132aeb9ef5242c844f6164d85ee4037d3c5) --- go.mod | 2 +- go.sum | 2 + package.json | 2 +- packages/grafana-ui/package.json | 1 + packages/grafana-ui/rollup.config.ts | 1 + .../DataSourceSettings/SigV4AuthSettings.tsx | 293 ++++-------------- yarn.lock | 139 +-------- 7 files changed, 77 insertions(+), 363 deletions(-) diff --git a/go.mod b/go.mod index 22158e72c16..b7b5d8f89f3 100644 --- a/go.mod +++ b/go.mod @@ -43,7 +43,7 @@ require ( github.com/google/go-cmp v0.5.4 github.com/google/uuid v1.2.0 github.com/gosimple/slug v1.9.0 - github.com/grafana/grafana-aws-sdk v0.2.0 + github.com/grafana/grafana-aws-sdk v0.3.0 github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 github.com/grafana/grafana-plugin-sdk-go v0.88.0 github.com/grafana/loki v1.6.2-0.20201026154740-6978ee5d7387 diff --git a/go.sum b/go.sum index 57124938836..8cb8fc24f60 100644 --- a/go.sum +++ b/go.sum @@ -723,6 +723,8 @@ github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036 h1:GplhUk6Xes5J github.com/grafana/go-mssqldb v0.0.0-20210326084033-d0ce3c521036/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/grafana/grafana-aws-sdk v0.2.0 h1:UTBBYwye+ad5YUIlwN7TGxLdz1wXN3Ezhl0pseDGRVA= github.com/grafana/grafana-aws-sdk v0.2.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U= +github.com/grafana/grafana-aws-sdk v0.3.0 h1:UT3rIXQFeAh0OaRJT7dUQojYaSjbI9RwOtMacaerv8I= +github.com/grafana/grafana-aws-sdk v0.3.0/go.mod h1:+pPo5U+pX0zWimR7YBc7ASeSQfbRkcTyQYqMiAj7G5U= github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4 h1:SPdxCL9BChFTlyi0Khv64vdCW4TMna8+sxL7+Chx+Ag= github.com/grafana/grafana-plugin-model v0.0.0-20190930120109-1fc953a61fb4/go.mod h1:nc0XxBzjeGcrMltCDw269LoWF9S8ibhgxolCdA1R8To= github.com/grafana/grafana-plugin-sdk-go v0.79.0/go.mod h1:NvxLzGkVhnoBKwzkst6CFfpMFKwAdIUZ1q8ssuLeF60= diff --git a/package.json b/package.json index e7d7ca195c3..bf1d6f0df43 100644 --- a/package.json +++ b/package.json @@ -200,7 +200,7 @@ }, "dependencies": { "@emotion/core": "10.0.27", - "@grafana/aws-sdk": "0.0.24", + "@grafana/aws-sdk": "0.0.3", "@grafana/slate-react": "0.22.9-grafana", "@popperjs/core": "2.5.4", "@reduxjs/toolkit": "1.5.0", diff --git a/packages/grafana-ui/package.json b/packages/grafana-ui/package.json index 4ff137a826f..f36fc10c05e 100644 --- a/packages/grafana-ui/package.json +++ b/packages/grafana-ui/package.json @@ -31,6 +31,7 @@ "@grafana/e2e-selectors": "7.5.1", "@grafana/slate-react": "0.22.9-grafana", "@grafana/tsconfig": "^1.0.0-rc1", + "@grafana/aws-sdk": "0.0.3", "@iconscout/react-unicons": "1.1.4", "@popperjs/core": "2.5.4", "@sentry/browser": "5.25.0", diff --git a/packages/grafana-ui/rollup.config.ts b/packages/grafana-ui/rollup.config.ts index b3698f143fa..354d21e1e61 100644 --- a/packages/grafana-ui/rollup.config.ts +++ b/packages/grafana-ui/rollup.config.ts @@ -28,6 +28,7 @@ const buildCjsPackage = ({ env }) => { external: [ 'react', 'react-dom', + '@grafana/aws-sdk', '@grafana/data', '@grafana/e2e-selectors', 'moment', diff --git a/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx b/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx index 9edd7f7d62a..d7ce2687278 100644 --- a/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx +++ b/packages/grafana-ui/src/components/DataSourceSettings/SigV4AuthSettings.tsx @@ -1,253 +1,70 @@ -import React, { useEffect } from 'react'; -import { HttpSettingsProps } from './types'; -import { SelectableValue } from '@grafana/data'; -import { Button, InlineFormLabel, Input } from '..'; -import Select from '../Forms/Legacy/Select/Select'; +import React from 'react'; +import { HttpSettingsBaseProps } from './types'; +import { DataSourceSettings } from '@grafana/data'; +import { + AwsAuthDataSourceSecureJsonData, + AwsAuthDataSourceJsonData, + ConnectionConfig, + ConnectionConfigProps, +} from '@grafana/aws-sdk'; -export const SigV4AuthSettings: React.FC = (props) => { +export const SigV4AuthSettings: React.FC = (props) => { const { dataSourceConfig, onChange } = props; - const authProviderOptions = [ - { label: 'AWS SDK Default', value: 'default' }, - { label: 'Access & secret key', value: 'keys' }, - { label: 'Credentials file', value: 'credentials' }, - ] as SelectableValue[]; - - const regions = [ - { value: 'af-south-1', label: 'af-south-1' }, - { value: 'ap-east-1', label: 'ap-east-1' }, - { value: 'ap-northeast-1', label: 'ap-northeast-1' }, - { value: 'ap-northeast-2', label: 'ap-northeast-2' }, - { value: 'ap-northeast-3', label: 'ap-northeast-3' }, - { value: 'ap-south-1', label: 'ap-south-1' }, - { value: 'ap-southeast-1', label: 'ap-southeast-1' }, - { value: 'ap-southeast-2', label: 'ap-southeast-2' }, - { value: 'ca-central-1', label: 'ca-central-1' }, - { value: 'cn-north-1', label: 'cn-north-1' }, - { value: 'cn-northwest-1', label: 'cn-northwest-1' }, - { value: 'eu-central-1', label: 'eu-central-1' }, - { value: 'eu-north-1', label: 'eu-north-1' }, - { value: 'eu-west-1', label: 'eu-west-1' }, - { value: 'eu-west-2', label: 'eu-west-2' }, - { value: 'eu-west-3', label: 'eu-west-3' }, - { value: 'me-south-1', label: 'me-south-1' }, - { value: 'sa-east-1', label: 'sa-east-1' }, - { value: 'us-east-1', label: 'us-east-1' }, - { value: 'us-east-2', label: 'us-east-2' }, - { value: 'us-gov-east-1', label: 'us-gov-east-1' }, - { value: 'us-gov-west-1', label: 'us-gov-west-1' }, - { value: 'us-iso-east-1', label: 'us-iso-east-1' }, - { value: 'us-isob-east-1', label: 'us-isob-east-1' }, - { value: 'us-west-1', label: 'us-west-1' }, - { value: 'us-west-2', label: 'us-west-2' }, - ] as SelectableValue[]; - - // Apply some defaults on initial render - useEffect(() => { - const sigV4AuthType = dataSourceConfig.jsonData.sigV4AuthType || 'default'; - onJsonDataChange('sigV4AuthType', sigV4AuthType); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - const onSecureJsonDataReset = (fieldName: string) => { - const state = { - ...dataSourceConfig, - secureJsonData: { - ...dataSourceConfig.secureJsonData, - [fieldName]: '', - }, - secureJsonFields: { - ...dataSourceConfig.secureJsonFields, - [fieldName]: false, - }, - }; - - onChange(state); - }; - - const onSecureJsonDataChange = (fieldName: string, fieldValue: string) => { - const state = { - ...dataSourceConfig, - secureJsonData: { - ...dataSourceConfig.secureJsonData, - [fieldName]: fieldValue, - }, - }; - - onChange(state); - }; - - const onJsonDataChange = (fieldName: string, fieldValue: string) => { - const state = { + // The @grafana/aws-sdk ConnectionConfig is designed to be rendered in a ConfigEditor, + // taking DataSourcePluginOptionsEditorProps as props. We therefore need to map the props accordingly. + const connectionConfigProps: ConnectionConfigProps = { + onOptionsChange: (awsDataSourceSettings) => { + const dataSourceSettings: DataSourceSettings = { + ...dataSourceConfig, + jsonData: { + ...dataSourceConfig.jsonData, + sigV4AuthType: awsDataSourceSettings.jsonData.authType, + sigV4Profile: awsDataSourceSettings.jsonData.profile, + sigV4AssumeRoleArn: awsDataSourceSettings.jsonData.assumeRoleArn, + sigV4ExternalId: awsDataSourceSettings.jsonData.externalId, + sigV4Region: awsDataSourceSettings.jsonData.defaultRegion, + sigV4Endpoint: awsDataSourceSettings.jsonData.endpoint, + }, + secureJsonFields: { + sigV4AccessKey: awsDataSourceSettings.secureJsonFields?.accessKey, + sigV4SecretKey: awsDataSourceSettings.secureJsonFields?.secretKey, + }, + secureJsonData: { + sigV4AccessKey: awsDataSourceSettings.secureJsonData?.accessKey, + sigV4SecretKey: awsDataSourceSettings.secureJsonData?.secretKey, + }, + }; + onChange(dataSourceSettings); + }, + options: { ...dataSourceConfig, jsonData: { ...dataSourceConfig.jsonData, - [fieldName]: fieldValue, + authType: dataSourceConfig.jsonData.sigV4AuthType, + profile: dataSourceConfig.jsonData.sigV4Profile, + assumeRoleArn: dataSourceConfig.jsonData.sigV4AssumeRoleArn, + externalId: dataSourceConfig.jsonData.sigV4ExternalId, + defaultRegion: dataSourceConfig.jsonData.sigV4Region, + endpoint: dataSourceConfig.jsonData.sigV4Endpoint, }, - }; - - onChange(state); + secureJsonFields: { + accessKey: dataSourceConfig.secureJsonFields?.sigV4AccessKey, + secretKey: dataSourceConfig.secureJsonFields?.sigV4SecretKey, + }, + secureJsonData: { + accessKey: dataSourceConfig.secureJsonData?.sigV4AccessKey, + secretKey: dataSourceConfig.secureJsonData?.sigV4SecretKey, + }, + }, }; return ( <> -
SigV4 Auth Details
-
-
-
- - Authentication Provider - - onJsonDataChange('sigV4Profile', e.currentTarget.value)} - /> -
-
-
- )} - {dataSourceConfig.jsonData.sigV4AuthType === 'keys' && ( -
- {dataSourceConfig.secureJsonFields?.sigV4AccessKey ? ( -
-
- Access Key ID - -
-
-
- -
-
-
- ) : ( -
-
- Access Key ID -
- onSecureJsonDataChange('sigV4AccessKey', e.currentTarget.value)} - /> -
-
-
- )} - {dataSourceConfig.secureJsonFields?.sigV4SecretKey ? ( -
-
- Secret Access Key - -
-
-
- -
-
-
- ) : ( -
-
- Secret Access Key -
- onSecureJsonDataChange('sigV4SecretKey', e.currentTarget.value)} - /> -
-
-
- )} -
- )} -
-
- - Assume Role ARN - -
- onJsonDataChange('sigV4AssumeRoleArn', e.currentTarget.value)} - /> -
-
-
-
- - External ID - -
- onJsonDataChange('sigV4ExternalId', e.currentTarget.value)} - /> -
-
-
-
-
-
- - Default Region - -