Secrets: Bump API version to v1beta1 (#108026)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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=
|
||||
|
||||
+1
-2
@@ -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=
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
)
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
}
|
||||
|
||||
|
||||
@@ -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()),
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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: {}}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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{}
|
||||
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user