Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions pkg/registry/apis/provisioning/secrets/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,17 @@ import (

"github.com/grafana/grafana-app-sdk/logging"
provisioning "github.com/grafana/grafana/pkg/apis/provisioning/v0alpha1"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/service"
"github.com/grafana/grafana/pkg/services/featuremgmt"
grafanasecrets "github.com/grafana/grafana/pkg/services/secrets"
legacysecrets "github.com/grafana/grafana/pkg/services/secrets"
)

func ProvideRepositorySecrets(
features featuremgmt.FeatureToggles,
legacySecretsSvc grafanasecrets.Service,
legacySecretsSvc legacysecrets.Service,
secretsSvc contracts.SecureValueClient,
decryptSvc service.DecryptService,
decryptSvc secret.DecryptService,
) RepositorySecrets {
return NewRepositorySecrets(features, NewSecretsService(secretsSvc, decryptSvc), NewSingleTenant(legacySecretsSvc))
}
Expand Down
13 changes: 5 additions & 8 deletions pkg/registry/apis/provisioning/secrets/secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,17 @@ import (

"github.com/grafana/authlib/types"
"github.com/grafana/grafana/pkg/apimachinery/identity"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
grafanasecrets "github.com/grafana/grafana/pkg/registry/apis/secret/service"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/client-go/dynamic"
)

const svcName = "provisioning"

//go:generate mockery --name SecureValueClient --structname MockSecureValueClient --inpackage --filename secure_value_client_mock.go --with-expecter
type SecureValueClient interface {
Client(ctx context.Context, namespace string) (dynamic.ResourceInterface, error)
}
type SecureValueClient = secret.SecureValueClient

