Plugins: Automatic service account (and token) setup (#76473)

* Update cue to have an AuthProvider entry

* Cable the new auth provider

* Add feature flag check to the accesscontrol service

* Fix test

* Change the structure of externalServiceRegistration (#76673)
This commit is contained in:
Gabriel MABILLE
2023-10-17 16:21:23 +02:00
committed by GitHub
parent 3bf9f97a89
commit 797a3c57af
15 changed files with 201 additions and 78 deletions
+3 -1
View File
@@ -59,8 +59,10 @@ func (s *Service) Get(ctx context.Context, p *plugins.Plugin) []string {
fmt.Sprintf("GF_APP_URL=%s", s.cfg.GrafanaAppURL),
fmt.Sprintf("GF_PLUGIN_APP_CLIENT_ID=%s", p.ExternalService.ClientID),
fmt.Sprintf("GF_PLUGIN_APP_CLIENT_SECRET=%s", p.ExternalService.ClientSecret),
fmt.Sprintf("GF_PLUGIN_APP_PRIVATE_KEY=%s", p.ExternalService.PrivateKey),
)
if p.ExternalService.PrivateKey != "" {
hostEnv = append(hostEnv, fmt.Sprintf("GF_PLUGIN_APP_PRIVATE_KEY=%s", p.ExternalService.PrivateKey))
}
}
hostEnv = append(hostEnv, s.featureToggleEnableVar(ctx)...)
+2 -3
View File
@@ -306,8 +306,8 @@ func TestInitializer_tracingEnvironmentVariables(t *testing.T) {
}
}
func TestInitializer_oauthEnvVars(t *testing.T) {
t.Run("backend datasource with oauth registration", func(t *testing.T) {
func TestInitializer_authEnvVars(t *testing.T) {
t.Run("backend datasource with auth registration", func(t *testing.T) {
p := &plugins.Plugin{
JSONData: plugins.JSONData{
ID: "test",
@@ -322,7 +322,6 @@ func TestInitializer_oauthEnvVars(t *testing.T) {
envVarsProvider := NewProvider(&config.Cfg{
GrafanaAppURL: "https://myorg.com/",
Features: featuremgmt.WithFeatures(featuremgmt.FlagExternalServiceAuth),
}, nil)
envVars := envVarsProvider.Get(context.Background(), p)
assert.Equal(t, "GF_VERSION=", envVars[0])
@@ -18,24 +18,11 @@
"version": "1.0.0"
},
"externalServiceRegistration": {
"impersonation": {
"enabled" : true,
"groups" : true,
"permissions" : [
{
"action": "read",
"scope": "datasource"
}
]
},
"self": {
"enabled" : true,
"permissions" : [
{
"action": "read",
"scope": "datasource"
}
]
}
"permissions" : [
{
"action": "read",
"scope": "datasource"
}
]
}
}
@@ -0,0 +1,38 @@
{
"id": "grafana-test-datasource",
"type": "datasource",
"name": "Test",
"backend": true,
"executable": "gpx_test_datasource",
"info": {
"author": {
"name": "Grafana Labs",
"url": "https://grafana.com"
},
"logos": {
"large": "img/ds.svg",
"small": "img/ds.svg"
},
"screenshots": [],
"updated": "2023-08-03",
"version": "1.0.0"
},
"externalServiceRegistration": {
"impersonation": {
"enabled" : true,
"groups" : true,
"permissions" : [
{
"action": "read",
"scope": "datasource"
}
]
},
"permissions" : [
{
"action": "read",
"scope": "datasource"
}
]
}
}
+3
View File
@@ -134,6 +134,9 @@ func TestParsePluginTestdata(t *testing.T) {
"external-registration": {
rootid: "grafana-test-datasource",
},
"oauth-external-registration": {
rootid: "grafana-test-datasource",
},
}
staticRootPath, err := filepath.Abs("../manager/testdata")
+6 -10
View File
@@ -413,11 +413,15 @@ schemas: [{
// External service registration information
externalServiceRegistration: #ExternalServiceRegistration
// ExternalServiceRegistration allows the service to get a service account token
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
#ExternalServiceRegistration: {
// Permissions are the permissions that the external service needs its associated service account to have.
permissions?: [...#Permission]
// Impersonation describes the permissions that the external service will have on behalf of the user
// This is only available with the OAuth2 Server
impersonation?: #Impersonation
// Self describes the permissions that the external service will have on behalf of itself
self?: #Self
}
#Impersonation: {
@@ -432,14 +436,6 @@ schemas: [{
// gain more privileges than the impersonated user has.
permissions?: [...#Permission]
}
#Self: {
// Enabled allows the service to request access tokens for itself using the client_credentials grant
// Defaults to true.
enabled?: bool
// Permissions are the permissions that the external service needs its associated service account to have.
permissions?: [...#Permission]
}
}
}]
lenses: []
+9 -13
View File
@@ -122,10 +122,13 @@ type Dependency struct {
// DependencyType defines model for Dependency.Type.
type DependencyType string
// ExternalServiceRegistration defines model for ExternalServiceRegistration.
// ExternalServiceRegistration allows the service to get a service account token
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
type ExternalServiceRegistration struct {
Impersonation *Impersonation `json:"impersonation,omitempty"`
Self *Self `json:"self,omitempty"`
// Permissions are the permissions that the external service needs its associated service account to have.
Permissions []Permission `json:"permissions,omitempty"`
}
// Header describes an HTTP header that is forwarded with a proxied request for
@@ -314,7 +317,10 @@ type PluginDef struct {
// $GOARCH><.exe for Windows>`, e.g. `plugin_linux_amd64`.
// Combination of $GOOS and $GOARCH can be found here:
// https://golang.org/doc/install/source#environment.
Executable *string `json:"executable,omitempty"`
Executable *string `json:"executable,omitempty"`
// ExternalServiceRegistration allows the service to get a service account token
// (or to use the client_credentials grant if the token provider is the OAuth2 Server)
ExternalServiceRegistration ExternalServiceRegistration `json:"externalServiceRegistration"`
// [internal only] Excludes the plugin from listings in Grafana's UI. Only
@@ -472,16 +478,6 @@ type Route struct {
UrlParams []URLParam `json:"urlParams,omitempty"`
}
// Self defines model for Self.
type Self struct {
// Enabled allows the service to request access tokens for itself using the client_credentials grant
// Defaults to true.
Enabled *bool `json:"enabled,omitempty"`
// Permissions are the permissions that the external service needs its associated service account to have.
Permissions []Permission `json:"permissions,omitempty"`
}
// TODO docs
type TokenAuth struct {
// Parameters for the token authentication request.