* feat(cloud-monitoring): add support for Google Cloud universe_domain (#110083) This change introduces support for Google Cloud's `universe_domain`, enabling connections to sovereign cloud environments with custom API endpoints. - Adds an optional "Universe Domain" field in the Google Cloud Monitoring data source configuration (frontend and backend). - Allows specifying a custom API domain (e.g., `s3nsapis.fr`) for use in sovereign environments. - Defaults to `googleapis.com` to ensure backward compatibility for existing configurations. Signed-off-by: Andreas Christou <andreas.christou@grafana.com> * Minor docs update * Doc updates * Update editor * Update docs/sources/datasources/google-cloud-monitoring/_index.md Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com> * Lint * Review --------- Signed-off-by: Andreas Christou <andreas.christou@grafana.com> Co-authored-by: Larissa Wandzura <126723338+lwandz13@users.noreply.github.com>
87 lines
2.4 KiB
Go
87 lines
2.4 KiB
Go
package cloudmonitoring
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/grafana/grafana-google-sdk-go/pkg/tokenprovider"
|
|
"github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
|
|
)
|
|
|
|
const (
|
|
cloudMonitor = "cloudmonitoring"
|
|
resourceManager = "cloudresourcemanager"
|
|
cloudMonitorScope = "https://www.googleapis.com/auth/monitoring.read"
|
|
resourceManagerScope = "https://www.googleapis.com/auth/cloudplatformprojects.readonly"
|
|
)
|
|
|
|
type routeInfo struct {
|
|
method string
|
|
url string
|
|
scopes []string
|
|
}
|
|
|
|
var routes = map[string]routeInfo{
|
|
cloudMonitor: {
|
|
method: "GET",
|
|
url: "https://monitoring.",
|
|
scopes: []string{cloudMonitorScope},
|
|
},
|
|
resourceManager: {
|
|
method: "GET",
|
|
url: "https://cloudresourcemanager.",
|
|
scopes: []string{resourceManagerScope},
|
|
},
|
|
}
|
|
|
|
func getMiddleware(model *datasourceInfo, routePath string) (httpclient.Middleware, error) {
|
|
providerConfig := tokenprovider.Config{
|
|
RoutePath: routePath,
|
|
RouteMethod: routes[routePath].method,
|
|
DataSourceID: model.id,
|
|
DataSourceUpdated: model.updated,
|
|
Scopes: routes[routePath].scopes,
|
|
}
|
|
|
|
var provider tokenprovider.TokenProvider
|
|
switch model.authenticationType {
|
|
case gceAuthentication:
|
|
if model.usingImpersonation {
|
|
providerConfig.TargetPrincipal = model.serviceAccountToImpersonate
|
|
provider = tokenprovider.NewImpersonatedGceAccessTokenProvider(providerConfig)
|
|
} else {
|
|
provider = tokenprovider.NewGceAccessTokenProvider(providerConfig)
|
|
}
|
|
case jwtAuthentication:
|
|
providerConfig.JwtTokenConfig = &tokenprovider.JwtTokenConfig{
|
|
Email: model.clientEmail,
|
|
URI: model.tokenUri,
|
|
PrivateKey: []byte(model.privateKey),
|
|
}
|
|
if model.usingImpersonation {
|
|
providerConfig.TargetPrincipal = model.serviceAccountToImpersonate
|
|
provider = tokenprovider.NewImpersonatedJwtAccessTokenProvider(providerConfig)
|
|
} else {
|
|
provider = tokenprovider.NewJwtAccessTokenProvider(providerConfig)
|
|
}
|
|
}
|
|
|
|
return tokenprovider.AuthMiddleware(provider), nil
|
|
}
|
|
|
|
func buildURL(route string, universeDomain string) string {
|
|
if universeDomain == "" {
|
|
universeDomain = "googleapis.com"
|
|
}
|
|
return routes[route].url + universeDomain
|
|
}
|
|
|
|
func newHTTPClient(model *datasourceInfo, opts httpclient.Options, clientProvider *httpclient.Provider, route string) (*http.Client, error) {
|
|
m, err := getMiddleware(model, route)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
opts.Middlewares = append(opts.Middlewares, m)
|
|
return clientProvider.New(opts)
|
|
}
|