Provisioning: Decrypt using Secrets Service in Operators (#110589)
* Use real secrets servicer decrypter * Add also server name just in case
This commit is contained in:
committed by
GitHub
parent
000ada4cd1
commit
57ea65dc42
@@ -1,7 +1,6 @@
|
||||
package provisioning
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
"k8s.io/client-go/rest"
|
||||
"k8s.io/client-go/transport"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
|
||||
@@ -20,7 +20,7 @@ import (
|
||||
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
|
||||
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
|
||||
"github.com/grafana/grafana/apps/provisioning/pkg/repository/local"
|
||||
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
|
||||
secretdecrypt "github.com/grafana/grafana/pkg/registry/apis/secret/decrypt"
|
||||
)
|
||||
|
||||
// provisioningControllerConfig contains the configuration that overlaps for the jobs and repo controllers
|
||||
@@ -34,6 +34,12 @@ type provisioningControllerConfig struct {
|
||||
// [grpc_client_authentication]
|
||||
// token =
|
||||
// token_exchange_url =
|
||||
// [secrets_manager]
|
||||
// grpc_server_address =
|
||||
// grpc_server_tls_server_name =
|
||||
// grpc_server_use_tls =
|
||||
// grpc_server_tls_ca_file =
|
||||
// grpc_server_tls_skip_verify =
|
||||
// [operator]
|
||||
// provisioning_server_url =
|
||||
// tls_insecure =
|
||||
@@ -48,6 +54,9 @@ func setupFromConfig(cfg *setting.Cfg) (controllerCfg *provisioningControllerCon
|
||||
if cfg == nil {
|
||||
return nil, fmt.Errorf("no configuration available")
|
||||
}
|
||||
// TODO: we should setup tracing properly
|
||||
// https://github.com/grafana/git-ui-sync-project/issues/507
|
||||
tracer := tracing.NewNoopTracerService()
|
||||
|
||||
gRPCAuth := cfg.SectionWithEnvOverrides("grpc_client_authentication")
|
||||
token := gRPCAuth.Key("token").String()
|
||||
@@ -96,8 +105,12 @@ func setupFromConfig(cfg *setting.Cfg) (controllerCfg *provisioningControllerCon
|
||||
return nil, fmt.Errorf("failed to create provisioning client: %w", err)
|
||||
}
|
||||
|
||||
// TODO: Replace with a real decrypter that uses the Grafana secret service
|
||||
repoFactory, err := setupRepoFactory(cfg, emptyValuesDecrypter, provisioningClient)
|
||||
decrypter, err := setupDecrypter(cfg, tracer, tokenExchangeClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup decrypter: %w", err)
|
||||
}
|
||||
|
||||
repoFactory, err := setupRepoFactory(cfg, decrypter, provisioningClient)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to setup repository getter: %w", err)
|
||||
}
|
||||
@@ -138,26 +151,6 @@ func buildTLSConfig(insecure bool, certFile, keyFile, caFile string) (rest.TLSCl
|
||||
return tlsConfig, nil
|
||||
}
|
||||
|
||||
// emptyValuesDecrypter is a decrypter that always returns empty values.
|
||||
// This is a temporary implementation and should be replaced with a real decrypter.
|
||||
// TODO: remove this and use a real decrypter that uses the Grafana secret service
|
||||
func emptyValuesDecrypter(r *provisioning.Repository) repository.SecureValues {
|
||||
return &emptyValues{}
|
||||
}
|
||||
|
||||
// emptyValues is a that always returns empty values.
|
||||
// This is a temporary implementation and should be replaced with a real decrypter.
|
||||
// TODO: remove this and use a real decrypter that uses the Grafana secret service
|
||||
type emptyValues struct{}
|
||||
|
||||
func (s *emptyValues) Token(ctx context.Context) (common.RawSecureValue, error) {
|
||||
return common.NewSecretValue(""), nil
|
||||
}
|
||||
|
||||
func (s *emptyValues) WebhookSecret(ctx context.Context) (common.RawSecureValue, error) {
|
||||
return common.NewSecretValue(""), nil
|
||||
}
|
||||
|
||||
func setupRepoFactory(
|
||||
cfg *setting.Cfg,
|
||||
decrypter repository.Decrypter,
|
||||
@@ -214,3 +207,34 @@ func setupRepoFactory(
|
||||
|
||||
return repoFactory, nil
|
||||
}
|
||||
|
||||
func setupDecrypter(cfg *setting.Cfg, tracer tracing.Tracer, tokenExchangeClient *authn.TokenExchangeClient) (decrypter repository.Decrypter, err error) {
|
||||
secretsSec := cfg.SectionWithEnvOverrides("secrets_manager")
|
||||
if secretsSec == nil {
|
||||
return nil, fmt.Errorf("no [secrets_manager] section found in config")
|
||||
}
|
||||
|
||||
address := secretsSec.Key("grpc_server_address").String()
|
||||
if address == "" {
|
||||
return nil, fmt.Errorf("grpc_server_address is required in [secrets_manager] section")
|
||||
}
|
||||
|
||||
secretsTls := secretdecrypt.TLSConfig{
|
||||
UseTLS: secretsSec.Key("grpc_server_use_tls").MustBool(true),
|
||||
CAFile: secretsSec.Key("grpc_server_tls_ca_file").String(),
|
||||
ServerName: secretsSec.Key("grpc_server_tls_server_name").String(),
|
||||
InsecureSkipVerify: secretsSec.Key("grpc_server_tls_skip_verify").MustBool(false),
|
||||
}
|
||||
|
||||
decryptSvc, err := secretdecrypt.NewGRPCDecryptClientWithTLS(
|
||||
tokenExchangeClient,
|
||||
tracer,
|
||||
address,
|
||||
secretsTls,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create decrypt service: %w", err)
|
||||
}
|
||||
|
||||
return repository.ProvideDecrypter(decryptSvc), nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user