mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudMonitoring: Migrate config editor from angular to react (#33645)
* fix broken config ctrl * replace angular config with react config editor * remove not used code * add extra linebreak * add noopener to link * only test jwt props that we actually need
This commit is contained in:
parent
1c58fd380f
commit
1a59117343
@ -0,0 +1,110 @@
|
|||||||
|
import React, { PureComponent } from 'react';
|
||||||
|
import { Select, FieldSet, InlineField, Alert } from '@grafana/ui';
|
||||||
|
import { DataSourcePluginOptionsEditorProps, onUpdateDatasourceJsonDataOptionSelect } from '@grafana/data';
|
||||||
|
import { AuthType, authTypes, CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../types';
|
||||||
|
import { JWTConfig } from './JWTConfig';
|
||||||
|
|
||||||
|
export type Props = DataSourcePluginOptionsEditorProps<CloudMonitoringOptions, CloudMonitoringSecureJsonData>;
|
||||||
|
|
||||||
|
export class ConfigEditor extends PureComponent<Props> {
|
||||||
|
render() {
|
||||||
|
const { options, onOptionsChange } = this.props;
|
||||||
|
const { secureJsonFields, jsonData } = options;
|
||||||
|
|
||||||
|
if (!jsonData.hasOwnProperty('authenticationType')) {
|
||||||
|
jsonData.authenticationType = AuthType.JWT;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<div className="gf-form-group">
|
||||||
|
<div className="grafana-info-box">
|
||||||
|
<h4>Google Cloud Monitoring Authentication</h4>
|
||||||
|
<p>
|
||||||
|
There are two ways to authenticate the Google Cloud Monitoring plugin - either by uploading a Service
|
||||||
|
Account key file or by automatically retrieving credentials from the Google metadata server. The latter
|
||||||
|
option is only available when running Grafana on a GCE virtual machine.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h5>Uploading a Service Account Key File</h5>
|
||||||
|
<p>
|
||||||
|
There are two ways to authenticate the Google Cloud Monitoring plugin. You can upload a Service Account
|
||||||
|
key file or automatically retrieve credentials from the Google metadata server. The latter option is only
|
||||||
|
available when running Grafana on a GCE virtual machine.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
The <strong>Monitoring Viewer</strong> role provides all the permissions that Grafana needs. The following
|
||||||
|
API needs to be enabled on GCP for the data source to work:{' '}
|
||||||
|
<a
|
||||||
|
className="external-link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="https://console.cloud.google.com/apis/library/monitoring.googleapis.com"
|
||||||
|
>
|
||||||
|
Monitoring API
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h5>GCE Default Service Account</h5>
|
||||||
|
<p>
|
||||||
|
If Grafana is running on a Google Compute Engine (GCE) virtual machine, it is possible for Grafana to
|
||||||
|
automatically retrieve the default project id and authentication token from the metadata server. In order
|
||||||
|
for this to work, you need to make sure that you have a service account that is setup as the default
|
||||||
|
account for the virtual machine and that the service account has been given read access to the Google
|
||||||
|
Cloud Monitoring Monitoring API.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Detailed instructions on how to create a Service Account can be found{' '}
|
||||||
|
<a
|
||||||
|
className="external-link"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
href="https://grafana.com/docs/grafana/latest/datasources/google-cloud-monitoring/"
|
||||||
|
>
|
||||||
|
in the documentation.
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<FieldSet>
|
||||||
|
<InlineField label="Authentication type" labelWidth={20}>
|
||||||
|
<Select
|
||||||
|
width={40}
|
||||||
|
value={authTypes.find((x) => x.value === jsonData.authenticationType) || authTypes[0]}
|
||||||
|
options={authTypes}
|
||||||
|
defaultValue={jsonData.authenticationType}
|
||||||
|
onChange={onUpdateDatasourceJsonDataOptionSelect(this.props, 'authenticationType')}
|
||||||
|
/>
|
||||||
|
</InlineField>
|
||||||
|
{jsonData.authenticationType === AuthType.JWT && (
|
||||||
|
<JWTConfig
|
||||||
|
isConfigured={secureJsonFields && !!secureJsonFields.jwt}
|
||||||
|
onChange={({ private_key, client_email, project_id, token_uri }) => {
|
||||||
|
onOptionsChange({
|
||||||
|
...options,
|
||||||
|
secureJsonData: {
|
||||||
|
...options.secureJsonData,
|
||||||
|
privateKey: private_key,
|
||||||
|
},
|
||||||
|
jsonData: {
|
||||||
|
...options.jsonData,
|
||||||
|
defaultProject: project_id,
|
||||||
|
clientEmail: client_email,
|
||||||
|
tokenUri: token_uri,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
></JWTConfig>
|
||||||
|
)}
|
||||||
|
</FieldSet>
|
||||||
|
{jsonData.authenticationType === AuthType.GCE && (
|
||||||
|
<Alert title="" severity="info">
|
||||||
|
Verify GCE default service account by clicking Save & Test
|
||||||
|
</Alert>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
import React, { FormEvent, useState } from 'react';
|
||||||
|
import { startCase } from 'lodash';
|
||||||
|
import { Button, FileUpload, InlineField, Input, useStyles, Alert } from '@grafana/ui';
|
||||||
|
import { css, cx } from '@emotion/css';
|
||||||
|
import { GrafanaTheme } from '@grafana/data';
|
||||||
|
|
||||||
|
const configKeys = ['project_id', 'private_key', 'client_email', 'token_uri'];
|
||||||
|
|
||||||
|
export interface JWT {
|
||||||
|
token_uri: string;
|
||||||
|
client_email: string;
|
||||||
|
private_key: string;
|
||||||
|
project_id: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
onChange: (jwt: JWT) => void;
|
||||||
|
isConfigured: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const validateJson = (json: JWT): json is JWT => {
|
||||||
|
return !!json.token_uri && !!json.client_email && !!json.project_id && !!json.project_id;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function JWTConfig({ onChange, isConfigured }: Props) {
|
||||||
|
const styles = useStyles(getStyles);
|
||||||
|
const [enableUpload, setEnableUpload] = useState<boolean>(!isConfigured);
|
||||||
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
|
||||||
|
return enableUpload ? (
|
||||||
|
<>
|
||||||
|
<FileUpload
|
||||||
|
className={styles}
|
||||||
|
accept="application/json"
|
||||||
|
onFileUpload={(event: FormEvent<HTMLInputElement>) => {
|
||||||
|
if (event?.currentTarget?.files?.length === 1) {
|
||||||
|
setError(null);
|
||||||
|
const reader = new FileReader();
|
||||||
|
const readerOnLoad = () => {
|
||||||
|
return (e: any) => {
|
||||||
|
const json = JSON.parse(e.target.result);
|
||||||
|
if (validateJson(json)) {
|
||||||
|
onChange(json);
|
||||||
|
setEnableUpload(false);
|
||||||
|
} else {
|
||||||
|
setError('Invalid JWT file');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
reader.onload = readerOnLoad();
|
||||||
|
reader.readAsText(event.currentTarget.files[0]);
|
||||||
|
} else {
|
||||||
|
setError('You can only upload one file');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Upload service account key file
|
||||||
|
</FileUpload>
|
||||||
|
|
||||||
|
{error && <p className={cx(styles, 'alert')}>{error}</p>}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{configKeys.map((key, i) => (
|
||||||
|
<InlineField label={startCase(key)} key={i} labelWidth={20} disabled>
|
||||||
|
<Input width={40} placeholder="configured" />
|
||||||
|
</InlineField>
|
||||||
|
))}
|
||||||
|
<Button variant="secondary" onClick={() => setEnableUpload(true)} className={styles}>
|
||||||
|
Upload another JWT file
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Alert title="" className={styles} severity="info">
|
||||||
|
Do not forget to save your changes after uploading a file
|
||||||
|
</Alert>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getStyles = (theme: GrafanaTheme) => css`
|
||||||
|
margin: ${theme.spacing.md} 0 0;
|
||||||
|
`;
|
@ -1,101 +0,0 @@
|
|||||||
import DatasourceSrv from 'app/features/plugins/datasource_srv';
|
|
||||||
import { AuthType, authTypes } from './types';
|
|
||||||
|
|
||||||
export interface JWT {
|
|
||||||
private_key: string;
|
|
||||||
token_uri: string;
|
|
||||||
client_email: string;
|
|
||||||
project_id: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class CloudMonitoringConfigCtrl {
|
|
||||||
static templateUrl = 'public/app/plugins/datasource/cloud-monitoring/partials/config.html';
|
|
||||||
|
|
||||||
// Set through angular bindings
|
|
||||||
declare current: any;
|
|
||||||
declare meta: any;
|
|
||||||
|
|
||||||
datasourceSrv: DatasourceSrv;
|
|
||||||
jsonText: string;
|
|
||||||
validationErrors: string[] = [];
|
|
||||||
inputDataValid: boolean;
|
|
||||||
authenticationTypes: Array<{ key: AuthType; value: string }>;
|
|
||||||
defaultAuthenticationType: string;
|
|
||||||
name: string;
|
|
||||||
|
|
||||||
/** @ngInject */
|
|
||||||
constructor(datasourceSrv: DatasourceSrv) {
|
|
||||||
this.defaultAuthenticationType = AuthType.JWT;
|
|
||||||
this.datasourceSrv = datasourceSrv;
|
|
||||||
this.name = this.meta.name;
|
|
||||||
this.current.jsonData = this.current.jsonData || {};
|
|
||||||
this.current.jsonData.authenticationType = this.current.jsonData.authenticationType
|
|
||||||
? this.current.jsonData.authenticationType
|
|
||||||
: this.defaultAuthenticationType;
|
|
||||||
this.current.secureJsonData = this.current.secureJsonData || {};
|
|
||||||
this.current.secureJsonFields = this.current.secureJsonFields || {};
|
|
||||||
this.authenticationTypes = authTypes;
|
|
||||||
}
|
|
||||||
|
|
||||||
save(jwt: JWT) {
|
|
||||||
this.current.secureJsonData.privateKey = jwt.private_key;
|
|
||||||
this.current.jsonData.tokenUri = jwt.token_uri;
|
|
||||||
this.current.jsonData.clientEmail = jwt.client_email;
|
|
||||||
this.current.jsonData.defaultProject = jwt.project_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
validateJwt(jwt: JWT) {
|
|
||||||
this.resetValidationMessages();
|
|
||||||
if (!jwt.private_key || jwt.private_key.length === 0) {
|
|
||||||
this.validationErrors.push('Private key field missing in JWT file.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jwt.token_uri || jwt.token_uri.length === 0) {
|
|
||||||
this.validationErrors.push('Token URI field missing in JWT file.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jwt.client_email || jwt.client_email.length === 0) {
|
|
||||||
this.validationErrors.push('Client Email field missing in JWT file.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!jwt.project_id || jwt.project_id.length === 0) {
|
|
||||||
this.validationErrors.push('Project Id field missing in JWT file.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.validationErrors.length === 0) {
|
|
||||||
this.inputDataValid = true;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
onUpload(json: JWT) {
|
|
||||||
this.jsonText = '';
|
|
||||||
if (this.validateJwt(json)) {
|
|
||||||
this.save(json);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onPasteJwt(e: any) {
|
|
||||||
try {
|
|
||||||
const json = JSON.parse(e.originalEvent.clipboardData.getData('text/plain') || this.jsonText);
|
|
||||||
if (this.validateJwt(json)) {
|
|
||||||
this.save(json);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
this.resetValidationMessages();
|
|
||||||
this.validationErrors.push(`Invalid json: ${error.message}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resetValidationMessages() {
|
|
||||||
this.validationErrors = [];
|
|
||||||
this.inputDataValid = false;
|
|
||||||
this.jsonText = '';
|
|
||||||
|
|
||||||
this.current.jsonData = Object.assign({}, { authenticationType: this.current.jsonData.authenticationType });
|
|
||||||
this.current.secureJsonData = {};
|
|
||||||
this.current.secureJsonFields = {};
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +1,14 @@
|
|||||||
import { DataSourcePlugin } from '@grafana/data';
|
import { DataSourcePlugin } from '@grafana/data';
|
||||||
import CloudMonitoringDatasource from './datasource';
|
import CloudMonitoringDatasource from './datasource';
|
||||||
import { QueryEditor } from './components/QueryEditor';
|
import { QueryEditor } from './components/QueryEditor';
|
||||||
import { CloudMonitoringConfigCtrl } from './config_ctrl';
|
import { ConfigEditor } from './components/ConfigEditor/ConfigEditor';
|
||||||
|
|
||||||
import { CloudMonitoringAnnotationsQueryCtrl } from './annotations_query_ctrl';
|
import { CloudMonitoringAnnotationsQueryCtrl } from './annotations_query_ctrl';
|
||||||
import { CloudMonitoringVariableQueryEditor } from './components/VariableQueryEditor';
|
import { CloudMonitoringVariableQueryEditor } from './components/VariableQueryEditor';
|
||||||
import { CloudMonitoringQuery } from './types';
|
import { CloudMonitoringQuery } from './types';
|
||||||
|
|
||||||
export const plugin = new DataSourcePlugin<CloudMonitoringDatasource, CloudMonitoringQuery>(CloudMonitoringDatasource)
|
export const plugin = new DataSourcePlugin<CloudMonitoringDatasource, CloudMonitoringQuery>(CloudMonitoringDatasource)
|
||||||
.setQueryEditor(QueryEditor)
|
.setQueryEditor(QueryEditor)
|
||||||
.setConfigCtrl(CloudMonitoringConfigCtrl)
|
.setConfigEditor(ConfigEditor)
|
||||||
.setAnnotationQueryCtrl(CloudMonitoringAnnotationsQueryCtrl)
|
.setAnnotationQueryCtrl(CloudMonitoringAnnotationsQueryCtrl)
|
||||||
.setVariableQueryEditor(CloudMonitoringVariableQueryEditor);
|
.setVariableQueryEditor(CloudMonitoringVariableQueryEditor);
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
<div class="gf-form-group">
|
|
||||||
<div class="grafana-info-box">
|
|
||||||
<h4>Google Cloud Monitoring Authentication</h4>
|
|
||||||
<p>
|
|
||||||
There are two ways to authenticate the Google Cloud Monitoring plugin - either by uploading a Service Account key file or by
|
|
||||||
automatically retrieving credentials from the Google metadata server. The latter option is only available when
|
|
||||||
running Grafana on a GCE virtual machine.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>Uploading a Service Account Key File</h5>
|
|
||||||
<p>
|
|
||||||
There are two ways to authenticate the Google Cloud Monitoring plugin. You can upload a Service Account key file or automatically retrieve
|
|
||||||
credentials from the Google metadata server. The latter option is only available when running Grafana on a GCE virtual machine.
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
The <strong>Monitoring Viewer</strong> role provides all the permissions that Grafana needs. The following API
|
|
||||||
needs to be enabled on GCP for the data source to work:
|
|
||||||
<a
|
|
||||||
class="external-link"
|
|
||||||
target="_blank"
|
|
||||||
href="https://console.cloud.google.com/apis/library/monitoring.googleapis.com"
|
|
||||||
>Monitoring API</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h5>GCE Default Service Account</h5>
|
|
||||||
<p>
|
|
||||||
If Grafana is running on a Google Compute Engine (GCE) virtual machine, it is possible for Grafana to
|
|
||||||
automatically retrieve the default project id and authentication token from the metadata server. In order for this
|
|
||||||
to work, you need to make sure that you have a service account that is setup as the default account for the
|
|
||||||
virtual machine and that the service account has been given read access to the Google Cloud Monitoring Monitoring API.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
Detailed instructions on how to create a Service Account can be found
|
|
||||||
<a class="external-link" target="_blank" href="https://grafana.com/docs/grafana/latest/datasources/google-cloud-monitoring/_index.md"
|
|
||||||
>in the documentation.</a
|
|
||||||
>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<div class="gf-form">
|
|
||||||
<h3>Authentication</h3>
|
|
||||||
<info-popover mode="header"
|
|
||||||
>Upload your Service Account key file or paste in the contents of the file. The file contents will be encrypted
|
|
||||||
and saved in the Grafana database.</info-popover
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form-inline">
|
|
||||||
<div class="gf-form max-width-30">
|
|
||||||
<span class="gf-form-label width-10">Authentication Type</span>
|
|
||||||
<div class="gf-form-select-wrapper max-width-24">
|
|
||||||
<select
|
|
||||||
class="gf-form-input"
|
|
||||||
ng-change="ctrl.gceError = ''"
|
|
||||||
ng-model="ctrl.current.jsonData.authenticationType"
|
|
||||||
ng-options="f.key as f.value for f in ctrl.authenticationTypes"
|
|
||||||
></select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
ng-if="ctrl.current.jsonData.authenticationType === ctrl.defaultAuthenticationType && !ctrl.current.jsonData.clientEmail && !ctrl.inputDataValid"
|
|
||||||
>
|
|
||||||
<div class="gf-form-group" ng-if="!ctrl.inputDataValid">
|
|
||||||
<div class="gf-form">
|
|
||||||
<form>
|
|
||||||
<dash-upload on-upload="ctrl.onUpload(dash)" btn-text="Upload Service Account key file"></dash-upload>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="gf-form-group">
|
|
||||||
<h5 class="section-heading" ng-if="!ctrl.inputDataValid">Or paste Service Account key JSON</h5>
|
|
||||||
<div class="gf-form" ng-if="!ctrl.inputDataValid">
|
|
||||||
<textarea
|
|
||||||
rows="10"
|
|
||||||
data-share-panel-url=""
|
|
||||||
class="gf-form-input"
|
|
||||||
ng-model="ctrl.jsonText"
|
|
||||||
ng-paste="ctrl.onPasteJwt($event)"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
<div ng-repeat="valError in ctrl.validationErrors" class="text-error p-l-1">
|
|
||||||
<icon name="'exclamation-triangle'"></icon>
|
|
||||||
{{valError}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="gf-form-group"
|
|
||||||
ng-if="ctrl.current.jsonData.authenticationType === ctrl.defaultAuthenticationType && (ctrl.inputDataValid || ctrl.current.jsonData.clientEmail)"
|
|
||||||
>
|
|
||||||
<h6>Uploaded Key Details</h6>
|
|
||||||
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-10">Project</span>
|
|
||||||
<input class="gf-form-input width-40" disabled type="text" ng-model="ctrl.current.jsonData.defaultProject" />
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-10">Client Email</span>
|
|
||||||
<input class="gf-form-input width-40" disabled type="text" ng-model="ctrl.current.jsonData.clientEmail" />
|
|
||||||
</div>
|
|
||||||
<div class="gf-form">
|
|
||||||
<span class="gf-form-label width-10">Token URI</span>
|
|
||||||
<input class="gf-form-input width-40" disabled type="text" ng-model="ctrl.current.jsonData.tokenUri" />
|
|
||||||
</div>
|
|
||||||
<div class="gf-form" ng-if="ctrl.current.secureJsonFields.privateKey">
|
|
||||||
<span class="gf-form-label width-10">Private Key</span>
|
|
||||||
<input type="text" class="gf-form-input max-width-12" disabled="disabled" value="configured" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="gf-form width-18" style="margin-top: 24px;">
|
|
||||||
<a class="btn btn-secondary gf-form-btn" href="#" ng-click="ctrl.resetValidationMessages()"
|
|
||||||
>Reset Service Account Key
|
|
||||||
</a>
|
|
||||||
<info-popover mode="right-normal">
|
|
||||||
Reset to clear the uploaded key and upload a new file.
|
|
||||||
</info-popover>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p
|
|
||||||
class="gf-form-label"
|
|
||||||
ng-hide="ctrl.current.secureJsonFields.privateKey || ctrl.current.jsonData.authenticationType !== ctrl.defaultAuthenticationType"
|
|
||||||
>
|
|
||||||
<icon name="'save'"></icon> Do not forget to save your changes after uploading a file.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="gf-form" ng-if="ctrl.gceError">
|
|
||||||
<pre class="gf-form-pre alert alert-error">{{ctrl.gceError}}</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="gf-form-label" ng-show="ctrl.current.jsonData.authenticationType !== ctrl.defaultAuthenticationType">
|
|
||||||
<icon name="'save'"></icon> Verify GCE default service account by clicking Save & Test
|
|
||||||
</p>
|
|
@ -5,9 +5,9 @@ export enum AuthType {
|
|||||||
GCE = 'gce',
|
GCE = 'gce',
|
||||||
}
|
}
|
||||||
|
|
||||||
export const authTypes = [
|
export const authTypes: Array<SelectableValue<string>> = [
|
||||||
{ value: 'Google JWT File', key: AuthType.JWT },
|
{ label: 'Google JWT File', value: AuthType.JWT },
|
||||||
{ value: 'GCE Default Service Account', key: AuthType.GCE },
|
{ label: 'GCE Default Service Account', value: AuthType.GCE },
|
||||||
];
|
];
|
||||||
|
|
||||||
export enum MetricFindQueryTypes {
|
export enum MetricFindQueryTypes {
|
||||||
@ -111,6 +111,12 @@ export interface CloudMonitoringOptions extends DataSourceJsonData {
|
|||||||
defaultProject?: string;
|
defaultProject?: string;
|
||||||
gceDefaultProject?: string;
|
gceDefaultProject?: string;
|
||||||
authenticationType?: string;
|
authenticationType?: string;
|
||||||
|
clientEmail?: string;
|
||||||
|
tokenUri?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CloudMonitoringSecureJsonData {
|
||||||
|
privateKey?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AnnotationTarget {
|
export interface AnnotationTarget {
|
||||||
|
Loading…
Reference in New Issue
Block a user