From 562d8dba5d52e6b7654cc2a82b9f15aa6db253f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zolt=C3=A1n=20Bedi?= Date: Wed, 29 Mar 2023 12:16:28 +0200 Subject: [PATCH] CloudMonitoring: Update sdks to latest (#65252) * Upgrade grafana-google-sdk-go to v0.1.0 * Upgrade @grafana/google-sdk to 0.1.1 * Update doc with provisioning example * Remove unused types * Use config types from the sdk * Add metrics --- .../google-cloud-monitoring/_index.md | 17 +++++++++++ go.mod | 2 +- go.sum | 2 ++ package.json | 2 +- pkg/tsdb/cloudmonitoring/cloudmonitoring.go | 29 ++++++++++--------- .../cloudmonitoring/cloudmonitoring_test.go | 2 +- pkg/tsdb/cloudmonitoring/httpclient.go | 12 ++++---- pkg/tsdb/cloudmonitoring/resource_handler.go | 2 +- .../cloudmonitoring/resource_handler_test.go | 2 +- .../components/ConfigEditor/ConfigEditor.tsx | 14 ++++++++- .../datasource/cloud-monitoring/constants.ts | 6 ---- .../datasource/cloud-monitoring/types.ts | 19 +++--------- yarn.lock | 15 ++++++---- 13 files changed, 74 insertions(+), 50 deletions(-) diff --git a/docs/sources/datasources/google-cloud-monitoring/_index.md b/docs/sources/datasources/google-cloud-monitoring/_index.md index 8626b5b9bd2..136be2fc9dd 100644 --- a/docs/sources/datasources/google-cloud-monitoring/_index.md +++ b/docs/sources/datasources/google-cloud-monitoring/_index.md @@ -108,6 +108,23 @@ datasources: -----END PRIVATE KEY----- ``` +**Using the JWT (Service Account private key path) authentication type:** + +```yaml +apiVersion: 1 + +datasources: + - name: Google Cloud Monitoring + type: stackdriver + access: proxy + jsonData: + tokenUri: https://oauth2.googleapis.com/token + clientEmail: stackdriver@myproject.iam.gserviceaccount.com + authenticationType: jwt + defaultProject: my-project-name + privateKeyPath: /etc/secrets/gce.pem +``` + **Using GCE Default Service Account authentication:** ```yaml diff --git a/go.mod b/go.mod index 187fc57d730..bd975e943e4 100644 --- a/go.mod +++ b/go.mod @@ -180,7 +180,7 @@ require ( github.com/google/flatbuffers v2.0.8+incompatible // indirect github.com/googleapis/gax-go/v2 v2.7.0 github.com/gorilla/mux v1.8.0 // indirect - github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58 + github.com/grafana/grafana-google-sdk-go v0.1.0 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.1-0.20191002090509-6af20e3a5340 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-msgpack v0.5.5 // indirect diff --git a/go.sum b/go.sum index 1cb3450bcb2..bf33026cbc3 100644 --- a/go.sum +++ b/go.sum @@ -1272,6 +1272,8 @@ github.com/grafana/grafana-azure-sdk-go v1.6.0 h1:lxvH/mVY7gKBtJKhZ4B/6tIZFY7Jth github.com/grafana/grafana-azure-sdk-go v1.6.0/go.mod h1:X4PdEQIYgHfn0KTa2ZTKvufhNz6jbCEKUQPZIlcyOGw= github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58 h1:2ud7NNM7LrGPO4x0NFR8qLq68CqI4SmB7I2yRN2w9oE= github.com/grafana/grafana-google-sdk-go v0.0.0-20211104130251-b190293eaf58/go.mod h1:Vo2TKWfDVmNTELBUM+3lkrZvFtBws0qSZdXhQxRdJrE= +github.com/grafana/grafana-google-sdk-go v0.1.0 h1:LKGY8z2DSxKjYfr2flZsWgTRTZ6HGQbTqewE3JvRaNA= +github.com/grafana/grafana-google-sdk-go v0.1.0/go.mod h1:Vo2TKWfDVmNTELBUM+3lkrZvFtBws0qSZdXhQxRdJrE= github.com/grafana/grafana-plugin-sdk-go v0.94.0/go.mod h1:3VXz4nCv6wH5SfgB3mlW39s+c+LetqSCjFj7xxPC5+M= github.com/grafana/grafana-plugin-sdk-go v0.114.0/go.mod h1:D7x3ah+1d4phNXpbnOaxa/osSaZlwh9/ZUnGGzegRbk= github.com/grafana/grafana-plugin-sdk-go v0.153.0 h1:5Z3NU/W32BsElkiqalvh6ow0Mx81GhAk94+GddIuTrQ= diff --git a/package.json b/package.json index b6f64477d2c..1481eea5a15 100644 --- a/package.json +++ b/package.json @@ -263,7 +263,7 @@ "@grafana/experimental": "1.1.0", "@grafana/faro-core": "1.0.2", "@grafana/faro-web-sdk": "1.0.2", - "@grafana/google-sdk": "0.0.4", + "@grafana/google-sdk": "0.1.1", "@grafana/lezer-logql": "0.1.2", "@grafana/monaco-logql": "^0.0.7", "@grafana/runtime": "workspace:*", diff --git a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go index 1bc46bb5655..dd289beec01 100644 --- a/pkg/tsdb/cloudmonitoring/cloudmonitoring.go +++ b/pkg/tsdb/cloudmonitoring/cloudmonitoring.go @@ -131,7 +131,7 @@ type Service struct { resourceHandler backend.CallResourceHandler // mocked in tests - gceDefaultProjectGetter func(ctx context.Context) (string, error) + gceDefaultProjectGetter func(ctx context.Context, scope string) (string, error) } type datasourceInfo struct { @@ -143,8 +143,7 @@ type datasourceInfo struct { clientEmail string tokenUri string services map[string]datasourceService - - decryptedSecureJSONData map[string]string + privateKey string } type datasourceJSONData struct { @@ -172,15 +171,19 @@ func newInstanceSettings(httpClientProvider httpclient.Provider) datasource.Inst } dsInfo := &datasourceInfo{ - id: settings.ID, - updated: settings.Updated, - url: settings.URL, - authenticationType: jsonData.AuthenticationType, - defaultProject: jsonData.DefaultProject, - clientEmail: jsonData.ClientEmail, - tokenUri: jsonData.TokenURI, - decryptedSecureJSONData: settings.DecryptedSecureJSONData, - services: map[string]datasourceService{}, + id: settings.ID, + updated: settings.Updated, + url: settings.URL, + authenticationType: jsonData.AuthenticationType, + defaultProject: jsonData.DefaultProject, + clientEmail: jsonData.ClientEmail, + tokenUri: jsonData.TokenURI, + services: map[string]datasourceService{}, + } + + dsInfo.privateKey, err = utils.GetPrivateKey(&settings) + if err != nil { + return nil, err } opts, err := settings.HTTPClientOptions() @@ -571,7 +574,7 @@ func (s *Service) ensureProject(ctx context.Context, dsInfo datasourceInfo, proj func (s *Service) getDefaultProject(ctx context.Context, dsInfo datasourceInfo) (string, error) { if dsInfo.authenticationType == gceAuthentication { - return s.gceDefaultProjectGetter(ctx) + return s.gceDefaultProjectGetter(ctx, cloudMonitorScope) } return dsInfo.defaultProject, nil } diff --git a/pkg/tsdb/cloudmonitoring/cloudmonitoring_test.go b/pkg/tsdb/cloudmonitoring/cloudmonitoring_test.go index 5209b122edc..b6692bc5a53 100644 --- a/pkg/tsdb/cloudmonitoring/cloudmonitoring_test.go +++ b/pkg/tsdb/cloudmonitoring/cloudmonitoring_test.go @@ -1150,7 +1150,7 @@ func TestCheckHealth(t *testing.T) { }) service := &Service{ im: im, - gceDefaultProjectGetter: func(ctx context.Context) (string, error) { + gceDefaultProjectGetter: func(ctx context.Context, scope string) (string, error) { return "", fmt.Errorf("not found!") }, } diff --git a/pkg/tsdb/cloudmonitoring/httpclient.go b/pkg/tsdb/cloudmonitoring/httpclient.go index b104e53dd38..c0f262a668d 100644 --- a/pkg/tsdb/cloudmonitoring/httpclient.go +++ b/pkg/tsdb/cloudmonitoring/httpclient.go @@ -9,8 +9,10 @@ import ( ) const ( - cloudMonitor = "cloudmonitoring" - resourceManager = "cloudresourcemanager" + cloudMonitor = "cloudmonitoring" + resourceManager = "cloudresourcemanager" + cloudMonitorScope = "https://www.googleapis.com/auth/monitoring.read" + resourceManagerScope = "https://www.googleapis.com/auth/cloudplatformprojects.readonly" ) type routeInfo struct { @@ -23,12 +25,12 @@ var routes = map[string]routeInfo{ cloudMonitor: { method: "GET", url: "https://monitoring.googleapis.com", - scopes: []string{"https://www.googleapis.com/auth/monitoring.read"}, + scopes: []string{cloudMonitorScope}, }, resourceManager: { method: "GET", url: "https://cloudresourcemanager.googleapis.com", - scopes: []string{"https://www.googleapis.com/auth/cloudplatformprojects.readonly"}, + scopes: []string{resourceManagerScope}, }, } @@ -49,7 +51,7 @@ func getMiddleware(model *datasourceInfo, routePath string) (httpclient.Middlewa providerConfig.JwtTokenConfig = &tokenprovider.JwtTokenConfig{ Email: model.clientEmail, URI: model.tokenUri, - PrivateKey: []byte(model.decryptedSecureJSONData["privateKey"]), + PrivateKey: []byte(model.privateKey), } provider = tokenprovider.NewJwtAccessTokenProvider(providerConfig) } diff --git a/pkg/tsdb/cloudmonitoring/resource_handler.go b/pkg/tsdb/cloudmonitoring/resource_handler.go index bbc582868a4..0066e27c1d5 100644 --- a/pkg/tsdb/cloudmonitoring/resource_handler.go +++ b/pkg/tsdb/cloudmonitoring/resource_handler.go @@ -34,7 +34,7 @@ func (s *Service) newResourceMux() *http.ServeMux { } func (s *Service) getGCEDefaultProject(rw http.ResponseWriter, req *http.Request) { - project, err := s.gceDefaultProjectGetter(req.Context()) + project, err := s.gceDefaultProjectGetter(req.Context(), resourceManagerScope) if err != nil { writeResponse(rw, http.StatusBadRequest, fmt.Sprintf("unexpected error %v", err)) return diff --git a/pkg/tsdb/cloudmonitoring/resource_handler_test.go b/pkg/tsdb/cloudmonitoring/resource_handler_test.go index 05453795997..f74a6cd346b 100644 --- a/pkg/tsdb/cloudmonitoring/resource_handler_test.go +++ b/pkg/tsdb/cloudmonitoring/resource_handler_test.go @@ -300,7 +300,7 @@ func Test_getGCEDefaultProject(t *testing.T) { }, }, }, - gceDefaultProjectGetter: func(ctx context.Context) (string, error) { + gceDefaultProjectGetter: func(ctx context.Context, scope string) (string, error) { return project, nil }, } diff --git a/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx b/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx index 26d7d6a771b..f9502bf1ddb 100644 --- a/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx +++ b/public/app/plugins/datasource/cloud-monitoring/components/ConfigEditor/ConfigEditor.tsx @@ -2,6 +2,7 @@ import React, { PureComponent } from 'react'; import { DataSourcePluginOptionsEditorProps } from '@grafana/data'; import { ConnectionConfig } from '@grafana/google-sdk'; +import { reportInteraction } from '@grafana/runtime'; import { SecureSocksProxySettings } from '@grafana/ui'; import { config } from 'app/core/config'; @@ -10,11 +11,22 @@ import { CloudMonitoringOptions, CloudMonitoringSecureJsonData } from '../../typ export type Props = DataSourcePluginOptionsEditorProps; export class ConfigEditor extends PureComponent { + handleOnOptionsChange = (options: Props['options']) => { + if (options.jsonData.privateKeyPath || options.secureJsonFields['privateKey']) { + reportInteraction('grafana_cloud_monitoring_config_changed', { + authenticationType: 'JWT', + privateKey: options.secureJsonFields['privateKey'], + privateKeyPath: !!options.jsonData.privateKeyPath, + }); + } + this.props.onOptionsChange(options); + }; + render() { const { options, onOptionsChange } = this.props; return ( <> - + {config.featureToggles.secureSocksDatasourceProxy && ( )} diff --git a/public/app/plugins/datasource/cloud-monitoring/constants.ts b/public/app/plugins/datasource/cloud-monitoring/constants.ts index e916247cb8e..050cf08dfcd 100644 --- a/public/app/plugins/datasource/cloud-monitoring/constants.ts +++ b/public/app/plugins/datasource/cloud-monitoring/constants.ts @@ -1,5 +1,3 @@ -import { GoogleAuthType } from '@grafana/google-sdk'; - import { MetricKind, QueryType, ValueTypes } from './types'; // not super excited about using uneven numbers, but this makes it align perfectly with rows that has two fields @@ -7,10 +5,6 @@ export const INPUT_WIDTH = 71; export const LABEL_WIDTH = 19; export const INNER_LABEL_WIDTH = 14; export const SELECT_WIDTH = 28; -export const AUTH_TYPES = [ - { value: 'Google JWT File', key: GoogleAuthType.JWT }, - { value: 'GCE Default Service Account', key: GoogleAuthType.GCE }, -]; export const ALIGNMENTS = [ { diff --git a/public/app/plugins/datasource/cloud-monitoring/types.ts b/public/app/plugins/datasource/cloud-monitoring/types.ts index d20e951f4f2..6e7cc4c8904 100644 --- a/public/app/plugins/datasource/cloud-monitoring/types.ts +++ b/public/app/plugins/datasource/cloud-monitoring/types.ts @@ -1,10 +1,5 @@ -import { DataQuery, DataSourceJsonData, SelectableValue } from '@grafana/data'; -import { GoogleAuthType } from '@grafana/google-sdk'; - -export const authTypes: Array> = [ - { label: 'Google JWT File', value: GoogleAuthType.JWT }, - { label: 'GCE Default Service Account', value: GoogleAuthType.GCE }, -]; +import { DataQuery, SelectableValue } from '@grafana/data'; +import { DataSourceOptions, DataSourceSecureJsonData } from '@grafana/google-sdk'; export enum MetricFindQueryTypes { Projects = 'projects', @@ -179,17 +174,11 @@ export interface CloudMonitoringQuery extends DataQuery { intervalMs: number; } -export interface CloudMonitoringOptions extends DataSourceJsonData { - defaultProject?: string; +export interface CloudMonitoringOptions extends DataSourceOptions { gceDefaultProject?: string; - authenticationType: GoogleAuthType; - clientEmail?: string; - tokenUri?: string; } -export interface CloudMonitoringSecureJsonData { - privateKey?: string; -} +export interface CloudMonitoringSecureJsonData extends DataSourceSecureJsonData {} export interface LegacyCloudMonitoringAnnotationQuery { projectName: string; diff --git a/yarn.lock b/yarn.lock index da95550061a..8be5c94f9fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5279,10 +5279,15 @@ __metadata: languageName: node linkType: hard -"@grafana/google-sdk@npm:0.0.4": - version: 0.0.4 - resolution: "@grafana/google-sdk@npm:0.0.4" - checksum: f8a1abfba7c7e41d197ff576a4afa1216e157e0803717f3d836e4c5050d173582757e195ff44f17a31946482f5bb32941bc9f6d62ea1fab84edfeaccd065cb6d +"@grafana/google-sdk@npm:0.1.1": + version: 0.1.1 + resolution: "@grafana/google-sdk@npm:0.1.1" + peerDependencies: + "@grafana/data": 9.4.1 + "@grafana/ui": 9.4.1 + react: 17.0.2 + react-dom: 17.0.2 + checksum: a49e8b09eed421ddaed0e32ef5e7bed55d2342550cdf6c0b59b60f4a038ccb3a31566ca55ad0e22c3a6c8ad145d534c31de949df07ec6eb4f4c5c6e4ce778cc7 languageName: node linkType: hard @@ -22138,7 +22143,7 @@ __metadata: "@grafana/experimental": 1.1.0 "@grafana/faro-core": 1.0.2 "@grafana/faro-web-sdk": 1.0.2 - "@grafana/google-sdk": 0.0.4 + "@grafana/google-sdk": 0.1.1 "@grafana/lezer-logql": 0.1.2 "@grafana/monaco-logql": ^0.0.7 "@grafana/runtime": "workspace:*"