Secrets: Extract external facing decrypt types to apps (#110432)

This commit is contained in:
Matheus Macabu
2025-09-02 10:30:29 +02:00
committed by GitHub
parent c1c51beee4
commit 1e926a29c0
16 changed files with 100 additions and 287 deletions
+3 -23
View File
@@ -5,30 +5,10 @@ import (
"fmt"
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
common "github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
)
// HACK: this interface and struct are used to avoid the dependency on the secret contracts
// "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" which creates a circular dependency
// between the apps/provisioning and root modules.
type DecryptResult struct {
Val *secretv1beta1.ExposedSecureValue
Err error
}
func (d DecryptResult) Error() error {
return d.Err
}
func (d DecryptResult) Value() *secretv1beta1.ExposedSecureValue {
return d.Val
}
type DecryptService interface {
Decrypt(ctx context.Context, group, namespace string, names ...string) (map[string]DecryptResult, error)
}
type Decrypter = func(r *provisioning.Repository) SecureValues
type SecureValues interface {
@@ -37,7 +17,7 @@ type SecureValues interface {
}
type secureValues struct {
svc DecryptService
svc decrypt.DecryptService
names provisioning.SecureValues
namespace string
}
@@ -72,7 +52,7 @@ func (s *secureValues) WebhookSecret(ctx context.Context) (common.RawSecureValue
return s.get(ctx, s.names.WebhookSecret)
}
func ProvideDecrypter(svc DecryptService) Decrypter {
func ProvideDecrypter(svc decrypt.DecryptService) Decrypter {
return func(r *provisioning.Repository) SecureValues {
return &secureValues{svc: svc, names: r.Secure, namespace: r.Namespace}
}
+14 -13
View File
@@ -9,6 +9,7 @@ import (
provisioning "github.com/grafana/grafana/apps/provisioning/pkg/apis/provisioning/v0alpha1"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/apimachinery/apis/common/v0alpha1"
)
@@ -34,11 +35,11 @@ func TestRepositorySecureValues(t *testing.T) {
},
},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
require.Equal(t, []string{"secret"}, names)
val := secretv1beta1.NewExposedSecureValue(names[0])
return map[string]DecryptResult{
names[0]: {Val: &val},
return map[string]decrypt.DecryptResult{
names[0]: decrypt.NewDecryptResultValue(&val),
}, nil
},
token: expectedDecryptedResult{
@@ -54,7 +55,7 @@ func TestRepositorySecureValues(t *testing.T) {
},
},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
t.Fatal("decrypt should not be called when Create is set")
return nil, nil
},
@@ -67,7 +68,7 @@ func TestRepositorySecureValues(t *testing.T) {
config: &provisioning.Repository{
Secure: provisioning.SecureValues{},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
t.Fatal("decrypt should not be called when no values are configured")
return nil, nil
},
@@ -81,10 +82,10 @@ func TestRepositorySecureValues(t *testing.T) {
},
},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
require.Equal(t, []string{"secret"}, names)
return map[string]DecryptResult{
names[0]: {Err: fmt.Errorf("error for name")},
return map[string]decrypt.DecryptResult{
names[0]: decrypt.NewDecryptResultErr(fmt.Errorf("error for name")),
}, nil
},
webhook: expectedDecryptedResult{
@@ -100,8 +101,8 @@ func TestRepositorySecureValues(t *testing.T) {
},
},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
return map[string]DecryptResult{}, nil
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
return map[string]decrypt.DecryptResult{}, nil
},
token: expectedDecryptedResult{
error: "not found", // it is not in the results above
@@ -116,7 +117,7 @@ func TestRepositorySecureValues(t *testing.T) {
},
},
},
decrypt: func(t *testing.T, names ...string) (map[string]DecryptResult, error) {
decrypt: func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error) {
return nil, fmt.Errorf("explode")
},
webhook: expectedDecryptedResult{
@@ -148,13 +149,13 @@ func TestRepositorySecureValues(t *testing.T) {
}
}
type decryptFn = func(t *testing.T, names ...string) (map[string]DecryptResult, error)
type decryptFn = func(t *testing.T, names ...string) (map[string]decrypt.DecryptResult, error)
type dummyDecryptService struct {
t *testing.T
fn decryptFn
}
func (d *dummyDecryptService) Decrypt(_ context.Context, _ string, _ string, names ...string) (map[string]DecryptResult, error) {
func (d *dummyDecryptService) Decrypt(_ context.Context, _ string, _ string, names ...string) (map[string]decrypt.DecryptResult, error) {
return d.fn(d.t, names...)
}
+36
View File
@@ -0,0 +1,36 @@
package decrypt
import (
"context"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
)
// DecryptService is the interface for the decrypt service.
type DecryptService interface {
Decrypt(ctx context.Context, serviceName string, namespace string, names ...string) (map[string]DecryptResult, error)
}
// DecryptResult is the (union) result of a decryption operation.
// It contains the decrypted `value` when the decryption succeeds, and the `err` when it fails.
// It is not possible to construct a `DecryptResult` where both `value` and `err` are set from another package.
type DecryptResult struct {
value *secretv1beta1.ExposedSecureValue
err error
}
func (d DecryptResult) Error() error {
return d.err
}
func (d DecryptResult) Value() *secretv1beta1.ExposedSecureValue {
return d.value
}
func NewDecryptResultErr(err error) DecryptResult {
return DecryptResult{err: err}
}
func NewDecryptResultValue(value *secretv1beta1.ExposedSecureValue) DecryptResult {
return DecryptResult{value: value}
}
@@ -4,10 +4,9 @@ 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"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/provisioning"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/secure"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/webhooks"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/setting"
)
@@ -20,21 +19,17 @@ func ProvideProvisioningOSSExtras(webhook *webhooks.WebhookExtraBuilder) []provi
func ProvideProvisioningOSSRepositoryExtras(
cfg *setting.Cfg,
decryptSvc secret.DecryptService,
decryptSvc decrypt.DecryptService,
ghFactory *github.Factory,
webhooksBuilder *webhooks.WebhookExtraBuilder,
) []repository.Extra {
// HACK: this interface and struct are used to avoid the dependency on the secret contracts
// "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" which creates a circular dependency
// between the apps/provisioning and root modules.
wrapper := secure.ProvideDecryptService(decryptSvc)
return []repository.Extra{
local.Extra(
cfg.HomePath,
cfg.PermittedProvisioningPaths,
),
github.Extra(
repository.ProvideDecrypter(wrapper),
repository.ProvideDecrypter(decryptSvc),
ghFactory,
webhooksBuilder,
),
@@ -1,36 +0,0 @@
package secure
import (
"context"
"github.com/grafana/grafana/apps/provisioning/pkg/repository"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
// HACK: this interface and struct are used to avoid the dependency on the secret contracts
// "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" which creates a circular dependency
// between the apps/provisioning and root modules.
type wrapper struct {
svc contracts.DecryptService
}
func (w *wrapper) Decrypt(ctx context.Context, group, namespace string, names ...string) (map[string]repository.DecryptResult, error) {
values, err := w.svc.Decrypt(ctx, group, namespace, names...)
if err != nil {
return nil, err
}
results := make(map[string]repository.DecryptResult, len(values))
for k, v := range values {
results[k] = repository.DecryptResult{
Val: v.Value(),
Err: v.Error(),
}
}
return results, nil
}
func ProvideDecryptService(svc contracts.DecryptService) repository.DecryptService {
return &wrapper{svc: svc}
}
@@ -26,32 +26,3 @@ type DecryptStorage interface {
type DecryptAuthorizer interface {
Authorize(ctx context.Context, namespace xkube.Namespace, secureValueName string, secureValueDecrypters []string) (identity string, allowed bool)
}
// DecryptService is the interface for the decrypt service.
type DecryptService interface {
Decrypt(ctx context.Context, serviceName string, namespace string, names ...string) (map[string]DecryptResult, error)
}
// DecryptResult is the (union) result of a decryption operation.
// It contains the decrypted `value` when the decryption succeeds, and the `err` when it fails.
// It is not possible to construct a `DecryptResult` where both `value` and `err` are set from another package.
type DecryptResult struct {
value *secretv1beta1.ExposedSecureValue
err error
}
func (d DecryptResult) Error() error {
return d.err
}
func (d DecryptResult) Value() *secretv1beta1.ExposedSecureValue {
return d.value
}
func NewDecryptResultErr(err error) DecryptResult {
return DecryptResult{err: err}
}
func NewDecryptResultValue(value *secretv1beta1.ExposedSecureValue) DecryptResult {
return DecryptResult{value: value}
}
@@ -21,6 +21,7 @@ import (
"github.com/grafana/authlib/types"
decryptv1beta1 "github.com/grafana/grafana/apps/secret/decrypt/v1beta1"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
@@ -30,7 +31,7 @@ type GRPCDecryptClient struct {
tokenExchanger authnlib.TokenExchanger
}
var _ contracts.DecryptService = &GRPCDecryptClient{}
var _ decrypt.DecryptService = &GRPCDecryptClient{}
type TLSConfig struct {
UseTLS bool
@@ -101,7 +102,7 @@ func createTLSCredentials(config TLSConfig) (credentials.TransportCredentials, e
}
// Decrypt a set of secure value names in a given namespace for a specific service name.
func (g *GRPCDecryptClient) Decrypt(ctx context.Context, serviceName string, namespace string, names ...string) (map[string]contracts.DecryptResult, error) {
func (g *GRPCDecryptClient) Decrypt(ctx context.Context, serviceName string, namespace string, names ...string) (map[string]decrypt.DecryptResult, error) {
_, err := types.ParseNamespace(namespace)
if err != nil {
return nil, err
@@ -114,7 +115,7 @@ func (g *GRPCDecryptClient) Decrypt(ctx context.Context, serviceName string, nam
}
}
if len(unique) < 1 {
return map[string]contracts.DecryptResult{}, nil
return map[string]decrypt.DecryptResult{}, nil
}
tokenExchangerInterceptor := authnlib.NewGrpcClientInterceptor(
@@ -149,14 +150,14 @@ func (g *GRPCDecryptClient) Decrypt(ctx context.Context, serviceName string, nam
return nil, fmt.Errorf("grpc decrypt failed: %w", err)
}
results := make(map[string]contracts.DecryptResult, len(resp.GetDecryptedValues()))
results := make(map[string]decrypt.DecryptResult, len(resp.GetDecryptedValues()))
for name, result := range resp.GetDecryptedValues() {
if result.GetErrorMessage() != "" {
results[name] = contracts.NewDecryptResultErr(errors.New(result.GetErrorMessage()))
results[name] = decrypt.NewDecryptResultErr(errors.New(result.GetErrorMessage()))
} else {
exposedSecureValue := secretv1beta1.NewExposedSecureValue(result.GetValue())
results[name] = contracts.NewDecryptResultValue(&exposedSecureValue)
results[name] = decrypt.NewDecryptResultValue(&exposedSecureValue)
}
}
@@ -4,6 +4,7 @@ import (
"context"
"github.com/grafana/authlib/types"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
@@ -13,7 +14,7 @@ type LocalDecryptClient struct {
decryptStorage contracts.DecryptStorage
}
var _ contracts.DecryptService = &LocalDecryptClient{}
var _ decrypt.DecryptService = &LocalDecryptClient{}
func NewLocalDecryptClient(decryptStorage contracts.DecryptStorage) (*LocalDecryptClient, error) {
return &LocalDecryptClient{
@@ -21,7 +22,7 @@ func NewLocalDecryptClient(decryptStorage contracts.DecryptStorage) (*LocalDecry
}, nil
}
func (c *LocalDecryptClient) Decrypt(ctx context.Context, serviceName, namespace string, names ...string) (map[string]contracts.DecryptResult, error) {
func (c *LocalDecryptClient) Decrypt(ctx context.Context, serviceName, namespace string, names ...string) (map[string]decrypt.DecryptResult, error) {
ns, err := types.ParseNamespace(namespace)
if err != nil {
return nil, err
@@ -29,7 +30,7 @@ func (c *LocalDecryptClient) Decrypt(ctx context.Context, serviceName, namespace
ctx = identity.WithServiceIdentityContext(ctx, ns.OrgID, identity.WithServiceIdentityName(serviceName))
results := make(map[string]contracts.DecryptResult, len(names))
results := make(map[string]decrypt.DecryptResult, len(names))
for _, name := range names {
_, found := results[name]
@@ -38,9 +39,9 @@ func (c *LocalDecryptClient) Decrypt(ctx context.Context, serviceName, namespace
}
exposedSecureValue, err := c.decryptStorage.Decrypt(ctx, xkube.Namespace(namespace), name)
if err != nil {
results[name] = contracts.NewDecryptResultErr(err)
results[name] = decrypt.NewDecryptResultErr(err)
} else {
results[name] = contracts.NewDecryptResultValue(&exposedSecureValue)
results[name] = decrypt.NewDecryptResultValue(&exposedSecureValue)
}
}
+2 -1
View File
@@ -6,12 +6,13 @@ import (
authnlib "github.com/grafana/authlib/authn"
"go.opentelemetry.io/otel/trace"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/services/authn/grpcutils"
"github.com/grafana/grafana/pkg/setting"
)
func ProvideDecryptService(cfg *setting.Cfg, tracer trace.Tracer, decryptStorage contracts.DecryptStorage) (contracts.DecryptService, error) {
func ProvideDecryptService(cfg *setting.Cfg, tracer trace.Tracer, decryptStorage contracts.DecryptStorage) (decrypt.DecryptService, error) {
if cfg.SecretsManagement.GrpcClientEnable {
grpcClientConfig := grpcutils.ReadGrpcClientConfig(cfg)
@@ -19,6 +19,7 @@ import (
decryptv1beta1 "github.com/grafana/grafana/apps/secret/decrypt/v1beta1"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
decryptcontracts "github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/secret/testutils"
@@ -39,8 +40,8 @@ func TestDecryptService(t *testing.T) {
mockErr := errors.New("mock error")
mockStorage := &mockDecryptStorage{}
mockStorage.On("Decrypt", mock.Anything, mock.Anything, mock.Anything).Return(secretv1beta1.ExposedSecureValue(""), mockErr)
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultErr(mockErr),
decryptedValuesResp := map[string]decryptcontracts.DecryptResult{
"secure-value-1": decryptcontracts.NewDecryptResultErr(mockErr),
}
cfg := setting.NewCfg()
@@ -66,9 +67,9 @@ func TestDecryptService(t *testing.T) {
mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2").
Return(exposedSecureValue2, nil)
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultValue(&exposedSecureValue1),
"secure-value-2": contracts.NewDecryptResultValue(&exposedSecureValue2),
decryptedValuesResp := map[string]decryptcontracts.DecryptResult{
"secure-value-1": decryptcontracts.NewDecryptResultValue(&exposedSecureValue1),
"secure-value-2": decryptcontracts.NewDecryptResultValue(&exposedSecureValue2),
}
cfg := setting.NewCfg()
@@ -93,9 +94,9 @@ func TestDecryptService(t *testing.T) {
mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2").
Return(secretv1beta1.ExposedSecureValue(""), mockErr)
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultValue(&exposedSecureValue),
"secure-value-2": contracts.NewDecryptResultErr(mockErr),
decryptedValuesResp := map[string]decryptcontracts.DecryptResult{
"secure-value-1": decryptcontracts.NewDecryptResultValue(&exposedSecureValue),
"secure-value-2": decryptcontracts.NewDecryptResultErr(mockErr),
}
cfg := setting.NewCfg()
@@ -1,27 +0,0 @@
package secret
import (
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
// DecryptService is a decrypt client for secure value secrets.
//
//go:generate mockery --name DecryptService --structname MockDecryptService --inpackage --filename decrypt_client_mock.go --with-expecter
type DecryptService = contracts.DecryptService
var (
ErrDecryptNotFound = contracts.ErrDecryptNotFound
ErrDecryptNotAuthorized = contracts.ErrDecryptNotAuthorized
ErrDecryptFailed = contracts.ErrDecryptFailed
)
type DecryptResult = contracts.DecryptResult
func NewDecryptResultErr(err error) DecryptResult {
return contracts.NewDecryptResultErr(err)
}
func NewDecryptResultValue(value *secretv1beta1.ExposedSecureValue) DecryptResult {
return contracts.NewDecryptResultValue(value)
}
@@ -1,113 +0,0 @@
// Code generated by mockery v2.53.4. DO NOT EDIT.
package secret
import (
context "context"
mock "github.com/stretchr/testify/mock"
contracts "github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
)
// MockDecryptService is an autogenerated mock type for the DecryptService type
type MockDecryptService struct {
mock.Mock
}
type MockDecryptService_Expecter struct {
mock *mock.Mock
}
func (_m *MockDecryptService) EXPECT() *MockDecryptService_Expecter {
return &MockDecryptService_Expecter{mock: &_m.Mock}
}
// Decrypt provides a mock function with given fields: ctx, serviceName, namespace, names
func (_m *MockDecryptService) Decrypt(ctx context.Context, serviceName string, namespace string, names ...string) (map[string]contracts.DecryptResult, error) {
_va := make([]interface{}, len(names))
for _i := range names {
_va[_i] = names[_i]
}
var _ca []interface{}
_ca = append(_ca, ctx, serviceName, namespace)
_ca = append(_ca, _va...)
ret := _m.Called(_ca...)
if len(ret) == 0 {
panic("no return value specified for Decrypt")
}
var r0 map[string]contracts.DecryptResult
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, string, string, ...string) (map[string]contracts.DecryptResult, error)); ok {
return rf(ctx, serviceName, namespace, names...)
}
if rf, ok := ret.Get(0).(func(context.Context, string, string, ...string) map[string]contracts.DecryptResult); ok {
r0 = rf(ctx, serviceName, namespace, names...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(map[string]contracts.DecryptResult)
}
}
if rf, ok := ret.Get(1).(func(context.Context, string, string, ...string) error); ok {
r1 = rf(ctx, serviceName, namespace, names...)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// MockDecryptService_Decrypt_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Decrypt'
type MockDecryptService_Decrypt_Call struct {
*mock.Call
}
// Decrypt is a helper method to define mock.On call
// - ctx context.Context
// - serviceName string
// - namespace string
// - names ...string
func (_e *MockDecryptService_Expecter) Decrypt(ctx interface{}, serviceName interface{}, namespace interface{}, names ...interface{}) *MockDecryptService_Decrypt_Call {
return &MockDecryptService_Decrypt_Call{Call: _e.mock.On("Decrypt",
append([]interface{}{ctx, serviceName, namespace}, names...)...)}
}
func (_c *MockDecryptService_Decrypt_Call) Run(run func(ctx context.Context, serviceName string, namespace string, names ...string)) *MockDecryptService_Decrypt_Call {
_c.Call.Run(func(args mock.Arguments) {
variadicArgs := make([]string, len(args)-3)
for i, a := range args[3:] {
if a != nil {
variadicArgs[i] = a.(string)
}
}
run(args[0].(context.Context), args[1].(string), args[2].(string), variadicArgs...)
})
return _c
}
func (_c *MockDecryptService_Decrypt_Call) Return(_a0 map[string]contracts.DecryptResult, _a1 error) *MockDecryptService_Decrypt_Call {
_c.Call.Return(_a0, _a1)
return _c
}
func (_c *MockDecryptService_Decrypt_Call) RunAndReturn(run func(context.Context, string, string, ...string) (map[string]contracts.DecryptResult, error)) *MockDecryptService_Decrypt_Call {
_c.Call.Return(run)
return _c
}
// NewMockDecryptService creates a new instance of MockDecryptService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewMockDecryptService(t interface {
mock.TestingT
Cleanup(func())
}) *MockDecryptService {
mock := &MockDecryptService{}
mock.Mock.Test(t)
t.Cleanup(func() { mock.AssertExpectations(t) })
return mock
}
@@ -13,6 +13,7 @@ import (
"k8s.io/utils/ptr"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
decryptcontracts "github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
@@ -162,7 +163,7 @@ type Sut struct {
SecureValueService contracts.SecureValueService
SecureValueMetadataStorage contracts.SecureValueMetadataStorage
DecryptStorage contracts.DecryptStorage
DecryptService contracts.DecryptService
DecryptService decryptcontracts.DecryptService
EncryptedValueStorage contracts.EncryptedValueStorage
GlobalEncryptedValueStorage contracts.GlobalEncryptedValueStorage
SQLKeeper *sqlkeeper.SQLKeeper
+3 -3
View File
@@ -4,10 +4,10 @@ import (
"github.com/stretchr/testify/mock"
"github.com/grafana/grafana/apps/provisioning/pkg/repository/github"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/infra/db"
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/plugins/manager/registry"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/grpcserver"
@@ -35,7 +35,7 @@ func ProvideTestEnv(
resourceClient resource.ResourceClient,
idService auth.IDService,
githubFactory *github.Factory,
decryptService secret.DecryptService,
decryptService decrypt.DecryptService,
) (*TestEnv, error) {
return &TestEnv{
TestingT: testingT,
@@ -73,5 +73,5 @@ type TestEnv struct {
ResourceClient resource.ResourceClient
IDService auth.IDService
GitHubFactory *github.Factory
DecryptService secret.DecryptService
DecryptService decrypt.DecryptService
}
+7 -7
View File
@@ -812,13 +812,13 @@ func Initialize(ctx context.Context, cfg *setting.Cfg, opts Options, apiOpts api
if err != nil {
return nil, err
}
v4, err := decrypt.ProvideDecryptService(cfg, tracer, decryptStorage)
decryptService, err := decrypt.ProvideDecryptService(cfg, tracer, decryptStorage)
if err != nil {
return nil, err
}
factory := github.ProvideFactory()
v5 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, v4, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v5)
v4 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, decryptService, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v4)
if err != nil {
return nil, err
}
@@ -1394,13 +1394,13 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
if err != nil {
return nil, err
}
v4, err := decrypt.ProvideDecryptService(cfg, tracer, decryptStorage)
decryptService, err := decrypt.ProvideDecryptService(cfg, tracer, decryptStorage)
if err != nil {
return nil, err
}
factory := github.ProvideFactory()
v5 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, v4, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v5)
v4 := extras.ProvideProvisioningOSSRepositoryExtras(cfg, decryptService, factory, webhookExtraBuilder)
repositoryFactory, err := repository.ProvideFactory(v4)
if err != nil {
return nil, err
}
@@ -1439,7 +1439,7 @@ func InitializeForTest(ctx context.Context, t sqlutil.ITestDB, testingT interfac
if err != nil {
return nil, err
}
testEnv, err := ProvideTestEnv(testingT, server, sqlStore, cfg, notificationServiceMock, grpcserverProvider, inMemory, httpclientProvider, oauthtokentestService, featureToggles, resourceClient, idimplService, factory, v4)
testEnv, err := ProvideTestEnv(testingT, server, sqlStore, cfg, notificationServiceMock, grpcserverProvider, inMemory, httpclientProvider, oauthtokentestService, featureToggles, resourceClient, idimplService, factory, decryptService)
if err != nil {
return nil, err
}
@@ -12,6 +12,7 @@ import (
"pgregory.net/rapid"
secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/apps/secret/pkg/decrypt"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/testutils"
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
@@ -111,24 +112,24 @@ func (m *model) list(namespace string) (*secretv1beta1.SecureValueList, error) {
return &secretv1beta1.SecureValueList{Items: out}, nil
}
func (m *model) decrypt(decrypter, namespace, name string) (map[string]contracts.DecryptResult, error) {
func (m *model) decrypt(decrypter, namespace, name string) (map[string]decrypt.DecryptResult, error) {
for _, v := range m.secureValues {
if v.Namespace == namespace &&
v.Name == name &&
v.active {
if slices.ContainsFunc(v.Spec.Decrypters, func(d string) bool { return d == decrypter }) {
return map[string]contracts.DecryptResult{
name: contracts.NewDecryptResultValue(deepCopy(v).Spec.Value),
return map[string]decrypt.DecryptResult{
name: decrypt.NewDecryptResultValue(deepCopy(v).Spec.Value),
}, nil
}
return map[string]contracts.DecryptResult{
name: contracts.NewDecryptResultErr(contracts.ErrDecryptNotAuthorized),
return map[string]decrypt.DecryptResult{
name: decrypt.NewDecryptResultErr(contracts.ErrDecryptNotAuthorized),
}, nil
}
}
return map[string]contracts.DecryptResult{
name: contracts.NewDecryptResultErr(contracts.ErrDecryptNotFound),
return map[string]decrypt.DecryptResult{
name: decrypt.NewDecryptResultErr(contracts.ErrDecryptNotFound),
}, nil
}