CloudWatch: Re-implement authentication (#25548)

* CloudWatch: Revisit authentication

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Simplify auth code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Use ARN

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Add Drone configuration

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove unused code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove .drone.yml

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix external ID usage

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Fix issues after merge

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove stale code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove stale code

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Use auth type enum

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix test snapshot

* Coordinate frontend and backend option names

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove old comments

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix front-end tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Introduce session cache

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Use constants

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix field alignment

* CloudWatch: Fix log message

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Tidy go.mod

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Handle arn auth type

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Fix role assumption duration

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix test

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Inline unnecessary constants

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Use serial comma in UI

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Inline unnecessary constants

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Fail if missing region

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Handle unconfigured region

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Log when using cached session

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Include region in cache key

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Add UI warnings for lecagy support

* Do not clear ARN fields whenging change authentication provider

* Graph NG: annotations display (#27972)

* Annotations support POC

* Fix markers memoization

* dev dashboard update

* Update public/app/plugins/panel/graph3/plugins/AnnotationsPlugin.tsx

* CloudWatch: Remove errors.BadRequest

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Undo unintentional change

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Remove log line

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix cache key computation

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Add region to cache key

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve log messages

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* CloudWatch: Add documentation

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve tooltip

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve docs

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve docs

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve docs

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve tooltip

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Add role assumption provisioning example

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Add upgrade notes

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Improve docs

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Apply suggestions from code review

Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>

* backend: use latest sdk (#28147)

fixes #27713 via https://github.com/grafana/grafana-plugin-sdk-go/pull/227

* Docs: Update Permissions documentation (#28144)

* removed overview.md

* content updates

* Update datasource_permissions.md

* update content

* content updates

* Update organization_roles.md

* Update docs/sources/enterprise/saml.md

Co-authored-by: Kyle Brandt <kyle@grafana.com>

* Update dashboard_folder_permissions.md

Co-authored-by: Kyle Brandt <kyle@grafana.com>

* area/grafana/toolkit: ci-package needs to use synchronous writes (#28148)

* ci needs to use synchronous writes or the file ends up with zero length

* <Enterprise Docs> Add instructions to upload license via UI (#28067)

* Add UI license upload option, reformat Enterprise license activation section

Added the option to upload a license file through the Server Admin UI, and did a little reformatting to make license activation look more like a process.

* Headers not bold, hyphens not asterisks

* Github: run metrics collector workflow every 10min (#28153)

* GithubActions: Updated cron schedule

* Updated

* Docs: Update explore docs: remove dot at the end of line (#28151)

HI - Removed Dot(.) at the end of line to make it consistent with other 2 points.

Thanks,
Ashish

* Fix frontend tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Fix frontend tests

Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>

* Docs: Update upgrade notes

Co-authored-by: Sofia Papagiannaki <sofia@grafana.com>
Co-authored-by: Dominik Prokop <dominik.prokop@grafana.com>
Co-authored-by: Marcus Efraimsson <marcus.efraimsson@gmail.com>
Co-authored-by: Kyle Brandt <kyle@grafana.com>
Co-authored-by: Diana Payton <52059945+oddlittlebird@users.noreply.github.com>
Co-authored-by: Brian Gann <briangann@users.noreply.github.com>
Co-authored-by: Mitch Seaman <mjseaman@users.noreply.github.com>
Co-authored-by: Torkel Ödegaard <torkel@grafana.org>
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
Co-authored-by: ashishagarwal06 <34888589+ashishagarwal06@users.noreply.github.com>
This commit is contained in:
Arve Knudsen
2020-10-12 17:58:58 +02:00
committed by GitHub
parent 519ec93c7d
commit 957c88eaca
15 changed files with 701 additions and 825 deletions

View File

@@ -78,7 +78,7 @@ describe('Render', () => {
expect(wrapper).toMatchSnapshot();
});
it('should should show credentials profile name field', () => {
it('should show credentials profile name field', () => {
const wrapper = setup({
jsonData: {
authType: 'credentials',
@@ -87,7 +87,7 @@ describe('Render', () => {
expect(wrapper).toMatchSnapshot();
});
it('should should show access key and secret access key fields', () => {
it('should show access key and secret access key fields', () => {
const wrapper = setup({
jsonData: {
authType: 'keys',
@@ -96,7 +96,7 @@ describe('Render', () => {
expect(wrapper).toMatchSnapshot();
});
it('should should show arn role field', () => {
it('should show arn role field', () => {
const wrapper = setup({
jsonData: {
authType: 'arn',

View File

@@ -2,6 +2,7 @@ import React, { PureComponent } from 'react';
import { InlineFormLabel, LegacyForms, Button } from '@grafana/ui';
const { Select, Input } = LegacyForms;
import {
AppEvents,
DataSourcePluginOptionsEditorProps,
onUpdateDatasourceJsonDataOptionSelect,
onUpdateDatasourceResetOption,
@@ -13,11 +14,12 @@ import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
import { CloudWatchDatasource } from '../datasource';
import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types';
import { CancelablePromise, makePromiseCancelable } from 'app/core/utils/CancelablePromise';
import { appEvents } from 'app/core/core';
const authProviderOptions = [
{ label: 'AWS SDK Default', value: 'default' },
{ label: 'Access & secret key', value: 'keys' },
{ label: 'Credentials file', value: 'credentials' },
{ label: 'ARN', value: 'arn' },
] as SelectableValue[];
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
@@ -44,6 +46,22 @@ export class ConfigEditor extends PureComponent<Props, State> {
console.warn('Cloud Watch ConfigEditor has unmounted, initialization was canceled');
}
});
if (this.props.options.jsonData.authType === 'arn') {
appEvents.emit(AppEvents.alertWarning, [
'Since grafana 7.3 authentication type "arn" is deprecated, falling back to default SDK provider',
]);
} else if (
this.props.options.jsonData.authType === 'credentials' &&
!this.props.options.jsonData.profile &&
!this.props.options.jsonData.database
) {
appEvents.emit(AppEvents.alertWarning, [
'As of grafana 7.3 authentication type "credentials" should be used only for shared file credentials. \
If you don\'t have a credentials file, switch to the default SDK provider for extracting credentials \
from environment variables or IAM roles',
]);
}
}
componentWillUnmount() {
@@ -125,17 +143,18 @@ export class ConfigEditor extends PureComponent<Props, State> {
<div className="gf-form-group">
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel className="width-14">Auth Provider</InlineFormLabel>
<InlineFormLabel
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Authentication Provider
</InlineFormLabel>
<Select
className="width-30"
value={authProviderOptions.find(authProvider => authProvider.value === options.jsonData.authType)}
options={authProviderOptions}
defaultValue={options.jsonData.authType}
onChange={option => {
if (options.jsonData.authType === 'arn' && option.value !== 'arn') {
delete this.props.options.jsonData.assumeRoleArn;
delete this.props.options.jsonData.externalId;
}
onUpdateDatasourceJsonDataOptionSelect(this.props, 'authType')(option);
}}
/>
@@ -229,21 +248,24 @@ export class ConfigEditor extends PureComponent<Props, State> {
)}
</div>
)}
{options.jsonData.authType === 'arn' && (
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel className="width-14" tooltip="ARN of Assume Role">
Assume Role ARN
</InlineFormLabel>
<div className="width-30">
<Input
className="width-30"
placeholder="arn:aws:iam:*"
value={options.jsonData.assumeRoleArn || ''}
onChange={onUpdateDatasourceJsonDataOption(this.props, 'assumeRoleArn')}
/>
</div>
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</InlineFormLabel>
<div className="width-30">
<Input
className="width-30"
placeholder="arn:aws:iam:*"
value={options.jsonData.assumeRoleArn || ''}
onChange={onUpdateDatasourceJsonDataOption(this.props, 'assumeRoleArn')}
/>
</div>
</div>
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel
className="width-14"
@@ -261,7 +283,7 @@ export class ConfigEditor extends PureComponent<Props, State> {
</div>
</div>
</div>
)}
</div>
<div className="gf-form-inline">
<div className="gf-form">
<InlineFormLabel

View File

@@ -18,8 +18,9 @@ exports[`Render should disable access key id field 1`] = `
>
<Component
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Auth Provider
Authentication Provider
</Component>
<Select
allowCustomValue={false}
@@ -46,6 +47,10 @@ exports[`Render should disable access key id field 1`] = `
openMenuOnFocus={false}
options={
Array [
Object {
"label": "AWS SDK Default",
"value": "default",
},
Object {
"label": "Access & secret key",
"value": "keys",
@@ -54,10 +59,6 @@ exports[`Render should disable access key id field 1`] = `
"label": "Credentials file",
"value": "credentials",
},
Object {
"label": "ARN",
"value": "arn",
},
]
}
tabSelectsValue={true}
@@ -116,6 +117,54 @@ exports[`Render should disable access key id field 1`] = `
</div>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="arn:aws:iam:*"
value=""
/>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="External ID"
value=""
/>
</div>
</div>
</div>
</div>
<div
className="gf-form-inline"
>
@@ -198,8 +247,9 @@ exports[`Render should render component 1`] = `
>
<Component
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Auth Provider
Authentication Provider
</Component>
<Select
allowCustomValue={false}
@@ -226,6 +276,10 @@ exports[`Render should render component 1`] = `
openMenuOnFocus={false}
options={
Array [
Object {
"label": "AWS SDK Default",
"value": "default",
},
Object {
"label": "Access & secret key",
"value": "keys",
@@ -234,10 +288,6 @@ exports[`Render should render component 1`] = `
"label": "Credentials file",
"value": "credentials",
},
Object {
"label": "ARN",
"value": "arn",
},
]
}
tabSelectsValue={true}
@@ -296,6 +346,54 @@ exports[`Render should render component 1`] = `
</div>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="arn:aws:iam:*"
value=""
/>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="External ID"
value=""
/>
</div>
</div>
</div>
</div>
<div
className="gf-form-inline"
>
@@ -360,7 +458,7 @@ exports[`Render should render component 1`] = `
</Fragment>
`;
exports[`Render should should show access key and secret access key fields 1`] = `
exports[`Render should show access key and secret access key fields 1`] = `
<Fragment>
<h3
className="page-heading"
@@ -378,8 +476,9 @@ exports[`Render should should show access key and secret access key fields 1`] =
>
<Component
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Auth Provider
Authentication Provider
</Component>
<Select
allowCustomValue={false}
@@ -406,6 +505,10 @@ exports[`Render should should show access key and secret access key fields 1`] =
openMenuOnFocus={false}
options={
Array [
Object {
"label": "AWS SDK Default",
"value": "default",
},
Object {
"label": "Access & secret key",
"value": "keys",
@@ -414,10 +517,6 @@ exports[`Render should should show access key and secret access key fields 1`] =
"label": "Credentials file",
"value": "credentials",
},
Object {
"label": "ARN",
"value": "arn",
},
]
}
tabSelectsValue={true}
@@ -476,6 +575,54 @@ exports[`Render should should show access key and secret access key fields 1`] =
</div>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="arn:aws:iam:*"
value=""
/>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="External ID"
value=""
/>
</div>
</div>
</div>
</div>
<div
className="gf-form-inline"
>
@@ -540,7 +687,7 @@ exports[`Render should should show access key and secret access key fields 1`] =
</Fragment>
`;
exports[`Render should should show arn role field 1`] = `
exports[`Render should show arn role field 1`] = `
<Fragment>
<h3
className="page-heading"
@@ -558,8 +705,9 @@ exports[`Render should should show arn role field 1`] = `
>
<Component
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Auth Provider
Authentication Provider
</Component>
<Select
allowCustomValue={false}
@@ -586,6 +734,10 @@ exports[`Render should should show arn role field 1`] = `
openMenuOnFocus={false}
options={
Array [
Object {
"label": "AWS SDK Default",
"value": "default",
},
Object {
"label": "Access & secret key",
"value": "keys",
@@ -594,10 +746,6 @@ exports[`Render should should show arn role field 1`] = `
"label": "Credentials file",
"value": "credentials",
},
Object {
"label": "ARN",
"value": "arn",
},
]
}
tabSelectsValue={true}
@@ -656,6 +804,54 @@ exports[`Render should should show arn role field 1`] = `
</div>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="arn:aws:iam:*"
value=""
/>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="External ID"
value=""
/>
</div>
</div>
</div>
</div>
<div
className="gf-form-inline"
>
@@ -720,7 +916,7 @@ exports[`Render should should show arn role field 1`] = `
</Fragment>
`;
exports[`Render should should show credentials profile name field 1`] = `
exports[`Render should show credentials profile name field 1`] = `
<Fragment>
<h3
className="page-heading"
@@ -738,8 +934,9 @@ exports[`Render should should show credentials profile name field 1`] = `
>
<Component
className="width-14"
tooltip="Specify which AWS credentials chain to use. AWS SDK Default is the recommended option for EKS, ECS, or if you've attached an IAM role to your EC2 instance."
>
Auth Provider
Authentication Provider
</Component>
<Select
allowCustomValue={false}
@@ -766,6 +963,10 @@ exports[`Render should should show credentials profile name field 1`] = `
openMenuOnFocus={false}
options={
Array [
Object {
"label": "AWS SDK Default",
"value": "default",
},
Object {
"label": "Access & secret key",
"value": "keys",
@@ -774,10 +975,6 @@ exports[`Render should should show credentials profile name field 1`] = `
"label": "Credentials file",
"value": "credentials",
},
Object {
"label": "ARN",
"value": "arn",
},
]
}
tabSelectsValue={true}
@@ -836,6 +1033,54 @@ exports[`Render should should show credentials profile name field 1`] = `
</div>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="Optionally, specify the ARN of a role to assume. Specifying a role here will ensure that the selected authentication provider is used to assume the specified role rather than using the credentials directly. Leave blank if you don't need to assume a role at all"
>
Assume Role ARN
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="arn:aws:iam:*"
value=""
/>
</div>
</div>
<div
className="gf-form-inline"
>
<div
className="gf-form"
>
<Component
className="width-14"
tooltip="If you are assuming a role in another account, that has been created with an external ID, specify the external ID here."
>
External ID
</Component>
<div
className="width-30"
>
<Input
className="width-30"
onChange={[Function]}
placeholder="External ID"
value=""
/>
</div>
</div>
</div>
</div>
<div
className="gf-form-inline"
>