//go:generate mockery --name Service --structname MockService --inpackage --filename secret_mock.go --with-expecter
type Service interface {
Expand All @@ -30,13 +27,13 @@ type Service interface {

var _ Service = (*secretsService)(nil)

//go:generate mockery --name DecryptService --structname MockDecryptService --srcpkg=github.com/grafana/grafana/pkg/registry/apis/secret/service --filename decrypt_service_mock.go --with-expecter
//go:generate mockery --name DecryptService --structname MockDecryptService --srcpkg=github.com/grafana/grafana/pkg/registry/apis/secret --filename decrypt_service_mock.go --with-expecter
type secretsService struct {
secureValues SecureValueClient
decryptSvc grafanasecrets.DecryptService
decryptSvc secret.DecryptService
}

func NewSecretsService(secretsSvc SecureValueClient, decryptSvc grafanasecrets.DecryptService) Service {
func NewSecretsService(secretsSvc SecureValueClient, decryptSvc secret.DecryptService) Service {
return &secretsService{
secureValues: secretsSvc,
decryptSvc: decryptSvc,
Expand Down
18 changes: 9 additions & 9 deletions pkg/registry/apis/provisioning/secrets/secret_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ import (

secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/registry/apis/provisioning/secrets/mocks"
"github.com/grafana/grafana/pkg/registry/apis/secret"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/service"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand Down Expand Up @@ -258,7 +258,7 @@ func TestSecretsService_Decrypt(t *testing.T) {
secretName: "test-secret",
setupMocks: func(mockSecretsSvc *MockSecureValueClient, mockDecryptSvc *mocks.MockDecryptService) {
exposedValue := secretv1beta1.NewExposedSecureValue("decrypted-data")
mockResult := service.NewDecryptResultValue(&exposedValue)
mockResult := secret.NewDecryptResultValue(&exposedValue)

mockDecryptSvc.EXPECT().Decrypt(
mock.MatchedBy(func(ctx context.Context) bool {
Expand All @@ -267,7 +267,7 @@ func TestSecretsService_Decrypt(t *testing.T) {
}),
"test-namespace",
"test-secret",
).Return(map[string]service.DecryptResult{
).Return(map[string]secret.DecryptResult{
"test-secret": mockResult,
}, nil)
},
Expand Down Expand Up @@ -299,24 +299,24 @@ func TestSecretsService_Decrypt(t *testing.T) {
}),
"test-namespace",
"test-secret",
).Return(map[string]service.DecryptResult{}, nil)
).Return(map[string]secret.DecryptResult{}, nil)
},
expectedError: contracts.ErrDecryptNotFound.Error(),
expectedError: secret.ErrDecryptNotFound.Error(),
},
{
name: "decrypt result has error",
namespace: "test-namespace",
secretName: "test-secret",
setupMocks: func(mockSecretsSvc *MockSecureValueClient, mockDecryptSvc *mocks.MockDecryptService) {
mockResult := service.NewDecryptResultErr(errors.New("decryption failed"))
mockResult := secret.NewDecryptResultErr(errors.New("decryption failed"))

mockDecryptSvc.EXPECT().Decrypt(
mock.MatchedBy(func(ctx context.Context) bool {
return ctx != nil
}),
"test-namespace",
"test-secret",
).Return(map[string]service.DecryptResult{
).Return(map[string]secret.DecryptResult{
"test-secret": mockResult,
}, nil)
},
Expand Down Expand Up @@ -354,7 +354,7 @@ func TestSecretsService_Decrypt_ServiceIdentityContext(t *testing.T) {
mockDecryptSvc := &mocks.MockDecryptService{}

exposedValue := secretv1beta1.NewExposedSecureValue("test-data")
mockResult := service.NewDecryptResultValue(&exposedValue)
mockResult := secret.NewDecryptResultValue(&exposedValue)

// Create a more detailed context matcher to verify the service identity context is created correctly
mockDecryptSvc.EXPECT().Decrypt(
Expand All @@ -364,7 +364,7 @@ func TestSecretsService_Decrypt_ServiceIdentityContext(t *testing.T) {
}),
"test-namespace",
"test-secret",
).Return(map[string]service.DecryptResult{
).Return(map[string]secret.DecryptResult{
"test-secret": mockResult,
}, nil)

Expand Down
29 changes: 29 additions & 0 deletions pkg/registry/apis/secret/contracts/decrypt.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,32 @@ type DecryptStorage interface {
type DecryptAuthorizer interface {
Authorize(ctx context.Context, secureValueName string, secureValueDecrypters []string) (identity string, allowed bool)
}

// DecryptService is the inferface for the decrypt service.
type DecryptService interface {
Decrypt(ctx context.Context, 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}
}
13 changes: 5 additions & 8 deletions pkg/registry/apis/secret/decrypt/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,28 @@ import (
"context"

"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/service"
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
)

type OSSDecryptService struct {
decryptStore contracts.DecryptStorage
}

var _ service.DecryptService = &OSSDecryptService{}

func ProvideDecryptService(decryptStore contracts.DecryptStorage) service.DecryptService {
func ProvideDecryptService(decryptStore contracts.DecryptStorage) contracts.DecryptService {
return &OSSDecryptService{
decryptStore: decryptStore,
}
}

func (d *OSSDecryptService) Decrypt(ctx context.Context, namespace string, names ...string) (map[string]service.DecryptResult, error) {
results := make(map[string]service.DecryptResult, len(names))
func (d *OSSDecryptService) Decrypt(ctx context.Context, namespace string, names ...string) (map[string]contracts.DecryptResult, error) {
results := make(map[string]contracts.DecryptResult, len(names))

for _, name := range names {
exposedSecureValue, err := d.decryptStore.Decrypt(ctx, xkube.Namespace(namespace), name)
if err != nil {
results[name] = service.NewDecryptResultErr(err)
results[name] = contracts.NewDecryptResultErr(err)
} else {
results[name] = service.NewDecryptResultValue(&exposedSecureValue)
results[name] = contracts.NewDecryptResultValue(&exposedSecureValue)
}
}

Expand Down
18 changes: 9 additions & 9 deletions pkg/registry/apis/secret/decrypt/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"testing"

secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1"
"github.com/grafana/grafana/pkg/registry/apis/secret/service"
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
Expand All @@ -23,8 +23,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]service.DecryptResult{
"secure-value-1": service.NewDecryptResultErr(mockErr),
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultErr(mockErr),
}

decryptService := &OSSDecryptService{
Expand All @@ -49,9 +49,9 @@ func TestDecryptService(t *testing.T) {
mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2").
Return(exposedSecureValue2, nil)

decryptedValuesResp := map[string]service.DecryptResult{
"secure-value-1": service.NewDecryptResultValue(&exposedSecureValue1),
"secure-value-2": service.NewDecryptResultValue(&exposedSecureValue2),
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultValue(&exposedSecureValue1),
"secure-value-2": contracts.NewDecryptResultValue(&exposedSecureValue2),
}

decryptService := &OSSDecryptService{
Expand All @@ -75,9 +75,9 @@ func TestDecryptService(t *testing.T) {
mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2").
Return(secretv1beta1.ExposedSecureValue(""), mockErr)

decryptedValuesResp := map[string]service.DecryptResult{
"secure-value-1": service.NewDecryptResultValue(&exposedSecureValue),
"secure-value-2": service.NewDecryptResultErr(mockErr),
decryptedValuesResp := map[string]contracts.DecryptResult{
"secure-value-1": contracts.NewDecryptResultValue(&exposedSecureValue),
"secure-value-2": contracts.NewDecryptResultErr(mockErr),
}

decryptService := &OSSDecryptService{
Expand Down
25 changes: 25 additions & 0 deletions pkg/registry/apis/secret/decrypt_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
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.
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)
}
8 changes: 0 additions & 8 deletions pkg/registry/apis/secret/errors.go

This file was deleted.

5 changes: 5 additions & 0 deletions pkg/registry/apis/secret/secure_value_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import (
authsvc "github.com/grafana/grafana/pkg/services/apiserver/auth/authorizer"
)

var (
ErrSecureValueNotFound = contracts.ErrSecureValueNotFound
ErrSecureValueAlreadyExists = contracts.ErrSecureValueAlreadyExists
)

// SecureValueClient is a CRUD client for the secure value API.
type SecureValueClient = contracts.SecureValueClient

Expand Down
36 changes: 0 additions & 36 deletions pkg/registry/apis/secret/service/decrypt.go

This file was deleted.

2 changes: 1 addition & 1 deletion pkg/registry/apis/secret/testutils/testutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ type Sut struct {
SecureValueService contracts.SecureValueService
SecureValueMetadataStorage contracts.SecureValueMetadataStorage
DecryptStorage contracts.DecryptStorage
DecryptService service.DecryptService
DecryptService contracts.DecryptService
EncryptedValueStorage contracts.EncryptedValueStorage
SQLKeeper *sqlkeeper.SQLKeeper
Database *database.Database
Expand Down
Loading
Loading