From 9c1b2fb79234ae32408ec083882313734930c1e4 Mon Sep 17 00:00:00 2001 From: Matheus Macabu Date: Fri, 11 Jul 2025 19:14:05 +0200 Subject: [PATCH] Secrets: Bump API version to v1beta1 (#108026) --- go.mod | 5 +- go.sum | 6 +- go.work.sum | 3 +- pkg/registry/apis/secret/contracts/decrypt.go | 4 +- pkg/registry/apis/secret/contracts/keeper.go | 22 ++-- .../apis/secret/contracts/secure_value.go | 8 +- .../apis/secret/decrypt/authorizer.go | 6 +- .../apis/secret/decrypt/service_test.go | 16 +-- .../secret/secretkeeper/fakes/fake_keeper.go | 12 +- .../apis/secret/secretkeeper/secretkeeper.go | 4 +- .../secret/secretkeeper/sqlkeeper/keeper.go | 12 +- .../secretkeeper/sqlkeeper/keeper_test.go | 4 +- pkg/registry/apis/secret/service/decrypt.go | 8 +- .../apis/secret/service/secure_value.go | 28 ++--- .../apis/secret/service/secure_value_test.go | 6 +- .../apis/secret/testutils/testutils.go | 23 ++-- pkg/storage/secret/metadata/decrypt_store.go | 4 +- .../secret/metadata/decrypt_store_test.go | 45 ++++---- pkg/storage/secret/metadata/keeper_model.go | 90 +++++++-------- pkg/storage/secret/metadata/keeper_store.go | 20 ++-- .../secret/metadata/keeper_store_test.go | 105 +++++++++--------- .../secret/metadata/secure_value_model.go | 14 +-- .../secret/metadata/secure_value_store.go | 10 +- .../metadata/secure_value_store_test.go | 21 ++-- .../secret/metadata/secure_value_test.go | 90 ++++++++------- 25 files changed, 290 insertions(+), 276 deletions(-) diff --git a/go.mod b/go.mod index dfb884a040c..5de283a74d2 100644 --- a/go.mod +++ b/go.mod @@ -136,6 +136,7 @@ require ( github.com/matttproud/golang_protobuf_extensions v1.0.4 // @grafana/alerting-backend github.com/microsoft/go-mssqldb v1.8.0 // @grafana/partner-datasources github.com/migueleliasweb/go-github-mock v1.1.0 // @grafana/grafana-app-platform-squad + github.com/mitchellh/copystructure v1.2.0 // @grafana/grafana-operator-experience-squad github.com/mitchellh/mapstructure v1.5.1-0.20231216201459-8508981c8b6c //@grafana/identity-access-team github.com/mocktools/go-smtp-mock/v2 v2.3.1 // @grafana/grafana-backend-group github.com/modern-go/reflect2 v1.0.2 // @grafana/alerting-backend @@ -233,8 +234,9 @@ require ( github.com/grafana/grafana/apps/iam v0.0.0-20250627191313-2f1a6ae1712b // @grafana/identity-access-team github.com/grafana/grafana/apps/investigations v0.0.0-20250627191313-2f1a6ae1712b // @fcjack @matryer github.com/grafana/grafana/apps/playlist v0.0.0-20250627191313-2f1a6ae1712b // @grafana/grafana-app-platform-squad + github.com/grafana/grafana/apps/secret v0.0.0-20250711114246-c9b2126c4ad5 // @grafana/grafana-operator-experience-squad github.com/grafana/grafana/pkg/aggregator v0.0.0-20250627191313-2f1a6ae1712b // @grafana/grafana-app-platform-squad - github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250627191313-2f1a6ae1712b // @grafana/grafana-app-platform-squad + github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250711114246-c9b2126c4ad5 // @grafana/grafana-app-platform-squad github.com/grafana/grafana/pkg/apis/secret v0.0.0-20250627191313-2f1a6ae1712b // @grafana/grafana-operator-experience-squad github.com/grafana/grafana/pkg/apiserver v0.0.0-20250627191313-2f1a6ae1712b // @grafana/grafana-app-platform-squad @@ -455,7 +457,6 @@ require ( github.com/miekg/dns v1.1.63 // indirect github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 // indirect github.com/minio/c2goasm v0.0.0-20190812172519-36a3d3bbc4f3 // indirect - github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect diff --git a/go.sum b/go.sum index 0a022fc6562..367b077d77a 100644 --- a/go.sum +++ b/go.sum @@ -1621,10 +1621,12 @@ github.com/grafana/grafana/apps/investigations v0.0.0-20250627191313-2f1a6ae1712 github.com/grafana/grafana/apps/investigations v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:8RlQ4U9lccPEBD/QxV4zyIMh9+lzjS/7xGpiqn3cHLY= github.com/grafana/grafana/apps/playlist v0.0.0-20250627191313-2f1a6ae1712b h1:elfpvk06igCjE0yL+/urc69UDOt1B/sPfdNg9X9kUMc= github.com/grafana/grafana/apps/playlist v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:fPtx6dwGm0PweQRVbgtthMapJMvXobBcORbndb7Dgd4= +github.com/grafana/grafana/apps/secret v0.0.0-20250711114246-c9b2126c4ad5 h1:+fMhUoqwGdY8ntH0GL2icJa3uk+bTiIMicawDG2r9Uc= +github.com/grafana/grafana/apps/secret v0.0.0-20250711114246-c9b2126c4ad5/go.mod h1:TIrKvhgo2j6lvVeOZ3TUmXbI4I48d6v7QcadL/f6SKQ= github.com/grafana/grafana/pkg/aggregator v0.0.0-20250627191313-2f1a6ae1712b h1:ei01IFqmnXkOrrVvsT3CYe+i5xYra3SCX7Wsu3PMsDU= github.com/grafana/grafana/pkg/aggregator v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:+H4Va9jDJlGQJjAN+OFD/hLx2I/yEzDRMQLaKecvgAc= -github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250627191313-2f1a6ae1712b h1:e0dG1tPpuv4NHCAPP235Gip/MBQB8fQ2XW2bwHqoWh4= -github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:u0+k7KLCvGi6zHWsc2B7r+tmGcYjN/qR+gn51pl104E= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250711114246-c9b2126c4ad5 h1:f4fopIH6eQRoZ/E7bstn69UtDAHleIdQ6DrdzEs++Ug= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250711114246-c9b2126c4ad5/go.mod h1:eAlOam2uWhrsEZlOoAr7XZ9hbBP7SyYGYn31/aQAPs8= github.com/grafana/grafana/pkg/apis/secret v0.0.0-20250627191313-2f1a6ae1712b h1:rkQO7exsDLdr4KGA7kgEnkQnbJGePbDIP1SUQptLRs8= github.com/grafana/grafana/pkg/apis/secret v0.0.0-20250627191313-2f1a6ae1712b/go.mod h1:9YjiHZzii2DZfocRDJbqSeC8M3GWenU5yexeHHxsZ4Y= github.com/grafana/grafana/pkg/apiserver v0.0.0-20250627191313-2f1a6ae1712b h1:QyJLJn3xwFTIXu9KPZujsrIUN0X8DdiR9b2h75L0AfI= diff --git a/go.work.sum b/go.work.sum index 754974ef77b..e2494dfa54a 100644 --- a/go.work.sum +++ b/go.work.sum @@ -718,7 +718,7 @@ github.com/grafana/grafana/apps/dashboard v0.0.0-20250616145019-8d27f12428cb/go. github.com/grafana/grafana/apps/investigation v0.0.0-20250121113133-e747350fee2d/go.mod h1:HQprw3MmiYj5OUV9CZnkwA1FKDZBmYACuAB3oDvUOmI= github.com/grafana/grafana/apps/playlist v0.0.0-20250121113133-e747350fee2d/go.mod h1:DjJe5osrW/BKrzN9hAAOSElNWutj1bcriExa7iDP7kA= github.com/grafana/grafana/pkg/aggregator v0.0.0-20250121113133-e747350fee2d/go.mod h1:1sq0guad+G4SUTlBgx7SXfhnzy7D86K/LcVOtiQCiMA= -github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250710134100-1f3dc0533caf/go.mod h1:eAlOam2uWhrsEZlOoAr7XZ9hbBP7SyYGYn31/aQAPs8= +github.com/grafana/grafana/pkg/apimachinery v0.0.0-20250711114246-c9b2126c4ad5/go.mod h1:eAlOam2uWhrsEZlOoAr7XZ9hbBP7SyYGYn31/aQAPs8= github.com/grafana/grafana/pkg/semconv v0.0.0-20250121113133-e747350fee2d/go.mod h1:tfLnBpPYgwrBMRz4EXqPCZJyCjEG4Ev37FSlXnocJ2c= github.com/grafana/grafana/pkg/storage/unified/apistore v0.0.0-20250121113133-e747350fee2d/go.mod h1:CXpwZ3Mkw6xVlGKc0SqUxqXCP3Uv182q6qAQnLaLxRg= github.com/grafana/grafana/pkg/storage/unified/apistore v0.0.0-20250514132646-acbc7b54ed9e/go.mod h1:xrKQcxQxz+IUF90ybtfENFeEXtlj9nAsX/3Fw0KEIeQ= @@ -1424,7 +1424,6 @@ k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7 h1:2OX19X59HxDprNCVrWi6jb7LW1 k8s.io/gengo/v2 v2.0.0-20250207200755-1244d31929d7/go.mod h1:EJykeLsmFC60UQbYJezXkEsG2FLrt0GPNkU5iK5GWxU= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/kms v0.33.2/go.mod h1:C1I8mjFFBNzfUZXYt9FZVJ8MJl7ynFbGgZFbBzkBJ3E= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= modernc.org/cc/v3 v3.36.3 h1:uISP3F66UlixxWEcKuIWERa4TwrZENHSL8tWxZz8bHg= modernc.org/ccgo/v3 v3.16.9 h1:AXquSwg7GuMk11pIdw7fmO1Y/ybgazVkMhsZWCV0mHM= diff --git a/pkg/registry/apis/secret/contracts/decrypt.go b/pkg/registry/apis/secret/contracts/decrypt.go index 73ff2248e7a..5bc3ac1631a 100644 --- a/pkg/registry/apis/secret/contracts/decrypt.go +++ b/pkg/registry/apis/secret/contracts/decrypt.go @@ -4,7 +4,7 @@ import ( "context" "errors" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" ) @@ -16,7 +16,7 @@ var ( // DecryptStorage is the interface for wiring and dependency injection. type DecryptStorage interface { - Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (secretv0alpha1.ExposedSecureValue, error) + Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (secretv1beta1.ExposedSecureValue, error) } // DecryptAuthorizer is the interface for authorizing decryption requests. diff --git a/pkg/registry/apis/secret/contracts/keeper.go b/pkg/registry/apis/secret/contracts/keeper.go index c7f0482e54d..b8d25cf651a 100644 --- a/pkg/registry/apis/secret/contracts/keeper.go +++ b/pkg/registry/apis/secret/contracts/keeper.go @@ -4,7 +4,7 @@ import ( "context" "errors" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "k8s.io/apimachinery/pkg/util/validation/field" ) @@ -15,12 +15,12 @@ var ( // KeeperMetadataStorage is the interface for wiring and dependency injection. type KeeperMetadataStorage interface { - Create(ctx context.Context, keeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) - Read(ctx context.Context, namespace xkube.Namespace, name string, opts ReadOpts) (*secretv0alpha1.Keeper, error) - Update(ctx context.Context, keeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) + Create(ctx context.Context, keeper *secretv1beta1.Keeper, actorUID string) (*secretv1beta1.Keeper, error) + Read(ctx context.Context, namespace xkube.Namespace, name string, opts ReadOpts) (*secretv1beta1.Keeper, error) + Update(ctx context.Context, keeper *secretv1beta1.Keeper, actorUID string) (*secretv1beta1.Keeper, error) Delete(ctx context.Context, namespace xkube.Namespace, name string) error - List(ctx context.Context, namespace xkube.Namespace) ([]secretv0alpha1.Keeper, error) - GetKeeperConfig(ctx context.Context, namespace string, name *string, opts ReadOpts) (secretv0alpha1.KeeperConfig, error) + List(ctx context.Context, namespace xkube.Namespace) ([]secretv1beta1.Keeper, error) + GetKeeperConfig(ctx context.Context, namespace string, name *string, opts ReadOpts) (secretv1beta1.KeeperConfig, error) } // ErrKeeperInvalidSecureValues is returned when a Keeper references SecureValues that do not exist. @@ -95,14 +95,14 @@ func (s ExternalID) String() string { // Keeper is the interface for secret keepers. type Keeper interface { - Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, exposedValueOrRef string) (ExternalID, error) - Update(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID ExternalID, exposedValueOrRef string) error - Expose(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID ExternalID) (secretv0alpha1.ExposedSecureValue, error) - Delete(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID ExternalID) error + Store(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, exposedValueOrRef string) (ExternalID, error) + Update(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID ExternalID, exposedValueOrRef string) error + Expose(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID ExternalID) (secretv1beta1.ExposedSecureValue, error) + Delete(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID ExternalID) error } // Service is the interface for secret keeper services. // This exists because OSS and Enterprise have different amounts of keepers available. type KeeperService interface { - KeeperForConfig(secretv0alpha1.KeeperConfig) (Keeper, error) + KeeperForConfig(secretv1beta1.KeeperConfig) (Keeper, error) } diff --git a/pkg/registry/apis/secret/contracts/secure_value.go b/pkg/registry/apis/secret/contracts/secure_value.go index 94bde58c68e..f3bc1d3c45c 100644 --- a/pkg/registry/apis/secret/contracts/secure_value.go +++ b/pkg/registry/apis/secret/contracts/secure_value.go @@ -4,7 +4,7 @@ import ( "context" "errors" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" ) @@ -30,9 +30,9 @@ type ReadOpts struct { // SecureValueMetadataStorage is the interface for wiring and dependency injection. type SecureValueMetadataStorage interface { - Create(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) - Read(ctx context.Context, namespace xkube.Namespace, name string, opts ReadOpts) (*secretv0alpha1.SecureValue, error) - List(ctx context.Context, namespace xkube.Namespace) ([]secretv0alpha1.SecureValue, error) + Create(ctx context.Context, sv *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, error) + Read(ctx context.Context, namespace xkube.Namespace, name string, opts ReadOpts) (*secretv1beta1.SecureValue, error) + List(ctx context.Context, namespace xkube.Namespace) ([]secretv1beta1.SecureValue, error) SetVersionToActive(ctx context.Context, namespace xkube.Namespace, name string, version int64) error SetVersionToInactive(ctx context.Context, namespace xkube.Namespace, name string, version int64) error SetExternalID(ctx context.Context, namespace xkube.Namespace, name string, version int64, externalID ExternalID) error diff --git a/pkg/registry/apis/secret/decrypt/authorizer.go b/pkg/registry/apis/secret/decrypt/authorizer.go index 9f2915d708b..0ae6f5c9796 100644 --- a/pkg/registry/apis/secret/decrypt/authorizer.go +++ b/pkg/registry/apis/secret/decrypt/authorizer.go @@ -9,7 +9,7 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" ) @@ -88,8 +88,8 @@ func (a *decryptAuthorizer) Authorize(ctx context.Context, secureValueName strin // Changes: 1) we don't support `*` for verbs; 2) we support specific names in the permission. func hasPermissionInToken(tokenPermissions []string, name string) bool { var ( - group = secretv0alpha1.GROUP - resource = secretv0alpha1.SecureValuesResourceInfo.GetName() + group = secretv1beta1.APIGroup + resource = secretv1beta1.SecureValuesResourceInfo.GetName() verb = "decrypt" ) diff --git a/pkg/registry/apis/secret/decrypt/service_test.go b/pkg/registry/apis/secret/decrypt/service_test.go index 665a6730527..0aaac869a67 100644 --- a/pkg/registry/apis/secret/decrypt/service_test.go +++ b/pkg/registry/apis/secret/decrypt/service_test.go @@ -5,7 +5,7 @@ import ( "errors" "testing" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + 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/xkube" "github.com/stretchr/testify/mock" @@ -22,7 +22,7 @@ func TestDecryptService(t *testing.T) { mockErr := errors.New("mock error") mockStorage := &MockDecryptStorage{} - mockStorage.On("Decrypt", mock.Anything, mock.Anything, mock.Anything).Return(secretv0alpha1.ExposedSecureValue(""), mockErr) + mockStorage.On("Decrypt", mock.Anything, mock.Anything, mock.Anything).Return(secretv1beta1.ExposedSecureValue(""), mockErr) decryptedValuesResp := map[string]service.DecryptResult{ "secure-value-1": service.NewDecryptResultErr(mockErr), } @@ -42,8 +42,8 @@ func TestDecryptService(t *testing.T) { mockStorage := &MockDecryptStorage{} // Set up the mock to return a different value for each name in the test - exposedSecureValue1 := secretv0alpha1.NewExposedSecureValue("value1") - exposedSecureValue2 := secretv0alpha1.NewExposedSecureValue("value2") + exposedSecureValue1 := secretv1beta1.NewExposedSecureValue("value1") + exposedSecureValue2 := secretv1beta1.NewExposedSecureValue("value2") mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-1"). Return(exposedSecureValue1, nil) mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2"). @@ -69,11 +69,11 @@ func TestDecryptService(t *testing.T) { mockErr := errors.New("mock error") mockStorage := &MockDecryptStorage{} - exposedSecureValue := secretv0alpha1.NewExposedSecureValue("value") + exposedSecureValue := secretv1beta1.NewExposedSecureValue("value") mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-1"). Return(exposedSecureValue, nil) mockStorage.On("Decrypt", mock.Anything, xkube.Namespace("default"), "secure-value-2"). - Return(secretv0alpha1.ExposedSecureValue(""), mockErr) + Return(secretv1beta1.ExposedSecureValue(""), mockErr) decryptedValuesResp := map[string]service.DecryptResult{ "secure-value-1": service.NewDecryptResultValue(&exposedSecureValue), @@ -95,7 +95,7 @@ type MockDecryptStorage struct { mock.Mock } -func (m *MockDecryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (secretv0alpha1.ExposedSecureValue, error) { +func (m *MockDecryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (secretv1beta1.ExposedSecureValue, error) { args := m.Called(ctx, namespace, name) - return args.Get(0).(secretv0alpha1.ExposedSecureValue), args.Error(1) + return args.Get(0).(secretv1beta1.ExposedSecureValue), args.Error(1) } diff --git a/pkg/registry/apis/secret/secretkeeper/fakes/fake_keeper.go b/pkg/registry/apis/secret/secretkeeper/fakes/fake_keeper.go index 0c8408a04bd..d24f9c0221c 100644 --- a/pkg/registry/apis/secret/secretkeeper/fakes/fake_keeper.go +++ b/pkg/registry/apis/secret/secretkeeper/fakes/fake_keeper.go @@ -6,7 +6,7 @@ import ( "github.com/google/uuid" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" ) @@ -24,7 +24,7 @@ func NewFakeKeeper() *FakeKeeper { } } -func (s *FakeKeeper) Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, exposedValueOrRef string) (contracts.ExternalID, error) { +func (s *FakeKeeper) Store(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, exposedValueOrRef string) (contracts.ExternalID, error) { ns, ok := s.values[namespace] if !ok { ns = make(map[string]string) @@ -36,7 +36,7 @@ func (s *FakeKeeper) Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, return contracts.ExternalID(uid), nil } -func (s *FakeKeeper) Expose(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID) (secretv0alpha1.ExposedSecureValue, error) { +func (s *FakeKeeper) Expose(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID) (secretv1beta1.ExposedSecureValue, error) { ns, ok := s.values[namespace] if !ok { return "", ErrSecretNotFound @@ -46,14 +46,14 @@ func (s *FakeKeeper) Expose(ctx context.Context, cfg secretv0alpha1.KeeperConfig return "", ErrSecretNotFound } - return secretv0alpha1.NewExposedSecureValue(exposedVal), nil + return secretv1beta1.NewExposedSecureValue(exposedVal), nil } -func (s *FakeKeeper) Delete(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID) error { +func (s *FakeKeeper) Delete(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID) error { return nil } -func (s *FakeKeeper) Update(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID, exposedValueOrRef string) error { +func (s *FakeKeeper) Update(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID, exposedValueOrRef string) error { ns, ok := s.values[namespace] if !ok { return ErrSecretNotFound diff --git a/pkg/registry/apis/secret/secretkeeper/secretkeeper.go b/pkg/registry/apis/secret/secretkeeper/secretkeeper.go index 9cb1a4ec495..fc65573ac61 100644 --- a/pkg/registry/apis/secret/secretkeeper/secretkeeper.go +++ b/pkg/registry/apis/secret/secretkeeper/secretkeeper.go @@ -3,7 +3,7 @@ package secretkeeper import ( "go.opentelemetry.io/otel/trace" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/secretkeeper/sqlkeeper" "github.com/prometheus/client_golang/prometheus" @@ -30,6 +30,6 @@ func ProvideService( // Ignore the config, but we could use it to get the keeper type and then return the correct keeper. // Instantiation only happens on ProvideService ONCE. -func (k *OSSKeeperService) KeeperForConfig(secretv0alpha1.KeeperConfig) (contracts.Keeper, error) { +func (k *OSSKeeperService) KeeperForConfig(secretv1beta1.KeeperConfig) (contracts.Keeper, error) { return k.systemKeeper, nil } diff --git a/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper.go b/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper.go index 30656bb8e65..a65052c40f0 100644 --- a/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper.go +++ b/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/secretkeeper/metrics" "github.com/prometheus/client_golang/prometheus" @@ -36,7 +36,7 @@ func NewSQLKeeper( } } -func (s *SQLKeeper) Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, exposedValueOrRef string) (contracts.ExternalID, error) { +func (s *SQLKeeper) Store(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, exposedValueOrRef string) (contracts.ExternalID, error) { ctx, span := s.tracer.Start(ctx, "SQLKeeper.Store", trace.WithAttributes(attribute.String("namespace", namespace))) defer span.End() @@ -58,7 +58,7 @@ func (s *SQLKeeper) Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, return externalID, nil } -func (s *SQLKeeper) Expose(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID) (secretv0alpha1.ExposedSecureValue, error) { +func (s *SQLKeeper) Expose(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID) (secretv1beta1.ExposedSecureValue, error) { ctx, span := s.tracer.Start(ctx, "SQLKeeper.Expose", trace.WithAttributes( attribute.String("namespace", namespace), attribute.String("externalID", externalID.String()), @@ -76,13 +76,13 @@ func (s *SQLKeeper) Expose(ctx context.Context, cfg secretv0alpha1.KeeperConfig, return "", fmt.Errorf("unable to decrypt value: %w", err) } - exposedValue := secretv0alpha1.NewExposedSecureValue(string(exposedBytes)) + exposedValue := secretv1beta1.NewExposedSecureValue(string(exposedBytes)) s.metrics.ExposeDuration.WithLabelValues(string(cfg.Type())).Observe(time.Since(start).Seconds()) return exposedValue, nil } -func (s *SQLKeeper) Delete(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID) error { +func (s *SQLKeeper) Delete(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID) error { ctx, span := s.tracer.Start(ctx, "SQLKeeper.Delete", trace.WithAttributes( attribute.String("namespace", namespace), attribute.String("externalID", externalID.String()), @@ -100,7 +100,7 @@ func (s *SQLKeeper) Delete(ctx context.Context, cfg secretv0alpha1.KeeperConfig, return nil } -func (s *SQLKeeper) Update(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID contracts.ExternalID, exposedValueOrRef string) error { +func (s *SQLKeeper) Update(ctx context.Context, cfg secretv1beta1.KeeperConfig, namespace string, externalID contracts.ExternalID, exposedValueOrRef string) error { ctx, span := s.tracer.Start(ctx, "SQLKeeper.Update", trace.WithAttributes( attribute.String("namespace", namespace), attribute.String("externalID", externalID.String()), diff --git a/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper_test.go b/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper_test.go index fa9aa7a6ba5..902c1f64b63 100644 --- a/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper_test.go +++ b/pkg/registry/apis/secret/secretkeeper/sqlkeeper/keeper_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/trace/noop" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" encryptionmanager "github.com/grafana/grafana/pkg/registry/apis/secret/encryption/manager" @@ -44,7 +44,7 @@ func Test_SQLKeeperSetup(t *testing.T) { require.NoError(t, err) require.NotNil(t, sqlKeeper) - keeperCfg := &secretv0alpha1.SystemKeeperConfig{} + keeperCfg := &secretv1beta1.SystemKeeperConfig{} t.Run("storing an encrypted value returns no error", func(t *testing.T) { externalId1, err := sqlKeeper.Store(ctx, keeperCfg, namespace1, plaintext1) diff --git a/pkg/registry/apis/secret/service/decrypt.go b/pkg/registry/apis/secret/service/decrypt.go index d9b19ed2e76..f8ff83d95c9 100644 --- a/pkg/registry/apis/secret/service/decrypt.go +++ b/pkg/registry/apis/secret/service/decrypt.go @@ -3,14 +3,14 @@ package service import ( "context" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" ) // 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 *secretv0alpha1.ExposedSecureValue + value *secretv1beta1.ExposedSecureValue err error } @@ -18,7 +18,7 @@ func (d DecryptResult) Error() error { return d.err } -func (d DecryptResult) Value() *secretv0alpha1.ExposedSecureValue { +func (d DecryptResult) Value() *secretv1beta1.ExposedSecureValue { return d.value } @@ -26,7 +26,7 @@ func NewDecryptResultErr(err error) DecryptResult { return DecryptResult{err: err} } -func NewDecryptResultValue(value *secretv0alpha1.ExposedSecureValue) DecryptResult { +func NewDecryptResultValue(value *secretv1beta1.ExposedSecureValue) DecryptResult { return DecryptResult{value: value} } diff --git a/pkg/registry/apis/secret/service/secure_value.go b/pkg/registry/apis/secret/service/secure_value.go index 2611eb5a41b..6170bca37b6 100644 --- a/pkg/registry/apis/secret/service/secure_value.go +++ b/pkg/registry/apis/secret/service/secure_value.go @@ -6,8 +6,8 @@ import ( claims "github.com/grafana/authlib/types" "github.com/grafana/grafana-app-sdk/logging" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/apimachinery/utils" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "go.opentelemetry.io/otel/attribute" @@ -41,7 +41,7 @@ func ProvideSecureValueService( } } -func (s *SecureValueService) Create(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) { +func (s *SecureValueService) Create(ctx context.Context, sv *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, error) { ctx, span := s.tracer.Start(ctx, "SecureValueService.Create", trace.WithAttributes( attribute.String("name", sv.GetName()), attribute.String("namespace", sv.GetNamespace()), @@ -51,7 +51,7 @@ func (s *SecureValueService) Create(ctx context.Context, sv *secretv0alpha1.Secu return s.createNewVersion(ctx, sv, actorUID) } -func (s *SecureValueService) Update(ctx context.Context, newSecureValue *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, bool, error) { +func (s *SecureValueService) Update(ctx context.Context, newSecureValue *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, bool, error) { ctx, span := s.tracer.Start(ctx, "SecureValueService.Update", trace.WithAttributes( attribute.String("name", newSecureValue.GetName()), attribute.String("namespace", newSecureValue.GetNamespace()), @@ -59,7 +59,7 @@ func (s *SecureValueService) Update(ctx context.Context, newSecureValue *secretv )) defer span.End() - if newSecureValue.Spec.Value == "" { + if newSecureValue.Spec.Value == nil { decrypted, err := s.secureValueMetadataStorage.ReadForDecrypt(ctx, xkube.Namespace(newSecureValue.Namespace), newSecureValue.Name) if err != nil { return nil, false, fmt.Errorf("reading secure value secret: %+w", err) @@ -82,7 +82,7 @@ func (s *SecureValueService) Update(ctx context.Context, newSecureValue *secretv return nil, false, fmt.Errorf("reading secret value from keeper: %w", err) } - newSecureValue.Spec.Value = secret + newSecureValue.Spec.Value = &secret } const updateIsSync = true @@ -90,12 +90,12 @@ func (s *SecureValueService) Update(ctx context.Context, newSecureValue *secretv return createdSv, updateIsSync, err } -func (s *SecureValueService) createNewVersion(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) { +func (s *SecureValueService) createNewVersion(ctx context.Context, sv *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, error) { createdSv, err := s.secureValueMetadataStorage.Create(ctx, sv, actorUID) if err != nil { return nil, fmt.Errorf("creating secure value: %w", err) } - createdSv.Status = secretv0alpha1.SecureValueStatus{ + createdSv.Status = secretv1beta1.SecureValueStatus{ Version: createdSv.Status.Version, } @@ -135,7 +135,7 @@ func (s *SecureValueService) createNewVersion(ctx context.Context, sv *secretv0a return createdSv, nil } -func (s *SecureValueService) Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.SecureValue, error) { +func (s *SecureValueService) Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv1beta1.SecureValue, error) { ctx, span := s.tracer.Start(ctx, "SecureValueService.Read", trace.WithAttributes( attribute.String("name", name), attribute.String("namespace", namespace.String()), @@ -145,7 +145,7 @@ func (s *SecureValueService) Read(ctx context.Context, namespace xkube.Namespace return s.secureValueMetadataStorage.Read(ctx, namespace, name, contracts.ReadOpts{ForUpdate: false}) } -func (s *SecureValueService) List(ctx context.Context, namespace xkube.Namespace) (*secretv0alpha1.SecureValueList, error) { +func (s *SecureValueService) List(ctx context.Context, namespace xkube.Namespace) (*secretv1beta1.SecureValueList, error) { ctx, span := s.tracer.Start(ctx, "SecureValueService.List", trace.WithAttributes( attribute.String("namespace", namespace.String()), )) @@ -157,8 +157,8 @@ func (s *SecureValueService) List(ctx context.Context, namespace xkube.Namespace } hasPermissionFor, err := s.accessClient.Compile(ctx, user, claims.ListRequest{ - Group: secretv0alpha1.GROUP, - Resource: secretv0alpha1.SecureValuesResourceInfo.GetName(), + Group: secretv1beta1.APIGroup, + Resource: secretv1beta1.SecureValuesResourceInfo.GetName(), Namespace: namespace.String(), Verb: utils.VerbGet, // Why not VerbList? }) @@ -171,7 +171,7 @@ func (s *SecureValueService) List(ctx context.Context, namespace xkube.Namespace return nil, fmt.Errorf("fetching secure values from storage: %+w", err) } - out := make([]secretv0alpha1.SecureValue, 0) + out := make([]secretv1beta1.SecureValue, 0) for _, metadata := range secureValuesMetadata { // Check whether the user has permission to access this specific SecureValue in the namespace. @@ -182,12 +182,12 @@ func (s *SecureValueService) List(ctx context.Context, namespace xkube.Namespace out = append(out, metadata) } - return &secretv0alpha1.SecureValueList{ + return &secretv1beta1.SecureValueList{ Items: out, }, nil } -func (s *SecureValueService) Delete(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.SecureValue, error) { +func (s *SecureValueService) Delete(ctx context.Context, namespace xkube.Namespace, name string) (*secretv1beta1.SecureValue, error) { ctx, span := s.tracer.Start(ctx, "SecureValueService.Delete", trace.WithAttributes( attribute.String("name", name), attribute.String("namespace", namespace.String()), diff --git a/pkg/registry/apis/secret/service/secure_value_test.go b/pkg/registry/apis/secret/service/secure_value_test.go index 865138d097b..1304e5b0ce1 100644 --- a/pkg/registry/apis/secret/service/secure_value_test.go +++ b/pkg/registry/apis/secret/service/secure_value_test.go @@ -3,11 +3,12 @@ package service_test import ( "testing" - "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "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" "github.com/stretchr/testify/require" + "k8s.io/utils/ptr" ) func TestCrud(t *testing.T) { @@ -23,7 +24,7 @@ func TestCrud(t *testing.T) { // Create the same secure value twice input := sv1.DeepCopy() input.Spec.Description = "d2" - input.Spec.Value = v0alpha1.NewExposedSecureValue("v2") + input.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("v2")) sv2, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(input)) require.NoError(t, err) @@ -55,6 +56,7 @@ func TestCrud(t *testing.T) { // Update the secure value input := sv1.DeepCopy() input.Spec.Description = "d2" + input.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("v3")) sv2, err := sut.UpdateSv(t.Context(), input) require.NoError(t, err) diff --git a/pkg/registry/apis/secret/testutils/testutils.go b/pkg/registry/apis/secret/testutils/testutils.go index b85b098d834..0485b44bfba 100644 --- a/pkg/registry/apis/secret/testutils/testutils.go +++ b/pkg/registry/apis/secret/testutils/testutils.go @@ -6,11 +6,12 @@ import ( "github.com/grafana/authlib/authn" "github.com/grafana/authlib/types" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/apimachinery/identity" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" encryptionstorage "github.com/grafana/grafana/pkg/storage/secret/encryption" "go.opentelemetry.io/otel/trace/noop" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" "github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" @@ -138,28 +139,28 @@ type Sut struct { } type CreateSvConfig struct { - Sv *secretv0alpha1.SecureValue + Sv *secretv1beta1.SecureValue } -func CreateSvWithSv(sv *secretv0alpha1.SecureValue) func(*CreateSvConfig) { +func CreateSvWithSv(sv *secretv1beta1.SecureValue) func(*CreateSvConfig) { return func(cfg *CreateSvConfig) { cfg.Sv = sv } } -func (s *Sut) CreateSv(ctx context.Context, opts ...func(*CreateSvConfig)) (*secretv0alpha1.SecureValue, error) { +func (s *Sut) CreateSv(ctx context.Context, opts ...func(*CreateSvConfig)) (*secretv1beta1.SecureValue, error) { cfg := CreateSvConfig{ - Sv: &secretv0alpha1.SecureValue{ + Sv: &secretv1beta1.SecureValue{ ObjectMeta: metav1.ObjectMeta{ Name: "sv1", Namespace: "ns1", }, - Spec: secretv0alpha1.SecureValueSpec{ + Spec: secretv1beta1.SecureValueSpec{ Description: "desc1", - Value: secretv0alpha1.NewExposedSecureValue("v1"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("v1")), Decrypters: []string{"decrypter1"}, }, - Status: secretv0alpha1.SecureValueStatus{}, + Status: secretv1beta1.SecureValueStatus{}, }, } for _, opt := range opts { @@ -173,12 +174,12 @@ func (s *Sut) CreateSv(ctx context.Context, opts ...func(*CreateSvConfig)) (*sec return createdSv, nil } -func (s *Sut) UpdateSv(ctx context.Context, sv *secretv0alpha1.SecureValue) (*secretv0alpha1.SecureValue, error) { +func (s *Sut) UpdateSv(ctx context.Context, sv *secretv1beta1.SecureValue) (*secretv1beta1.SecureValue, error) { newSv, _, err := s.SecureValueService.Update(ctx, sv, "actor-uid") return newSv, err } -func (s *Sut) DeleteSv(ctx context.Context, namespace, name string) (*secretv0alpha1.SecureValue, error) { +func (s *Sut) DeleteSv(ctx context.Context, namespace, name string) (*secretv1beta1.SecureValue, error) { sv, err := s.SecureValueService.Delete(ctx, xkube.Namespace(namespace), name) return sv, err } @@ -191,7 +192,7 @@ func newKeeperServiceWrapper(keeper contracts.Keeper) *keeperServiceWrapper { return &keeperServiceWrapper{keeper: keeper} } -func (wrapper *keeperServiceWrapper) KeeperForConfig(cfg secretv0alpha1.KeeperConfig) (contracts.Keeper, error) { +func (wrapper *keeperServiceWrapper) KeeperForConfig(cfg secretv1beta1.KeeperConfig) (contracts.Keeper, error) { return wrapper.keeper, nil } diff --git a/pkg/storage/secret/metadata/decrypt_store.go b/pkg/storage/secret/metadata/decrypt_store.go index e907374748a..93d212299cb 100644 --- a/pkg/storage/secret/metadata/decrypt_store.go +++ b/pkg/storage/secret/metadata/decrypt_store.go @@ -13,7 +13,7 @@ import ( "go.opentelemetry.io/otel/trace" "github.com/grafana/grafana-app-sdk/logging" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -60,7 +60,7 @@ type decryptStorage struct { } // Decrypt decrypts a secure value from the keeper. -func (s *decryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (_ secretv0alpha1.ExposedSecureValue, decryptErr error) { +func (s *decryptStorage) Decrypt(ctx context.Context, namespace xkube.Namespace, name string) (_ secretv1beta1.ExposedSecureValue, decryptErr error) { ctx, span := s.tracer.Start(ctx, "DecryptStorage.Decrypt", trace.WithAttributes( attribute.String("namespace", namespace.String()), attribute.String("name", name), diff --git a/pkg/storage/secret/metadata/decrypt_store_test.go b/pkg/storage/secret/metadata/decrypt_store_test.go index 5ebbb2f9466..b3ad4643b8a 100644 --- a/pkg/storage/secret/metadata/decrypt_store_test.go +++ b/pkg/storage/secret/metadata/decrypt_store_test.go @@ -7,9 +7,10 @@ import ( "github.com/grafana/authlib/authn" "github.com/grafana/authlib/types" "github.com/stretchr/testify/require" + "k8s.io/utils/ptr" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/apimachinery/identity" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/testutils" ) @@ -73,12 +74,12 @@ func TestIntegrationDecrypt(t *testing.T) { })) // Create a secure value that is not in the allowlist - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = svName sv.Namespace = "default" @@ -110,12 +111,12 @@ func TestIntegrationDecrypt(t *testing.T) { })) // Create a secure value that is in the allowlist - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = "sv-test" sv.Namespace = "default" @@ -149,12 +150,12 @@ func TestIntegrationDecrypt(t *testing.T) { })) // Create a secure value that is in the allowlist - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = svName sv.Namespace = "default" @@ -181,12 +182,12 @@ func TestIntegrationDecrypt(t *testing.T) { sut := testutils.Setup(t) // Create a secure value - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = "sv-test" sv.Namespace = "default" @@ -214,12 +215,12 @@ func TestIntegrationDecrypt(t *testing.T) { sut := testutils.Setup(t) // Create a secure value - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = svName sv.Namespace = "default" @@ -246,12 +247,12 @@ func TestIntegrationDecrypt(t *testing.T) { sut := testutils.Setup(t) // Create a secure value - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = "sv-test" sv.Namespace = "default" @@ -279,12 +280,12 @@ func TestIntegrationDecrypt(t *testing.T) { sut := testutils.Setup(t) // Create a secure value - spec := secretv0alpha1.SecureValueSpec{ + spec := secretv1beta1.SecureValueSpec{ Description: "description", Decrypters: []string{svcIdentity}, - Value: secretv0alpha1.NewExposedSecureValue("value"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("value")), } - sv := &secretv0alpha1.SecureValue{Spec: spec} + sv := &secretv1beta1.SecureValue{Spec: spec} sv.Name = svName sv.Namespace = "default" diff --git a/pkg/storage/secret/metadata/keeper_model.go b/pkg/storage/secret/metadata/keeper_model.go index ae8ef7bb908..8fd43dc35e0 100644 --- a/pkg/storage/secret/metadata/keeper_model.go +++ b/pkg/storage/secret/metadata/keeper_model.go @@ -6,8 +6,8 @@ import ( "time" "github.com/google/uuid" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/apimachinery/utils" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/storage/secret/migrator" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,7 +37,7 @@ func (*keeperDB) TableName() string { } // toKubernetes maps a DB row into a Kubernetes resource (metadata + spec). -func (kp *keeperDB) toKubernetes() (*secretv0alpha1.Keeper, error) { +func (kp *keeperDB) toKubernetes() (*secretv1beta1.Keeper, error) { annotations := make(map[string]string, 0) if kp.Annotations != "" { if err := json.Unmarshal([]byte(kp.Annotations), &annotations); err != nil { @@ -52,23 +52,23 @@ func (kp *keeperDB) toKubernetes() (*secretv0alpha1.Keeper, error) { } } - resource := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + resource := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: kp.Description, }, } // Obtain provider configs - provider := toProvider(secretv0alpha1.KeeperType(kp.Type), kp.Payload) + provider := toProvider(secretv1beta1.KeeperType(kp.Type), kp.Payload) switch v := provider.(type) { - case *secretv0alpha1.AWSKeeperConfig: - resource.Spec.AWS = v - case *secretv0alpha1.AzureKeeperConfig: + case *secretv1beta1.KeeperAWSConfig: + resource.Spec.Aws = v + case *secretv1beta1.KeeperAzureConfig: resource.Spec.Azure = v - case *secretv0alpha1.GCPKeeperConfig: - resource.Spec.GCP = v - case *secretv0alpha1.HashiCorpKeeperConfig: - resource.Spec.HashiCorp = v + case *secretv1beta1.KeeperGCPConfig: + resource.Spec.Gcp = v + case *secretv1beta1.KeeperHashiCorpConfig: + resource.Spec.HashiCorpVault = v } // Set all meta fields here for consistency. @@ -94,7 +94,7 @@ func (kp *keeperDB) toKubernetes() (*secretv0alpha1.Keeper, error) { } // toKeeperCreateRow maps a Kubernetes resource into a DB row for new resources being created/inserted. -func toKeeperCreateRow(kp *secretv0alpha1.Keeper, actorUID string) (*keeperDB, error) { +func toKeeperCreateRow(kp *secretv1beta1.Keeper, actorUID string) (*keeperDB, error) { row, err := toKeeperRow(kp) if err != nil { return nil, fmt.Errorf("failed to map to row: %w", err) @@ -112,7 +112,7 @@ func toKeeperCreateRow(kp *secretv0alpha1.Keeper, actorUID string) (*keeperDB, e } // toKeeperUpdateRow maps a Kubernetes resource into a DB row for existing resources being updated. -func toKeeperUpdateRow(currentRow *keeperDB, newKeeper *secretv0alpha1.Keeper, actorUID string) (*keeperDB, error) { +func toKeeperUpdateRow(currentRow *keeperDB, newKeeper *secretv1beta1.Keeper, actorUID string) (*keeperDB, error) { row, err := toKeeperRow(newKeeper) if err != nil { return nil, fmt.Errorf("failed to map to row: %w", err) @@ -130,7 +130,7 @@ func toKeeperUpdateRow(currentRow *keeperDB, newKeeper *secretv0alpha1.Keeper, a } // toKeeperRow maps a Kubernetes Keeper resource into a Keeper DB row. -func toKeeperRow(kp *secretv0alpha1.Keeper) (*keeperDB, error) { +func toKeeperRow(kp *secretv1beta1.Keeper) (*keeperDB, error) { var annotations string if len(kp.Annotations) > 0 { cleanedAnnotations := xkube.CleanAnnotations(kp.Annotations) @@ -196,19 +196,19 @@ func toKeeperRow(kp *secretv0alpha1.Keeper) (*keeperDB, error) { // toTypeAndPayload obtain keeper type and payload from a Kubernetes Keeper resource. // TODO: Move as method of KeeperSpec -func toTypeAndPayload(kp *secretv0alpha1.Keeper) (secretv0alpha1.KeeperType, string, error) { - if kp.Spec.AWS != nil { - payload, err := json.Marshal(kp.Spec.AWS.AWSCredentials) - return secretv0alpha1.AWSKeeperType, string(payload), err +func toTypeAndPayload(kp *secretv1beta1.Keeper) (secretv1beta1.KeeperType, string, error) { + if kp.Spec.Aws != nil { + payload, err := json.Marshal(kp.Spec.Aws) + return secretv1beta1.AWSKeeperType, string(payload), err } else if kp.Spec.Azure != nil { payload, err := json.Marshal(kp.Spec.Azure) - return secretv0alpha1.AzureKeeperType, string(payload), err - } else if kp.Spec.GCP != nil { - payload, err := json.Marshal(kp.Spec.GCP) - return secretv0alpha1.GCPKeeperType, string(payload), err - } else if kp.Spec.HashiCorp != nil { - payload, err := json.Marshal(kp.Spec.HashiCorp) - return secretv0alpha1.HashiCorpKeeperType, string(payload), err + return secretv1beta1.AzureKeeperType, string(payload), err + } else if kp.Spec.Gcp != nil { + payload, err := json.Marshal(kp.Spec.Gcp) + return secretv1beta1.GCPKeeperType, string(payload), err + } else if kp.Spec.HashiCorpVault != nil { + payload, err := json.Marshal(kp.Spec.HashiCorpVault) + return secretv1beta1.HashiCorpKeeperType, string(payload), err } return "", "", fmt.Errorf("no keeper type found") @@ -216,28 +216,28 @@ func toTypeAndPayload(kp *secretv0alpha1.Keeper) (secretv0alpha1.KeeperType, str // toProvider maps a KeeperType and payload into a provider config struct. // TODO: Move as method of KeeperType -func toProvider(keeperType secretv0alpha1.KeeperType, payload string) secretv0alpha1.KeeperConfig { +func toProvider(keeperType secretv1beta1.KeeperType, payload string) secretv1beta1.KeeperConfig { switch keeperType { - case secretv0alpha1.AWSKeeperType: - aws := &secretv0alpha1.AWSKeeperConfig{} + case secretv1beta1.AWSKeeperType: + aws := &secretv1beta1.KeeperAWSConfig{} if err := json.Unmarshal([]byte(payload), aws); err != nil { return nil } return aws - case secretv0alpha1.AzureKeeperType: - azure := &secretv0alpha1.AzureKeeperConfig{} + case secretv1beta1.AzureKeeperType: + azure := &secretv1beta1.KeeperAzureConfig{} if err := json.Unmarshal([]byte(payload), azure); err != nil { return nil } return azure - case secretv0alpha1.GCPKeeperType: - gcp := &secretv0alpha1.GCPKeeperConfig{} + case secretv1beta1.GCPKeeperType: + gcp := &secretv1beta1.KeeperGCPConfig{} if err := json.Unmarshal([]byte(payload), gcp); err != nil { return nil } return gcp - case secretv0alpha1.HashiCorpKeeperType: - hashicorp := &secretv0alpha1.HashiCorpKeeperConfig{} + case secretv1beta1.HashiCorpKeeperType: + hashicorp := &secretv1beta1.KeeperHashiCorpConfig{} if err := json.Unmarshal([]byte(payload), hashicorp); err != nil { return nil } @@ -248,17 +248,17 @@ func toProvider(keeperType secretv0alpha1.KeeperType, payload string) secretv0al } // extractSecureValues extracts unique securevalues referenced by the keeper, if any. -func extractSecureValues(kp *secretv0alpha1.Keeper) map[string]struct{} { +func extractSecureValues(kp *secretv1beta1.Keeper) map[string]struct{} { switch { - case kp.Spec.AWS != nil: + case kp.Spec.Aws != nil: secureValues := make(map[string]struct{}, 0) - if kp.Spec.AWS.AccessKeyID.SecureValueName != "" { - secureValues[kp.Spec.AWS.AccessKeyID.SecureValueName] = struct{}{} + if kp.Spec.Aws.AccessKeyID.SecureValueName != "" { + secureValues[kp.Spec.Aws.AccessKeyID.SecureValueName] = struct{}{} } - if kp.Spec.AWS.SecretAccessKey.SecureValueName != "" { - secureValues[kp.Spec.AWS.SecretAccessKey.SecureValueName] = struct{}{} + if kp.Spec.Aws.SecretAccessKey.SecureValueName != "" { + secureValues[kp.Spec.Aws.SecretAccessKey.SecureValueName] = struct{}{} } return secureValues @@ -269,12 +269,12 @@ func extractSecureValues(kp *secretv0alpha1.Keeper) map[string]struct{} { } // GCP does not reference secureValues. - case kp.Spec.GCP != nil: + case kp.Spec.Gcp != nil: return nil - case kp.Spec.HashiCorp != nil: - if kp.Spec.HashiCorp.Token.SecureValueName != "" { - return map[string]struct{}{kp.Spec.HashiCorp.Token.SecureValueName: {}} + case kp.Spec.HashiCorpVault != nil: + if kp.Spec.HashiCorpVault.Token.SecureValueName != "" { + return map[string]struct{}{kp.Spec.HashiCorpVault.Token.SecureValueName: {}} } } diff --git a/pkg/storage/secret/metadata/keeper_store.go b/pkg/storage/secret/metadata/keeper_store.go index defc9974125..6b4e73fc2bd 100644 --- a/pkg/storage/secret/metadata/keeper_store.go +++ b/pkg/storage/secret/metadata/keeper_store.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -46,7 +46,7 @@ func ProvideKeeperMetadataStorage( }, nil } -func (s *keeperMetadataStorage) Create(ctx context.Context, keeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) { +func (s *keeperMetadataStorage) Create(ctx context.Context, keeper *secretv1beta1.Keeper, actorUID string) (*secretv1beta1.Keeper, error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.Create", trace.WithAttributes( attribute.String("name", keeper.GetName()), @@ -111,7 +111,7 @@ func (s *keeperMetadataStorage) Create(ctx context.Context, keeper *secretv0alph return createdKeeper, nil } -func (s *keeperMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv0alpha1.Keeper, error) { +func (s *keeperMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv1beta1.Keeper, error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.Read", trace.WithAttributes( attribute.String("name", name), @@ -174,7 +174,7 @@ func (s *keeperMetadataStorage) read(ctx context.Context, namespace, name string return &keeper, nil } -func (s *keeperMetadataStorage) Update(ctx context.Context, newKeeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) { +func (s *keeperMetadataStorage) Update(ctx context.Context, newKeeper *secretv1beta1.Keeper, actorUID string) (*secretv1beta1.Keeper, error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.Update", trace.WithAttributes( attribute.String("name", newKeeper.GetName()), @@ -291,7 +291,7 @@ func (s *keeperMetadataStorage) Delete(ctx context.Context, namespace xkube.Name return nil } -func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) (keeperList []secretv0alpha1.Keeper, err error) { +func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) (keeperList []secretv1beta1.Keeper, err error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.List", trace.WithAttributes( attribute.String("namespace", namespace.String()), @@ -318,7 +318,7 @@ func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namesp } defer func() { _ = rows.Close() }() - keepers := make([]secretv0alpha1.Keeper, 0) + keepers := make([]secretv1beta1.Keeper, 0) for rows.Next() { var row keeperDB @@ -350,7 +350,7 @@ func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namesp // validateSecureValueReferences checks that all secure values referenced by the keeper exist and are not referenced by other third-party keepers. // It is used by other methods inside a transaction. -func (s *keeperMetadataStorage) validateSecureValueReferences(ctx context.Context, keeper *secretv0alpha1.Keeper) (err error) { +func (s *keeperMetadataStorage) validateSecureValueReferences(ctx context.Context, keeper *secretv1beta1.Keeper) (err error) { ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.ValidateSecureValueReferences", trace.WithAttributes( attribute.String("name", keeper.GetName()), attribute.String("namespace", keeper.GetNamespace()), @@ -497,7 +497,7 @@ func (s *keeperMetadataStorage) validateSecureValueReferences(ctx context.Contex return nil } -func (s *keeperMetadataStorage) GetKeeperConfig(ctx context.Context, namespace string, name *string, opts contracts.ReadOpts) (secretv0alpha1.KeeperConfig, error) { +func (s *keeperMetadataStorage) GetKeeperConfig(ctx context.Context, namespace string, name *string, opts contracts.ReadOpts) (secretv1beta1.KeeperConfig, error) { ctx, span := s.tracer.Start(ctx, "KeeperMetadataStorage.GetKeeperConfig", trace.WithAttributes( attribute.String("namespace", namespace), attribute.Bool("isForUpdate", opts.ForUpdate), @@ -506,7 +506,7 @@ func (s *keeperMetadataStorage) GetKeeperConfig(ctx context.Context, namespace s // Check if keeper is the systemwide one. if name == nil { - return &secretv0alpha1.SystemKeeperConfig{}, nil + return &secretv1beta1.SystemKeeperConfig{}, nil } start := time.Now() @@ -518,7 +518,7 @@ func (s *keeperMetadataStorage) GetKeeperConfig(ctx context.Context, namespace s return nil, err } - keeperConfig := toProvider(secretv0alpha1.KeeperType(kp.Type), kp.Payload) + keeperConfig := toProvider(secretv1beta1.KeeperType(kp.Type), kp.Payload) s.metrics.KeeperMetadataGetKeeperConfigDuration.Observe(time.Since(start).Seconds()) diff --git a/pkg/storage/secret/metadata/keeper_store_test.go b/pkg/storage/secret/metadata/keeper_store_test.go index c5da14eaf2d..02f2207b61f 100644 --- a/pkg/storage/secret/metadata/keeper_store_test.go +++ b/pkg/storage/secret/metadata/keeper_store_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/storage/secret/migrator" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/trace/noop" + "k8s.io/utils/ptr" ) func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { @@ -22,10 +23,10 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { defaultKeeperName := "kp-test" defaultKeeperNS := "default" - testKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + testKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } @@ -41,7 +42,7 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { // get system keeper config keeperConfig, err := keeperMetadataStorage.GetKeeperConfig(ctx, defaultKeeperNS, nil, contracts.ReadOpts{}) require.NoError(t, err) - require.IsType(t, &secretv0alpha1.SystemKeeperConfig{}, keeperConfig) + require.IsType(t, &secretv1beta1.SystemKeeperConfig{}, keeperConfig) }) t.Run("get test keeper config", func(t *testing.T) { @@ -90,10 +91,10 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { keeperTest := "kp-test2" keeperNamespaceTest := "ns" - testKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + testKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "another description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } testKeeper.Name = keeperTest @@ -128,10 +129,10 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { keeperNamespaceTest := "ns" // Create initial keeper - initialKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + initialKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "initial description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } initialKeeper.Name = keeperTest @@ -147,10 +148,10 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { require.Equal(t, "initial description", keeper.Spec.Description) // Update the keeper with new values - updatedKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + updatedKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "updated description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } updatedKeeper.Name = keeperTest @@ -182,19 +183,17 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { keeperNamespaceTest := "ns" // Create initial keeper with first AWS config - initialKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + initialKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "initial description", - AWS: &secretv0alpha1.AWSKeeperConfig{ - AWSCredentials: secretv0alpha1.AWSCredentials{ - AccessKeyID: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_ACCESS_KEY_ID_1", - }, - SecretAccessKey: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_SECRET_ACCESS_KEY_1", - }, - KMSKeyID: "kms-key-id-1", + Aws: &secretv1beta1.KeeperAWSConfig{ + AccessKeyID: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_ACCESS_KEY_ID_1", }, + SecretAccessKey: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_SECRET_ACCESS_KEY_1", + }, + KmsKeyID: ptr.To("kms-key-id-1"), }, }, } @@ -208,24 +207,22 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { // Verify initial AWS config keeper, err := keeperMetadataStorage.Read(ctx, xkube.Namespace(keeperNamespaceTest), keeperTest, contracts.ReadOpts{}) require.NoError(t, err) - require.Equal(t, "AWS_ACCESS_KEY_ID_1", keeper.Spec.AWS.AccessKeyID.ValueFromEnv) - require.Equal(t, "AWS_SECRET_ACCESS_KEY_1", keeper.Spec.AWS.SecretAccessKey.ValueFromEnv) - require.Equal(t, "kms-key-id-1", keeper.Spec.AWS.KMSKeyID) + require.Equal(t, "AWS_ACCESS_KEY_ID_1", keeper.Spec.Aws.AccessKeyID.ValueFromEnv) + require.Equal(t, "AWS_SECRET_ACCESS_KEY_1", keeper.Spec.Aws.SecretAccessKey.ValueFromEnv) + require.Equal(t, "kms-key-id-1", *keeper.Spec.Aws.KmsKeyID) // Update with new AWS config - updatedKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + updatedKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "updated description", - AWS: &secretv0alpha1.AWSKeeperConfig{ - AWSCredentials: secretv0alpha1.AWSCredentials{ - AccessKeyID: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_ACCESS_KEY_ID_2", - }, - SecretAccessKey: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_SECRET_ACCESS_KEY_2", - }, - KMSKeyID: "kms-key-id-2", + Aws: &secretv1beta1.KeeperAWSConfig{ + AccessKeyID: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_ACCESS_KEY_ID_2", }, + SecretAccessKey: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_SECRET_ACCESS_KEY_2", + }, + KmsKeyID: ptr.To("kms-key-id-2"), }, }, } @@ -239,9 +236,9 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { // Verify updated AWS config updatedKeeper, err = keeperMetadataStorage.Read(ctx, xkube.Namespace(keeperNamespaceTest), keeperTest, contracts.ReadOpts{}) require.NoError(t, err) - require.Equal(t, "AWS_ACCESS_KEY_ID_2", updatedKeeper.Spec.AWS.AccessKeyID.ValueFromEnv) - require.Equal(t, "AWS_SECRET_ACCESS_KEY_2", updatedKeeper.Spec.AWS.SecretAccessKey.ValueFromEnv) - require.Equal(t, "kms-key-id-2", updatedKeeper.Spec.AWS.KMSKeyID) + require.Equal(t, "AWS_ACCESS_KEY_ID_2", updatedKeeper.Spec.Aws.AccessKeyID.ValueFromEnv) + require.Equal(t, "AWS_SECRET_ACCESS_KEY_2", updatedKeeper.Spec.Aws.SecretAccessKey.ValueFromEnv) + require.Equal(t, "kms-key-id-2", *updatedKeeper.Spec.Aws.KmsKeyID) }) t.Run("list keepers in empty namespace", func(t *testing.T) { @@ -276,17 +273,15 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { keeperNamespaceTest := "ns1" // Create initial keeper - initialKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + initialKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "initial description", - AWS: &secretv0alpha1.AWSKeeperConfig{ - AWSCredentials: secretv0alpha1.AWSCredentials{ - AccessKeyID: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_ACCESS_KEY_ID", - }, - SecretAccessKey: secretv0alpha1.CredentialValue{ - ValueFromEnv: "AWS_SECRET_ACCESS_KEY", - }, + Aws: &secretv1beta1.KeeperAWSConfig{ + AccessKeyID: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_ACCESS_KEY_ID", + }, + SecretAccessKey: secretv1beta1.KeeperCredentialValue{ + ValueFromEnv: "AWS_SECRET_ACCESS_KEY", }, }, }, @@ -320,10 +315,10 @@ func Test_KeeperMetadataStorage_GetKeeperConfig(t *testing.T) { ctx := context.Background() keeperMetadataStorage := initStorage(t) - nonExistentKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + nonExistentKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "some description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } nonExistentKeeper.Name = "non-existent" diff --git a/pkg/storage/secret/metadata/secure_value_model.go b/pkg/storage/secret/metadata/secure_value_model.go index 134128f8a25..c2f59a6e4c1 100644 --- a/pkg/storage/secret/metadata/secure_value_model.go +++ b/pkg/storage/secret/metadata/secure_value_model.go @@ -7,8 +7,8 @@ import ( "time" "github.com/google/uuid" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/apimachinery/utils" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/storage/secret/migrator" @@ -45,7 +45,7 @@ func (*secureValueDB) TableName() string { } // toKubernetes maps a DB row into a Kubernetes resource (metadata + spec). -func (sv *secureValueDB) toKubernetes() (*secretv0alpha1.SecureValue, error) { +func (sv *secureValueDB) toKubernetes() (*secretv1beta1.SecureValue, error) { annotations := make(map[string]string, 0) if sv.Annotations != "" { if err := json.Unmarshal([]byte(sv.Annotations), &annotations); err != nil { @@ -68,12 +68,12 @@ func (sv *secureValueDB) toKubernetes() (*secretv0alpha1.SecureValue, error) { } } - resource := &secretv0alpha1.SecureValue{ - Spec: secretv0alpha1.SecureValueSpec{ + resource := &secretv1beta1.SecureValue{ + Spec: secretv1beta1.SecureValueSpec{ Description: sv.Description, Decrypters: decrypters, }, - Status: secretv0alpha1.SecureValueStatus{ + Status: secretv1beta1.SecureValueStatus{ ExternalID: sv.ExternalID, Version: sv.Version, }, @@ -111,7 +111,7 @@ func (sv *secureValueDB) toKubernetes() (*secretv0alpha1.SecureValue, error) { } // toCreateRow maps a Kubernetes resource into a DB row for new resources being created/inserted. -func toCreateRow(sv *secretv0alpha1.SecureValue, actorUID string) (*secureValueDB, error) { +func toCreateRow(sv *secretv1beta1.SecureValue, actorUID string) (*secureValueDB, error) { row, err := toRow(sv, "") if err != nil { return nil, fmt.Errorf("failed to convert SecureValue to secureValueDB: %w", err) @@ -129,7 +129,7 @@ func toCreateRow(sv *secretv0alpha1.SecureValue, actorUID string) (*secureValueD } // toRow maps a Kubernetes resource into a DB row. -func toRow(sv *secretv0alpha1.SecureValue, externalID string) (*secureValueDB, error) { +func toRow(sv *secretv1beta1.SecureValue, externalID string) (*secureValueDB, error) { var annotations string if len(sv.Annotations) > 0 { cleanedAnnotations := xkube.CleanAnnotations(sv.Annotations) diff --git a/pkg/storage/secret/metadata/secure_value_store.go b/pkg/storage/secret/metadata/secure_value_store.go index ecc22df28bd..3653c6006df 100644 --- a/pkg/storage/secret/metadata/secure_value_store.go +++ b/pkg/storage/secret/metadata/secure_value_store.go @@ -5,7 +5,7 @@ import ( "fmt" "time" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -46,7 +46,7 @@ type secureValueMetadataStorage struct { tracer trace.Tracer } -func (s *secureValueMetadataStorage) Create(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) { +func (s *secureValueMetadataStorage) Create(ctx context.Context, sv *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "SecureValueMetadataStorage.Create", trace.WithAttributes( attribute.String("name", sv.GetName()), @@ -289,7 +289,7 @@ func (s *secureValueMetadataStorage) readActiveVersion(ctx context.Context, name return secureValue, nil } -func (s *secureValueMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv0alpha1.SecureValue, error) { +func (s *secureValueMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv1beta1.SecureValue, error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "SecureValueMetadataStorage.Read", trace.WithAttributes( attribute.String("name", name), @@ -314,7 +314,7 @@ func (s *secureValueMetadataStorage) Read(ctx context.Context, namespace xkube.N return secureValueKub, nil } -func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) (svList []secretv0alpha1.SecureValue, error error) { +func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) (svList []secretv1beta1.SecureValue, error error) { start := time.Now() ctx, span := s.tracer.Start(ctx, "SecureValueMetadataStorage.List", trace.WithAttributes( attribute.String("namespace", namespace.String()), @@ -341,7 +341,7 @@ func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.N } defer func() { _ = rows.Close() }() - secureValues := make([]secretv0alpha1.SecureValue, 0) + secureValues := make([]secretv1beta1.SecureValue, 0) for rows.Next() { row := secureValueDB{} diff --git a/pkg/storage/secret/metadata/secure_value_store_test.go b/pkg/storage/secret/metadata/secure_value_store_test.go index 1de2dbf73f1..4014d497264 100644 --- a/pkg/storage/secret/metadata/secure_value_store_test.go +++ b/pkg/storage/secret/metadata/secure_value_store_test.go @@ -4,7 +4,7 @@ import ( "context" "testing" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "github.com/grafana/grafana/pkg/registry/apis/secret/contracts" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" "github.com/grafana/grafana/pkg/services/featuremgmt" @@ -14,15 +14,16 @@ import ( "github.com/grafana/grafana/pkg/storage/secret/migrator" "github.com/stretchr/testify/require" "go.opentelemetry.io/otel/trace/noop" + "k8s.io/utils/ptr" ) func createTestKeeper(t *testing.T, ctx context.Context, keeperStorage contracts.KeeperMetadataStorage, name, namespace string) string { t.Helper() - testKeeper := &secretv0alpha1.Keeper{ - Spec: secretv0alpha1.KeeperSpec{ + testKeeper := &secretv1beta1.Keeper{ + Spec: secretv1beta1.KeeperSpec{ Description: "test keeper description", - AWS: &secretv0alpha1.AWSKeeperConfig{}, + Aws: &secretv1beta1.KeeperAWSConfig{}, }, } testKeeper.Name = name @@ -56,10 +57,10 @@ func Test_SecureValueMetadataStorage_CreateAndRead(t *testing.T) { keeperName := createTestKeeper(t, ctx, keeperStorage, "test-keeper", "default") // Create a test secure value - testSecureValue := &secretv0alpha1.SecureValue{ - Spec: secretv0alpha1.SecureValueSpec{ + testSecureValue := &secretv1beta1.SecureValue{ + Spec: secretv1beta1.SecureValueSpec{ Description: "test description", - Value: "test-value", + Value: ptr.To(secretv1beta1.NewExposedSecureValue("test-value")), Keeper: &keeperName, }, } @@ -110,10 +111,10 @@ func Test_SecureValueMetadataStorage_CreateAndRead(t *testing.T) { keeperName := createTestKeeper(t, ctx, keeperStorage, "test-keeper-2", "default") // Create a test secure value - testSecureValue := &secretv0alpha1.SecureValue{ - Spec: secretv0alpha1.SecureValueSpec{ + testSecureValue := &secretv1beta1.SecureValue{ + Spec: secretv1beta1.SecureValueSpec{ Description: "test description 2", - Value: "test-value-2", + Value: ptr.To(secretv1beta1.NewExposedSecureValue("test-value-2")), Keeper: &keeperName, }, } diff --git a/pkg/storage/secret/metadata/secure_value_test.go b/pkg/storage/secret/metadata/secure_value_test.go index 459db29f74a..d35213ecd77 100644 --- a/pkg/storage/secret/metadata/secure_value_test.go +++ b/pkg/storage/secret/metadata/secure_value_test.go @@ -5,18 +5,20 @@ import ( "slices" "testing" - secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1" + secretv1beta1 "github.com/grafana/grafana/apps/secret/pkg/apis/secret/v1beta1" "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/testutils" "github.com/grafana/grafana/pkg/registry/apis/secret/xkube" + "github.com/mitchellh/copystructure" "github.com/stretchr/testify/require" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/ptr" "pgregory.net/rapid" ) type modelSecureValue struct { - *secretv0alpha1.SecureValue + *secretv1beta1.SecureValue active bool } @@ -66,7 +68,7 @@ func (m *model) readActiveVersion(namespace, name string) *modelSecureValue { return nil } -func (m *model) create(sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) { +func (m *model) create(sv *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, error) { modelSv := &modelSecureValue{sv, false} modelSv.Status.Version = m.getNewVersionNumber(modelSv.Namespace, modelSv.Name) modelSv.Status.ExternalID = fmt.Sprintf("%d", modelSv.Status.Version) @@ -75,9 +77,9 @@ func (m *model) create(sv *secretv0alpha1.SecureValue, actorUID string) (*secret return modelSv.SecureValue, nil } -func (m *model) update(newSecureValue *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, bool, error) { +func (m *model) update(newSecureValue *secretv1beta1.SecureValue, actorUID string) (*secretv1beta1.SecureValue, bool, error) { // If the payload doesn't contain a value, get the value from current version - if newSecureValue.Spec.Value == "" { + if newSecureValue.Spec.Value == nil { sv := m.readActiveVersion(newSecureValue.Namespace, newSecureValue.Name) if sv == nil { return nil, false, contracts.ErrSecureValueNotFound @@ -88,7 +90,7 @@ func (m *model) update(newSecureValue *secretv0alpha1.SecureValue, actorUID stri return createdSv, true, err } -func (m *model) delete(namespace, name string) (*secretv0alpha1.SecureValue, error) { +func (m *model) delete(namespace, name string) (*secretv1beta1.SecureValue, error) { modelSv := m.readActiveVersion(namespace, name) if modelSv == nil { return nil, contracts.ErrSecureValueNotFound @@ -97,8 +99,8 @@ func (m *model) delete(namespace, name string) (*secretv0alpha1.SecureValue, err return modelSv.SecureValue, nil } -func (m *model) list(namespace string) (*secretv0alpha1.SecureValueList, error) { - out := make([]secretv0alpha1.SecureValue, 0) +func (m *model) list(namespace string) (*secretv1beta1.SecureValueList, error) { + out := make([]secretv1beta1.SecureValue, 0) for _, v := range m.secureValues { if v.Namespace == namespace && v.active { @@ -106,7 +108,7 @@ func (m *model) list(namespace string) (*secretv0alpha1.SecureValueList, error) } } - return &secretv0alpha1.SecureValueList{Items: out}, nil + return &secretv1beta1.SecureValueList{Items: out}, nil } func (m *model) decrypt(decrypter, namespace, name string) (map[string]service.DecryptResult, error) { @@ -116,7 +118,7 @@ func (m *model) decrypt(decrypter, namespace, name string) (map[string]service.D v.active { if slices.ContainsFunc(v.Spec.Decrypters, func(d string) bool { return d == decrypter }) { return map[string]service.DecryptResult{ - name: service.NewDecryptResultValue(&v.DeepCopy().Spec.Value), + name: service.NewDecryptResultValue(deepCopy(v).Spec.Value), }, nil } @@ -130,7 +132,7 @@ func (m *model) decrypt(decrypter, namespace, name string) (map[string]service.D }, nil } -func (m *model) read(namespace, name string) (*secretv0alpha1.SecureValue, error) { +func (m *model) read(namespace, name string) (*secretv1beta1.SecureValue, error) { modelSv := m.readActiveVersion(namespace, name) if modelSv == nil { return nil, contracts.ErrSecureValueNotFound @@ -142,25 +144,25 @@ var ( decryptersGen = rapid.SampledFrom([]string{"svc1", "svc2", "svc3", "svc4", "svc5"}) nameGen = rapid.SampledFrom([]string{"n1", "n2", "n3", "n4", "n5"}) namespaceGen = rapid.SampledFrom([]string{"ns1", "ns2", "ns3", "ns4", "ns5"}) - anySecureValueGen = rapid.Custom(func(t *rapid.T) *secretv0alpha1.SecureValue { - return &secretv0alpha1.SecureValue{ + anySecureValueGen = rapid.Custom(func(t *rapid.T) *secretv1beta1.SecureValue { + return &secretv1beta1.SecureValue{ ObjectMeta: metav1.ObjectMeta{ Name: nameGen.Draw(t, "name"), Namespace: namespaceGen.Draw(t, "ns"), }, - Spec: secretv0alpha1.SecureValueSpec{ + Spec: secretv1beta1.SecureValueSpec{ Description: rapid.SampledFrom([]string{"d1", "d2", "d3", "d4", "d5"}).Draw(t, "description"), - Value: secretv0alpha1.NewExposedSecureValue(rapid.SampledFrom([]string{"v1", "v2", "v3", "v4", "v5"}).Draw(t, "value")), + Value: ptr.To(secretv1beta1.NewExposedSecureValue(rapid.SampledFrom([]string{"v1", "v2", "v3", "v4", "v5"}).Draw(t, "value"))), Decrypters: rapid.SliceOfDistinct(decryptersGen, func(v string) string { return v }).Draw(t, "decrypters"), }, - Status: secretv0alpha1.SecureValueStatus{}, + Status: secretv1beta1.SecureValueStatus{}, } }) - updateSecureValueGen = rapid.Custom(func(t *rapid.T) *secretv0alpha1.SecureValue { + updateSecureValueGen = rapid.Custom(func(t *rapid.T) *secretv1beta1.SecureValue { sv := anySecureValueGen.Draw(t, "sv") // Maybe update the secret value, maybe not if !rapid.Bool().Draw(t, "should_update_value") { - sv.Spec.Value = "" + sv.Spec.Value = nil } return sv }) @@ -184,17 +186,17 @@ type decryptInput struct { func TestModel(t *testing.T) { t.Parallel() - sv := &secretv0alpha1.SecureValue{ + sv := &secretv1beta1.SecureValue{ ObjectMeta: metav1.ObjectMeta{ Name: "sv1", Namespace: "ns1", }, - Spec: secretv0alpha1.SecureValueSpec{ + Spec: secretv1beta1.SecureValueSpec{ Description: "desc1", - Value: secretv0alpha1.NewExposedSecureValue("v1"), + Value: ptr.To(secretv1beta1.NewExposedSecureValue("v1")), Decrypters: []string{"decrypter1"}, }, - Status: secretv0alpha1.SecureValueStatus{}, + Status: secretv1beta1.SecureValueStatus{}, } t.Run("creating secure values", func(t *testing.T) { @@ -203,14 +205,14 @@ func TestModel(t *testing.T) { m := newModel() // Create a secure value - sv1, err := m.create(sv.DeepCopy(), "actor-uid") + sv1, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) require.Equal(t, sv.Namespace, sv1.Namespace) require.Equal(t, sv.Name, sv1.Name) require.EqualValues(t, 1, sv1.Status.Version) // Create a new version of a secure value - sv2, err := m.create(sv.DeepCopy(), "actor-uid") + sv2, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) require.Equal(t, sv.Namespace, sv2.Namespace) require.Equal(t, sv.Name, sv2.Name) @@ -222,27 +224,27 @@ func TestModel(t *testing.T) { m := newModel() - sv1, err := m.create(sv.DeepCopy(), "actor-uid") + sv1, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) // Create a new version of a secure value by updating it - sv2, _, err := m.update(sv1.DeepCopy(), "actor-uid") + sv2, _, err := m.update(deepCopy(sv1), "actor-uid") require.NoError(t, err) require.Equal(t, sv.Namespace, sv2.Namespace) require.Equal(t, sv.Name, sv2.Name) require.EqualValues(t, 2, sv2.Status.Version) // Try updating a secure value that doesn't exist without specifying a value for it - sv3 := sv2.DeepCopy() + sv3 := deepCopy(sv2) sv3.Name = "i_dont_exist" - sv3.Spec.Value = "" + sv3.Spec.Value = nil _, _, err = m.update(sv3, "actor-uid") require.ErrorIs(t, err, contracts.ErrSecureValueNotFound) // Updating a value that doesn't exist creates a new version - sv4 := sv3.DeepCopy() + sv4 := deepCopy(sv3) sv4.Name = "i_dont_exist" - sv4.Spec.Value = secretv0alpha1.NewExposedSecureValue("sv4") + sv4.Spec.Value = ptr.To(secretv1beta1.NewExposedSecureValue("sv4")) sv4, _, err = m.update(sv4, "actor-uid") require.NoError(t, err) require.EqualValues(t, 1, sv4.Status.Version) @@ -253,7 +255,7 @@ func TestModel(t *testing.T) { m := newModel() - sv1, err := m.create(sv.DeepCopy(), "actor-uid") + sv1, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) // Deleting a secure value @@ -279,7 +281,7 @@ func TestModel(t *testing.T) { require.Equal(t, 0, len(list.Items)) // Create a secure value - sv1, err := m.create(sv.DeepCopy(), "actor-uid") + sv1, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) // 1 secure value exists and it should be returned @@ -304,7 +306,8 @@ func TestModel(t *testing.T) { require.ErrorIs(t, result["name"].Error(), contracts.ErrDecryptNotFound) // Create a secure value - sv1, err := m.create(sv.DeepCopy(), "actor-uid") + secret := "v1" + sv1, err := m.create(deepCopy(sv), "actor-uid") require.NoError(t, err) // Decrypt the just created secure value @@ -312,7 +315,7 @@ func TestModel(t *testing.T) { require.NoError(t, err) require.Equal(t, 1, len(result)) require.Nil(t, result[sv1.Name].Error()) - require.Equal(t, result[sv1.Name].Value().DangerouslyExposeAndConsumeValue(), sv.DeepCopy().Spec.Value.DangerouslyExposeAndConsumeValue()) + require.Equal(t, secret, result[sv1.Name].Value().DangerouslyExposeAndConsumeValue()) }) } @@ -328,9 +331,10 @@ func TestStateMachine(t *testing.T) { t.Repeat(map[string]func(*rapid.T){ "create": func(t *rapid.T) { sv := anySecureValueGen.Draw(t, "sv") - modelCreatedSv, modelErr := model.create(sv.DeepCopy(), "actor-uid") - createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(sv.DeepCopy())) + modelCreatedSv, modelErr := model.create(deepCopy(sv), "actor-uid") + + createdSv, err := sut.CreateSv(t.Context(), testutils.CreateSvWithSv(deepCopy(sv))) if err != nil || modelErr != nil { require.ErrorIs(t, err, modelErr) return @@ -341,8 +345,8 @@ func TestStateMachine(t *testing.T) { }, "update": func(t *rapid.T) { sv := updateSecureValueGen.Draw(t, "sv") - modelCreatedSv, _, modelErr := model.update(sv.DeepCopy(), "actor-uid") - createdSv, err := sut.UpdateSv(t.Context(), sv.DeepCopy()) + modelCreatedSv, _, modelErr := model.update(deepCopy(sv), "actor-uid") + createdSv, err := sut.UpdateSv(t.Context(), deepCopy(sv)) if err != nil || modelErr != nil { require.ErrorIs(t, err, modelErr) return @@ -379,7 +383,7 @@ func TestStateMachine(t *testing.T) { // PERFORMANCE: The lists are always small for _, v1 := range modelList.Items { - if !slices.ContainsFunc(list.Items, func(v2 secretv0alpha1.SecureValue) bool { + if !slices.ContainsFunc(list.Items, func(v2 secretv1beta1.SecureValue) bool { return v2.Namespace == v1.Namespace && v2.Name == v1.Name && v2.Status.Version == v1.Status.Version }) { t.Fatalf("expected sut to return secure value ns=%+v name=%+v version=%+v in the result", v1.Namespace, v1.Name, v1.Status.Version) @@ -417,3 +421,11 @@ func TestStateMachine(t *testing.T) { }) }) } + +func deepCopy[T any](sv T) T { + copied, err := copystructure.Copy(sv) + if err != nil { + panic(fmt.Sprintf("failed to copy secure value: %v", err)) + } + return copied.(T) +}