mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch: Consume the grafana/aws-sdk (#31807)
* consume the grafana/aws-sdk * upgrade aws-sdk
This commit is contained in:
@@ -200,6 +200,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@emotion/core": "10.0.27",
|
"@emotion/core": "10.0.27",
|
||||||
|
"@grafana/aws-sdk": "0.0.2",
|
||||||
"@grafana/slate-react": "0.22.9-grafana",
|
"@grafana/slate-react": "0.22.9-grafana",
|
||||||
"@popperjs/core": "2.5.4",
|
"@popperjs/core": "2.5.4",
|
||||||
"@reduxjs/toolkit": "1.5.0",
|
"@reduxjs/toolkit": "1.5.0",
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { shallow } from 'enzyme';
|
import { shallow } from 'enzyme';
|
||||||
import ConfigEditor, { Props } from './ConfigEditor';
|
import { AwsAuthType } from '@grafana/aws-sdk';
|
||||||
|
import { ConfigEditor, Props } from './ConfigEditor';
|
||||||
|
|
||||||
jest.mock('app/features/plugins/datasource_srv', () => ({
|
jest.mock('app/features/plugins/datasource_srv', () => ({
|
||||||
getDatasourceSrv: () => ({
|
getDatasourceSrv: () => ({
|
||||||
@@ -46,7 +47,7 @@ const setup = (propOverrides?: object) => {
|
|||||||
externalId: '',
|
externalId: '',
|
||||||
database: '',
|
database: '',
|
||||||
customMetricsNamespaces: '',
|
customMetricsNamespaces: '',
|
||||||
authType: 'keys',
|
authType: AwsAuthType.Keys,
|
||||||
defaultRegion: 'us-east-2',
|
defaultRegion: 'us-east-2',
|
||||||
timeField: '@timestamp',
|
timeField: '@timestamp',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,339 +1,63 @@
|
|||||||
import React, { PureComponent } from 'react';
|
import React, { FC, useEffect, useState } from 'react';
|
||||||
import { InlineFormLabel, LegacyForms, Button } from '@grafana/ui';
|
import { Input, InlineField } from '@grafana/ui';
|
||||||
const { Select, Input } = LegacyForms;
|
import { DataSourcePluginOptionsEditorProps, onUpdateDatasourceJsonDataOption } from '@grafana/data';
|
||||||
import {
|
import { ConnectionConfig } from '@grafana/aws-sdk';
|
||||||
AppEvents,
|
|
||||||
SelectableValue,
|
|
||||||
DataSourcePluginOptionsEditorProps,
|
|
||||||
onUpdateDatasourceJsonDataOptionSelect,
|
|
||||||
onUpdateDatasourceResetOption,
|
|
||||||
onUpdateDatasourceJsonDataOption,
|
|
||||||
onUpdateDatasourceSecureJsonDataOption,
|
|
||||||
} from '@grafana/data';
|
|
||||||
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 = [
|
import { getDatasourceSrv } from 'app/features/plugins/datasource_srv';
|
||||||
{ label: 'AWS SDK Default', value: 'default' },
|
import { store } from 'app/store/store';
|
||||||
{ label: 'Access & secret key', value: 'keys' },
|
import { notifyApp } from 'app/core/actions';
|
||||||
{ label: 'Credentials file', value: 'credentials' },
|
import { createWarningNotification } from 'app/core/copy/appNotification';
|
||||||
] as SelectableValue[];
|
|
||||||
|
import { CloudWatchJsonData, CloudWatchSecureJsonData } from '../types';
|
||||||
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
|
|
||||||
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
|
export type Props = DataSourcePluginOptionsEditorProps<CloudWatchJsonData, CloudWatchSecureJsonData>;
|
||||||
|
|
||||||
export interface State {
|
export const ConfigEditor: FC<Props> = (props: Props) => {
|
||||||
regions: SelectableValue[];
|
const [datasource, setDatasource] = useState<CloudWatchDatasource>();
|
||||||
}
|
|
||||||
|
|
||||||
export class ConfigEditor extends PureComponent<Props, State> {
|
const addWarning = (message: string) => {
|
||||||
constructor(props: Props) {
|
store.dispatch(notifyApp(createWarningNotification('CloudWatch Authentication', message)));
|
||||||
super(props);
|
};
|
||||||
|
|
||||||
this.state = {
|
useEffect(() => {
|
||||||
regions: [],
|
getDatasourceSrv()
|
||||||
};
|
.loadDatasource(props.options.name)
|
||||||
}
|
.then((datasource: CloudWatchDatasource) => setDatasource(datasource));
|
||||||
|
|
||||||
loadRegionsPromise: CancelablePromise<any> | null = null;
|
if (props.options.jsonData.authType === 'arn') {
|
||||||
|
addWarning('Since grafana 7.3 authentication type "arn" is deprecated, falling back to default SDK provider');
|
||||||
componentDidMount() {
|
|
||||||
this.loadRegionsPromise = makePromiseCancelable(this.loadRegions());
|
|
||||||
this.loadRegionsPromise.promise.catch(({ isCanceled }) => {
|
|
||||||
if (isCanceled) {
|
|
||||||
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 (
|
} else if (
|
||||||
this.props.options.jsonData.authType === 'credentials' &&
|
props.options.jsonData.authType === 'credentials' &&
|
||||||
!this.props.options.jsonData.profile &&
|
!props.options.jsonData.profile &&
|
||||||
!this.props.options.jsonData.database
|
!props.options.jsonData.database
|
||||||
) {
|
) {
|
||||||
appEvents.emit(AppEvents.alertWarning, [
|
addWarning(
|
||||||
'As of grafana 7.3 authentication type "credentials" should be used only for shared file credentials. \
|
'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 \
|
If you don\'t have a credentials file, switch to the default SDK provider for extracting credentials \
|
||||||
from environment variables or IAM roles',
|
from environment variables or IAM roles'
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
if (this.loadRegionsPromise) {
|
|
||||||
this.loadRegionsPromise.cancel();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async loadRegions() {
|
|
||||||
await getDatasourceSrv()
|
|
||||||
.loadDatasource(this.props.options.name)
|
|
||||||
.then((ds: CloudWatchDatasource) => ds.getRegions())
|
|
||||||
.then(
|
|
||||||
(regions: any) => {
|
|
||||||
this.setState({
|
|
||||||
regions: regions.map((region: any) => {
|
|
||||||
return {
|
|
||||||
value: region.value,
|
|
||||||
label: region.text,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(err: any) => {
|
|
||||||
const regions = [
|
|
||||||
'af-south-1',
|
|
||||||
'ap-east-1',
|
|
||||||
'ap-northeast-1',
|
|
||||||
'ap-northeast-2',
|
|
||||||
'ap-northeast-3',
|
|
||||||
'ap-south-1',
|
|
||||||
'ap-southeast-1',
|
|
||||||
'ap-southeast-2',
|
|
||||||
'ca-central-1',
|
|
||||||
'cn-north-1',
|
|
||||||
'cn-northwest-1',
|
|
||||||
'eu-central-1',
|
|
||||||
'eu-north-1',
|
|
||||||
'eu-south-1',
|
|
||||||
'eu-west-1',
|
|
||||||
'eu-west-2',
|
|
||||||
'eu-west-3',
|
|
||||||
'me-south-1',
|
|
||||||
'sa-east-1',
|
|
||||||
'us-east-1',
|
|
||||||
'us-east-2',
|
|
||||||
'us-gov-east-1',
|
|
||||||
'us-gov-west-1',
|
|
||||||
'us-iso-east-1',
|
|
||||||
'us-isob-east-1',
|
|
||||||
'us-west-1',
|
|
||||||
'us-west-2',
|
|
||||||
];
|
|
||||||
|
|
||||||
this.setState({
|
|
||||||
regions: regions.map((region: string) => ({
|
|
||||||
value: region,
|
|
||||||
label: region,
|
|
||||||
})),
|
|
||||||
});
|
|
||||||
|
|
||||||
// expected to fail when creating new datasource
|
|
||||||
// console.error('failed to get latest regions', err);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const { regions } = this.state;
|
|
||||||
const { options } = this.props;
|
|
||||||
const secureJsonData = (options.secureJsonData || {}) as CloudWatchSecureJsonData;
|
|
||||||
let profile = options.jsonData.profile;
|
|
||||||
if (profile === undefined) {
|
|
||||||
profile = options.database;
|
|
||||||
}
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3 className="page-heading">CloudWatch Details</h3>
|
<ConnectionConfig
|
||||||
<div className="gf-form-group">
|
{...props}
|
||||||
<div className="gf-form-inline">
|
loadRegions={
|
||||||
<div className="gf-form">
|
datasource &&
|
||||||
<InlineFormLabel
|
(() => datasource!.getRegions().then((r) => r.filter((r) => r.value !== 'default').map((v) => v.value)))
|
||||||
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."
|
>
|
||||||
>
|
<InlineField label="Namespaces of Custom Metrics" labelWidth={28} tooltip="Namespaces of Custom Metrics.">
|
||||||
Authentication Provider
|
<Input
|
||||||
</InlineFormLabel>
|
width={60}
|
||||||
<Select
|
placeholder="Namespace1,Namespace2"
|
||||||
className="width-30"
|
value={props.options.jsonData.customMetricsNamespaces || ''}
|
||||||
value={authProviderOptions.find((authProvider) => authProvider.value === options.jsonData.authType)}
|
onChange={onUpdateDatasourceJsonDataOption(props, 'customMetricsNamespaces')}
|
||||||
options={authProviderOptions}
|
/>
|
||||||
defaultValue={options.jsonData.authType}
|
</InlineField>
|
||||||
onChange={(option) => {
|
</ConnectionConfig>
|
||||||
onUpdateDatasourceJsonDataOptionSelect(this.props, 'authType')(option);
|
</>
|
||||||
}}
|
);
|
||||||
/>
|
};
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{options.jsonData.authType === 'credentials' && (
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel
|
|
||||||
className="width-14"
|
|
||||||
tooltip="Credentials profile name, as specified in ~/.aws/credentials, leave blank for default."
|
|
||||||
>
|
|
||||||
Credentials Profile Name
|
|
||||||
</InlineFormLabel>
|
|
||||||
<div className="width-30">
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
placeholder="default"
|
|
||||||
value={profile}
|
|
||||||
onChange={onUpdateDatasourceJsonDataOption(this.props, 'profile')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{options.jsonData.authType === 'keys' && (
|
|
||||||
<div>
|
|
||||||
{options.secureJsonFields?.accessKey ? (
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14">Access Key ID</InlineFormLabel>
|
|
||||||
<Input className="width-25" placeholder="Configured" disabled={true} />
|
|
||||||
</div>
|
|
||||||
<div className="gf-form">
|
|
||||||
<div className="max-width-30 gf-form-inline">
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
type="button"
|
|
||||||
onClick={onUpdateDatasourceResetOption(this.props, 'accessKey')}
|
|
||||||
>
|
|
||||||
Reset
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14">Access Key ID</InlineFormLabel>
|
|
||||||
<div className="width-30">
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
value={secureJsonData.accessKey || ''}
|
|
||||||
onChange={onUpdateDatasourceSecureJsonDataOption(this.props, 'accessKey')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{options.secureJsonFields?.secretKey ? (
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14">Secret Access Key</InlineFormLabel>
|
|
||||||
<Input className="width-25" placeholder="Configured" disabled={true} />
|
|
||||||
</div>
|
|
||||||
<div className="gf-form">
|
|
||||||
<div className="max-width-30 gf-form-inline">
|
|
||||||
<Button
|
|
||||||
variant="secondary"
|
|
||||||
type="button"
|
|
||||||
onClick={onUpdateDatasourceResetOption(this.props, 'secretKey')}
|
|
||||||
>
|
|
||||||
Reset
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14">Secret Access Key</InlineFormLabel>
|
|
||||||
<div className="width-30">
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
value={secureJsonData.secretKey || ''}
|
|
||||||
onChange={onUpdateDatasourceSecureJsonDataOption(this.props, 'secretKey')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</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"
|
|
||||||
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
|
|
||||||
</InlineFormLabel>
|
|
||||||
<div className="width-30">
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
placeholder="External ID"
|
|
||||||
value={options.jsonData.externalId || ''}
|
|
||||||
onChange={onUpdateDatasourceJsonDataOption(this.props, 'externalId')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel
|
|
||||||
className="width-14"
|
|
||||||
tooltip="Specify the region, such as for US West (Oregon) use ` us-west-2 ` as the region."
|
|
||||||
>
|
|
||||||
Default Region
|
|
||||||
</InlineFormLabel>
|
|
||||||
<Select
|
|
||||||
className="width-30"
|
|
||||||
value={regions.find((region) => region.value === options.jsonData.defaultRegion)}
|
|
||||||
options={regions}
|
|
||||||
defaultValue={options.jsonData.defaultRegion}
|
|
||||||
onChange={onUpdateDatasourceJsonDataOptionSelect(this.props, 'defaultRegion')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14" tooltip="Namespaces of Custom Metrics.">
|
|
||||||
Custom Metrics
|
|
||||||
</InlineFormLabel>
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
placeholder="Namespace1,Namespace2"
|
|
||||||
value={options.jsonData.customMetricsNamespaces || ''}
|
|
||||||
onChange={onUpdateDatasourceJsonDataOption(this.props, 'customMetricsNamespaces')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="gf-form-inline">
|
|
||||||
<div className="gf-form">
|
|
||||||
<InlineFormLabel className="width-14" tooltip="Optionally, specify a custom endpoint for the service.">
|
|
||||||
Endpoint
|
|
||||||
</InlineFormLabel>
|
|
||||||
<div className="width-30">
|
|
||||||
<Input
|
|
||||||
className="width-30"
|
|
||||||
placeholder={'https://{service}.{region}.amazonaws.com'}
|
|
||||||
value={options.jsonData.endpoint || ''}
|
|
||||||
onChange={onUpdateDatasourceJsonDataOption(this.props, 'endpoint')}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export default ConfigEditor;
|
|
||||||
|
|||||||
@@ -5,12 +5,14 @@ import React, { memo } from 'react';
|
|||||||
import { AbsoluteTimeRange, QueryEditorProps } from '@grafana/data';
|
import { AbsoluteTimeRange, QueryEditorProps } from '@grafana/data';
|
||||||
import { InlineFormLabel } from '@grafana/ui';
|
import { InlineFormLabel } from '@grafana/ui';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { CloudWatchLogsQuery, CloudWatchQuery } from '../types';
|
import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../types';
|
||||||
import { CloudWatchLogsQueryField } from './LogsQueryField';
|
import { CloudWatchLogsQueryField } from './LogsQueryField';
|
||||||
import CloudWatchLink from './CloudWatchLink';
|
import CloudWatchLink from './CloudWatchLink';
|
||||||
import { css } from 'emotion';
|
import { css } from 'emotion';
|
||||||
|
|
||||||
type Props = QueryEditorProps<CloudWatchDatasource, CloudWatchQuery> & { allowCustomValue?: boolean };
|
type Props = QueryEditorProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData> & {
|
||||||
|
allowCustomValue?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
const labelClass = css`
|
const labelClass = css`
|
||||||
margin-left: 3px;
|
margin-left: 3px;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ import syntax from '../syntax';
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { AbsoluteTimeRange, AppEvents, ExploreQueryFieldProps, SelectableValue } from '@grafana/data';
|
import { AbsoluteTimeRange, AppEvents, ExploreQueryFieldProps, SelectableValue } from '@grafana/data';
|
||||||
import { CloudWatchLogsQuery, CloudWatchQuery } from '../types';
|
import { CloudWatchJsonData, CloudWatchLogsQuery, CloudWatchQuery } from '../types';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
import { LanguageMap, languages as prismLanguages } from 'prismjs';
|
||||||
import { CloudWatchLanguageProvider } from '../language_provider';
|
import { CloudWatchLanguageProvider } from '../language_provider';
|
||||||
@@ -32,7 +32,8 @@ import { appEvents } from 'app/core/core';
|
|||||||
import { InputActionMeta } from '@grafana/ui/src/components/Select/types';
|
import { InputActionMeta } from '@grafana/ui/src/components/Select/types';
|
||||||
import { getStatsGroups } from '../utils/query/getStatsGroups';
|
import { getStatsGroups } from '../utils/query/getStatsGroups';
|
||||||
|
|
||||||
export interface CloudWatchLogsQueryFieldProps extends ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery> {
|
export interface CloudWatchLogsQueryFieldProps
|
||||||
|
extends ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData> {
|
||||||
absoluteRange: AbsoluteTimeRange;
|
absoluteRange: AbsoluteTimeRange;
|
||||||
onLabelsRefresh?: () => void;
|
onLabelsRefresh?: () => void;
|
||||||
ExtraFieldElement?: ReactNode;
|
ExtraFieldElement?: ReactNode;
|
||||||
|
|||||||
@@ -7,11 +7,12 @@ import { TemplateSrv } from 'app/features/templating/template_srv';
|
|||||||
import { MetricsQueryEditor, normalizeQuery, Props } from './MetricsQueryEditor';
|
import { MetricsQueryEditor, normalizeQuery, Props } from './MetricsQueryEditor';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { CustomVariableModel, initialVariableModelState } from '../../../../features/variables/types';
|
import { CustomVariableModel, initialVariableModelState } from '../../../../features/variables/types';
|
||||||
|
import { CloudWatchJsonData } from '../types';
|
||||||
|
|
||||||
const setup = () => {
|
const setup = () => {
|
||||||
const instanceSettings = {
|
const instanceSettings = {
|
||||||
jsonData: { defaultRegion: 'us-east-1' },
|
jsonData: { defaultRegion: 'us-east-1' },
|
||||||
} as DataSourceInstanceSettings;
|
} as DataSourceInstanceSettings<CloudWatchJsonData>;
|
||||||
|
|
||||||
const templateSrv = new TemplateSrv();
|
const templateSrv = new TemplateSrv();
|
||||||
const variable: CustomVariableModel = {
|
const variable: CustomVariableModel = {
|
||||||
|
|||||||
@@ -4,11 +4,11 @@ import isEmpty from 'lodash/isEmpty';
|
|||||||
import { ExploreQueryFieldProps } from '@grafana/data';
|
import { ExploreQueryFieldProps } from '@grafana/data';
|
||||||
import { LegacyForms, ValidationEvents, EventsWithValidation, Icon } from '@grafana/ui';
|
import { LegacyForms, ValidationEvents, EventsWithValidation, Icon } from '@grafana/ui';
|
||||||
const { Input, Switch } = LegacyForms;
|
const { Input, Switch } = LegacyForms;
|
||||||
import { CloudWatchQuery, CloudWatchMetricsQuery } from '../types';
|
import { CloudWatchQuery, CloudWatchMetricsQuery, CloudWatchJsonData } from '../types';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { QueryField, Alias, MetricsQueryFieldsEditor } from './';
|
import { QueryField, Alias, MetricsQueryFieldsEditor } from './';
|
||||||
|
|
||||||
export type Props = ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery>;
|
export type Props = ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData>;
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
showMeta: boolean;
|
showMeta: boolean;
|
||||||
|
|||||||
@@ -2,13 +2,13 @@ import React, { PureComponent } from 'react';
|
|||||||
import pick from 'lodash/pick';
|
import pick from 'lodash/pick';
|
||||||
import { ExploreQueryFieldProps, ExploreMode } from '@grafana/data';
|
import { ExploreQueryFieldProps, ExploreMode } from '@grafana/data';
|
||||||
import { Segment } from '@grafana/ui';
|
import { Segment } from '@grafana/ui';
|
||||||
import { CloudWatchQuery } from '../types';
|
import { CloudWatchJsonData, CloudWatchQuery } from '../types';
|
||||||
import { CloudWatchDatasource } from '../datasource';
|
import { CloudWatchDatasource } from '../datasource';
|
||||||
import { QueryInlineField } from './';
|
import { QueryInlineField } from './';
|
||||||
import { MetricsQueryEditor } from './MetricsQueryEditor';
|
import { MetricsQueryEditor } from './MetricsQueryEditor';
|
||||||
import LogsQueryEditor from './LogsQueryEditor';
|
import LogsQueryEditor from './LogsQueryEditor';
|
||||||
|
|
||||||
export type Props = ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery>;
|
export type Props = ExploreQueryFieldProps<CloudWatchDatasource, CloudWatchQuery, CloudWatchJsonData>;
|
||||||
|
|
||||||
const apiModes = {
|
const apiModes = {
|
||||||
Metrics: { label: 'CloudWatch Metrics', value: 'Metrics' },
|
Metrics: { label: 'CloudWatch Metrics', value: 'Metrics' },
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -11,7 +11,13 @@ import {
|
|||||||
import * as redux from 'app/store/store';
|
import * as redux from 'app/store/store';
|
||||||
import { CloudWatchDatasource, MAX_ATTEMPTS } from '../datasource';
|
import { CloudWatchDatasource, MAX_ATTEMPTS } from '../datasource';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { CloudWatchLogsQuery, CloudWatchLogsQueryStatus, CloudWatchMetricsQuery, LogAction } from '../types';
|
import {
|
||||||
|
CloudWatchJsonData,
|
||||||
|
CloudWatchLogsQuery,
|
||||||
|
CloudWatchLogsQueryStatus,
|
||||||
|
CloudWatchMetricsQuery,
|
||||||
|
LogAction,
|
||||||
|
} from '../types';
|
||||||
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
import { convertToStoreState } from '../../../../../test/helpers/convertToStoreState';
|
import { convertToStoreState } from '../../../../../test/helpers/convertToStoreState';
|
||||||
@@ -46,7 +52,7 @@ function getTestContext({ response = {}, throws = false, templateSrv = new Templ
|
|||||||
const instanceSettings = {
|
const instanceSettings = {
|
||||||
jsonData: { defaultRegion: 'us-east-1' },
|
jsonData: { defaultRegion: 'us-east-1' },
|
||||||
name: 'TestDatasource',
|
name: 'TestDatasource',
|
||||||
} as DataSourceInstanceSettings;
|
} as DataSourceInstanceSettings<CloudWatchJsonData>;
|
||||||
|
|
||||||
const timeSrv = {
|
const timeSrv = {
|
||||||
time: { from: '2016-12-31 15:00:00Z', to: '2016-12-31 16:00:00Z' },
|
time: { from: '2016-12-31 15:00:00Z', to: '2016-12-31 16:00:00Z' },
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { DataQuery, SelectableValue, DataSourceJsonData } from '@grafana/data';
|
import { DataQuery, SelectableValue } from '@grafana/data';
|
||||||
|
import { AwsAuthDataSourceSecureJsonData, AwsAuthDataSourceJsonData } from '@grafana/aws-sdk';
|
||||||
|
|
||||||
export interface CloudWatchMetricsQuery extends DataQuery {
|
export interface CloudWatchMetricsQuery extends DataQuery {
|
||||||
queryMode?: 'Metrics';
|
queryMode?: 'Metrics';
|
||||||
@@ -56,16 +57,14 @@ export interface AnnotationQuery extends CloudWatchMetricsQuery {
|
|||||||
|
|
||||||
export type SelectableStrings = Array<SelectableValue<string>>;
|
export type SelectableStrings = Array<SelectableValue<string>>;
|
||||||
|
|
||||||
export interface CloudWatchJsonData extends DataSourceJsonData {
|
export interface CloudWatchJsonData extends AwsAuthDataSourceJsonData {
|
||||||
timeField?: string;
|
timeField?: string;
|
||||||
assumeRoleArn?: string;
|
|
||||||
externalId?: string;
|
|
||||||
database?: string;
|
database?: string;
|
||||||
customMetricsNamespaces?: string;
|
customMetricsNamespaces?: string;
|
||||||
endpoint?: string;
|
endpoint?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CloudWatchSecureJsonData {
|
export interface CloudWatchSecureJsonData extends AwsAuthDataSourceSecureJsonData {
|
||||||
accessKey: string;
|
accessKey: string;
|
||||||
secretKey: string;
|
secretKey: string;
|
||||||
}
|
}
|
||||||
|
|||||||
102
yarn.lock
102
yarn.lock
@@ -3431,6 +3431,40 @@
|
|||||||
source-map "~0.6.1"
|
source-map "~0.6.1"
|
||||||
typescript "~3.9.7"
|
typescript "~3.9.7"
|
||||||
|
|
||||||
|
"@grafana/aws-sdk@0.0.2":
|
||||||
|
version "0.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@grafana/aws-sdk/-/aws-sdk-0.0.2.tgz#dcaa8672158ce12d5e83b10c6d801b718e03e66a"
|
||||||
|
integrity sha512-nKkFoNJ76NgGolJArdro39Ho7YA769BO3nq8/NeUHai9MeEVmPviuqC5pnswb08Q4QTEKESi0Zo3x8GvfF6cZg==
|
||||||
|
dependencies:
|
||||||
|
"@grafana/data" "7.5.0-beta.1"
|
||||||
|
"@grafana/runtime" "7.5.0-beta.1"
|
||||||
|
"@grafana/ui" "7.5.0-beta.1"
|
||||||
|
|
||||||
|
"@grafana/data@7.5.0-beta.1":
|
||||||
|
version "7.5.0-beta.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@grafana/data/-/data-7.5.0-beta.1.tgz#4c6dcd07daee713a06e46d230b9c09877fd5f732"
|
||||||
|
integrity sha512-hYU3XWVp2rsLfSZVwYFM9wL0e+i1ktlNPzELGL66EcSV+ak41orlcjpwEpke4O7Vtht6t5qSoTycYlmj6+aZEw==
|
||||||
|
dependencies:
|
||||||
|
"@braintree/sanitize-url" "4.0.0"
|
||||||
|
"@types/d3-interpolate" "^1.3.1"
|
||||||
|
apache-arrow "0.16.0"
|
||||||
|
eventemitter3 "4.0.7"
|
||||||
|
lodash "4.17.21"
|
||||||
|
marked "2.0.1"
|
||||||
|
rxjs "6.6.3"
|
||||||
|
xss "1.0.6"
|
||||||
|
|
||||||
|
"@grafana/e2e-selectors@7.5.0-beta.1":
|
||||||
|
version "7.5.0-beta.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@grafana/e2e-selectors/-/e2e-selectors-7.5.0-beta.1.tgz#063734af7a112033d2e78219969619194fca3526"
|
||||||
|
integrity sha512-zn23xTrkNtCRSI4wg23CatAq2t4R2JWtqwEKvRfP3qWuJTwql2vu1pLJufJUcTkJtn3ImmwSMGvxZ/wI9SPbqQ==
|
||||||
|
dependencies:
|
||||||
|
"@grafana/tsconfig" "^1.0.0-rc1"
|
||||||
|
commander "5.0.0"
|
||||||
|
execa "4.0.0"
|
||||||
|
typescript "4.1.2"
|
||||||
|
yaml "^1.8.3"
|
||||||
|
|
||||||
"@grafana/eslint-config@2.2.1":
|
"@grafana/eslint-config@2.2.1":
|
||||||
version "2.2.1"
|
version "2.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/@grafana/eslint-config/-/eslint-config-2.2.1.tgz#a7c6dd57ae0011fb2535a688e1e17969e621d21a"
|
resolved "https://registry.yarnpkg.com/@grafana/eslint-config/-/eslint-config-2.2.1.tgz#a7c6dd57ae0011fb2535a688e1e17969e621d21a"
|
||||||
@@ -3447,6 +3481,16 @@
|
|||||||
prettier "2.2.1"
|
prettier "2.2.1"
|
||||||
typescript "4.1.3"
|
typescript "4.1.3"
|
||||||
|
|
||||||
|
"@grafana/runtime@7.5.0-beta.1":
|
||||||
|
version "7.5.0-beta.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@grafana/runtime/-/runtime-7.5.0-beta.1.tgz#f0e29a2493d440b7dd6d09def9727c2ce41cb743"
|
||||||
|
integrity sha512-Cn62/9N1g3TX9vaoGgpD0/bWG2U1nsAoHboLbQnKkztH8tmLoChHqUaZ/5Lsu3s9K5mxI3YA+4PrAxr4NlUPjw==
|
||||||
|
dependencies:
|
||||||
|
"@grafana/data" "7.5.0-beta.1"
|
||||||
|
"@grafana/ui" "7.5.0-beta.1"
|
||||||
|
systemjs "0.20.19"
|
||||||
|
systemjs-plugin-css "0.1.37"
|
||||||
|
|
||||||
"@grafana/slate-react@0.22.9-grafana":
|
"@grafana/slate-react@0.22.9-grafana":
|
||||||
version "0.22.9-grafana"
|
version "0.22.9-grafana"
|
||||||
resolved "https://registry.yarnpkg.com/@grafana/slate-react/-/slate-react-0.22.9-grafana.tgz#07f35f0ffc018f616b9f82fa6e5ba65fae75c6a0"
|
resolved "https://registry.yarnpkg.com/@grafana/slate-react/-/slate-react-0.22.9-grafana.tgz#07f35f0ffc018f616b9f82fa6e5ba65fae75c6a0"
|
||||||
@@ -3474,6 +3518,64 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@grafana/tsconfig/-/tsconfig-1.0.0-rc1.tgz#d07ea16755a50cae21000113f30546b61647a200"
|
resolved "https://registry.yarnpkg.com/@grafana/tsconfig/-/tsconfig-1.0.0-rc1.tgz#d07ea16755a50cae21000113f30546b61647a200"
|
||||||
integrity sha512-nucKPGyzlSKYSiJk5RA8GzMdVWhdYNdF+Hh65AXxjD9PlY69JKr5wANj8bVdQboag6dgg0BFKqgKPyY+YtV4Iw==
|
integrity sha512-nucKPGyzlSKYSiJk5RA8GzMdVWhdYNdF+Hh65AXxjD9PlY69JKr5wANj8bVdQboag6dgg0BFKqgKPyY+YtV4Iw==
|
||||||
|
|
||||||
|
"@grafana/ui@7.5.0-beta.1":
|
||||||
|
version "7.5.0-beta.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@grafana/ui/-/ui-7.5.0-beta.1.tgz#0de30ebe9e51df956fa20f1d0a396d286b3f8c5f"
|
||||||
|
integrity sha512-/+VeGVRjRtd9bOwhzdwWqk8IVrENlGoMWCuRaNQU0+q2tdPQurXYbE3rmxKVtKysPTYNzbhS5Ox5QzYkPkoriA==
|
||||||
|
dependencies:
|
||||||
|
"@emotion/core" "10.0.27"
|
||||||
|
"@grafana/data" "7.5.0-beta.1"
|
||||||
|
"@grafana/e2e-selectors" "7.5.0-beta.1"
|
||||||
|
"@grafana/slate-react" "0.22.9-grafana"
|
||||||
|
"@grafana/tsconfig" "^1.0.0-rc1"
|
||||||
|
"@iconscout/react-unicons" "1.1.4"
|
||||||
|
"@popperjs/core" "2.5.4"
|
||||||
|
"@sentry/browser" "5.25.0"
|
||||||
|
"@testing-library/jest-dom" "5.11.9"
|
||||||
|
"@torkelo/react-select" "3.0.8"
|
||||||
|
"@types/hoist-non-react-statics" "3.3.1"
|
||||||
|
"@types/react-beautiful-dnd" "12.1.2"
|
||||||
|
"@types/react-color" "3.0.1"
|
||||||
|
"@types/react-select" "3.0.8"
|
||||||
|
"@types/react-table" "7.0.12"
|
||||||
|
"@types/slate" "0.47.1"
|
||||||
|
"@types/slate-react" "0.22.5"
|
||||||
|
"@visx/event" "1.3.0"
|
||||||
|
"@visx/gradient" "1.0.0"
|
||||||
|
"@visx/scale" "1.4.0"
|
||||||
|
"@visx/shape" "1.4.0"
|
||||||
|
"@visx/tooltip" "1.3.0"
|
||||||
|
classnames "2.2.6"
|
||||||
|
d3 "5.15.0"
|
||||||
|
emotion "10.0.27"
|
||||||
|
hoist-non-react-statics "3.3.2"
|
||||||
|
immutable "3.8.2"
|
||||||
|
jquery "3.5.1"
|
||||||
|
lodash "4.17.21"
|
||||||
|
moment "2.24.0"
|
||||||
|
monaco-editor "0.20.0"
|
||||||
|
papaparse "5.3.0"
|
||||||
|
rc-cascader "1.0.1"
|
||||||
|
rc-drawer "3.1.3"
|
||||||
|
rc-slider "9.6.4"
|
||||||
|
rc-time-picker "^3.7.3"
|
||||||
|
react "17.0.1"
|
||||||
|
react-beautiful-dnd "13.0.0"
|
||||||
|
react-calendar "2.19.2"
|
||||||
|
react-color "2.18.0"
|
||||||
|
react-custom-scrollbars "4.2.1"
|
||||||
|
react-dom "17.0.1"
|
||||||
|
react-highlight-words "0.16.0"
|
||||||
|
react-hook-form "5.1.3"
|
||||||
|
react-monaco-editor "0.36.0"
|
||||||
|
react-popper "2.2.4"
|
||||||
|
react-storybook-addon-props-combinations "1.1.0"
|
||||||
|
react-table "7.0.0"
|
||||||
|
react-transition-group "4.4.1"
|
||||||
|
slate "0.47.8"
|
||||||
|
tinycolor2 "1.4.1"
|
||||||
|
uplot "1.6.4"
|
||||||
|
|
||||||
"@icons/material@^0.2.4":
|
"@icons/material@^0.2.4":
|
||||||
version "0.2.4"
|
version "0.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
resolved "https://registry.yarnpkg.com/@icons/material/-/material-0.2.4.tgz#e90c9f71768b3736e76d7dd6783fc6c2afa88bc8"
|
||||||
|
|||||||
Reference in New Issue
Block a user