SecretsManager: Keeper and secure value contracts, secretkeeper changes (#105379)
Co-authored-by: PoorlyDefinedBehaviour <brunotj2015@hotmail.com> Co-authored-by: Matheus Macabu <macabu@users.noreply.github.com>
This commit is contained in:
co-authored by
PoorlyDefinedBehaviour
Matheus Macabu
parent
137639e0de
commit
8c64078965
@@ -6,7 +6,7 @@ import (
|
||||
|
||||
secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -15,23 +15,74 @@ var (
|
||||
|
||||
// KeeperMetadataStorage is the interface for wiring and dependency injection.
|
||||
type KeeperMetadataStorage interface {
|
||||
Create(ctx context.Context, keeper *secretv0alpha1.Keeper) (*secretv0alpha1.Keeper, error)
|
||||
Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.Keeper, error)
|
||||
Update(ctx context.Context, keeper *secretv0alpha1.Keeper) (*secretv0alpha1.Keeper, error)
|
||||
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)
|
||||
Delete(ctx context.Context, namespace xkube.Namespace, name string) error
|
||||
List(ctx context.Context, namespace xkube.Namespace, options *internalversion.ListOptions) (*secretv0alpha1.KeeperList, error)
|
||||
List(ctx context.Context, namespace xkube.Namespace) ([]secretv0alpha1.Keeper, error)
|
||||
GetKeeperConfig(ctx context.Context, namespace string, name *string, opts ReadOpts) (secretv0alpha1.KeeperConfig, error)
|
||||
}
|
||||
|
||||
// KeeperType represents the type of a Keeper.
|
||||
type KeeperType string
|
||||
// ErrKeeperInvalidSecureValues is returned when a Keeper references SecureValues that do not exist.
|
||||
type ErrKeeperInvalidSecureValues struct {
|
||||
invalidSecureValues map[string]struct{}
|
||||
}
|
||||
|
||||
const (
|
||||
SQLKeeperType KeeperType = "sql"
|
||||
AWSKeeperType KeeperType = "aws"
|
||||
AzureKeeperType KeeperType = "azure"
|
||||
GCPKeeperType KeeperType = "gcp"
|
||||
HashiCorpKeeperType KeeperType = "hashicorp"
|
||||
)
|
||||
var _ xkube.ErrorLister = (*ErrKeeperInvalidSecureValues)(nil)
|
||||
|
||||
func NewErrKeeperInvalidSecureValues(invalidSecureValues map[string]struct{}) *ErrKeeperInvalidSecureValues {
|
||||
return &ErrKeeperInvalidSecureValues{invalidSecureValues: invalidSecureValues}
|
||||
}
|
||||
|
||||
func (e *ErrKeeperInvalidSecureValues) Error() string {
|
||||
return e.ErrorList().ToAggregate().Error()
|
||||
}
|
||||
|
||||
func (e *ErrKeeperInvalidSecureValues) ErrorList() field.ErrorList {
|
||||
errs := make(field.ErrorList, 0, len(e.invalidSecureValues))
|
||||
|
||||
path := field.NewPath("secureValueName")
|
||||
|
||||
for sv := range e.invalidSecureValues {
|
||||
errs = append(errs, field.NotFound(path, sv))
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// ErrKeeperInvalidSecureValuesReference is returned when a Keeper references SecureValues from a non-SQL Keeper.
|
||||
type ErrKeeperInvalidSecureValuesReference struct {
|
||||
invalidSecureValues map[string]string
|
||||
}
|
||||
|
||||
var _ xkube.ErrorLister = (*ErrKeeperInvalidSecureValuesReference)(nil)
|
||||
|
||||
func NewErrKeeperInvalidSecureValuesReference(invalidSecureValues map[string]string) *ErrKeeperInvalidSecureValuesReference {
|
||||
return &ErrKeeperInvalidSecureValuesReference{invalidSecureValues: invalidSecureValues}
|
||||
}
|
||||
|
||||
func (e *ErrKeeperInvalidSecureValuesReference) Error() string {
|
||||
return e.ErrorList().ToAggregate().Error()
|
||||
}
|
||||
|
||||
func (e *ErrKeeperInvalidSecureValuesReference) ErrorList() field.ErrorList {
|
||||
errs := make(field.ErrorList, 0, len(e.invalidSecureValues))
|
||||
|
||||
path := field.NewPath("secureValueName")
|
||||
|
||||
for sv, keeper := range e.invalidSecureValues {
|
||||
errs = append(
|
||||
errs,
|
||||
field.TypeInvalid(
|
||||
path,
|
||||
sv,
|
||||
`cannot reference third-party keeper "`+keeper+`" in another third-party keeper, use a "sql" keeper instead`,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// ExternalID represents either the secure value's GUID or ref (in case of external secret references).
|
||||
// This is saved in the secure_value metadata storage as `external_id`.
|
||||
@@ -50,6 +101,8 @@ type Keeper interface {
|
||||
Delete(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, externalID ExternalID) error
|
||||
}
|
||||
|
||||
const (
|
||||
DefaultSQLKeeper = "kp-default-sql"
|
||||
)
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -6,18 +6,33 @@ import (
|
||||
|
||||
secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/xkube"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
)
|
||||
|
||||
type DecryptSecureValue struct {
|
||||
Keeper *string
|
||||
Ref string
|
||||
ExternalID string
|
||||
Decrypters []string
|
||||
}
|
||||
|
||||
var (
|
||||
ErrSecureValueNotFound = errors.New("secure value not found")
|
||||
ErrSecureValueNotFound = errors.New("secure value not found")
|
||||
ErrSecureValueAlreadyExists = errors.New("secure value already exists")
|
||||
ErrSecureValueOperationInProgress = errors.New("an operation is already in progress for the secure value")
|
||||
)
|
||||
|
||||
type ReadOpts struct {
|
||||
ForUpdate bool
|
||||
}
|
||||
|
||||
// SecureValueMetadataStorage is the interface for wiring and dependency injection.
|
||||
type SecureValueMetadataStorage interface {
|
||||
Create(ctx context.Context, sv *secretv0alpha1.SecureValue) (*secretv0alpha1.SecureValue, error)
|
||||
Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.SecureValue, error)
|
||||
Update(ctx context.Context, sv *secretv0alpha1.SecureValue) (*secretv0alpha1.SecureValue, error)
|
||||
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)
|
||||
Update(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error)
|
||||
Delete(ctx context.Context, namespace xkube.Namespace, name string) error
|
||||
List(ctx context.Context, namespace xkube.Namespace, options *internalversion.ListOptions) (*secretv0alpha1.SecureValueList, error)
|
||||
List(ctx context.Context, namespace xkube.Namespace) (*secretv0alpha1.SecureValueList, error)
|
||||
SetStatus(ctx context.Context, namespace xkube.Namespace, name string, status secretv0alpha1.SecureValueStatus) error
|
||||
SetExternalID(ctx context.Context, namespace xkube.Namespace, name string, externalID ExternalID) error
|
||||
ReadForDecrypt(ctx context.Context, namespace xkube.Namespace, name string) (*DecryptSecureValue, error)
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -79,12 +80,27 @@ func (s *KeeperRest) List(ctx context.Context, options *internalversion.ListOpti
|
||||
return nil, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
keepersList, err := s.storage.List(ctx, xkube.Namespace(namespace), options)
|
||||
labelSelector := options.LabelSelector
|
||||
if labelSelector == nil {
|
||||
labelSelector = labels.Everything()
|
||||
}
|
||||
|
||||
keepersList, err := s.storage.List(ctx, xkube.Namespace(namespace))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list keepers: %w", err)
|
||||
}
|
||||
|
||||
return keepersList, nil
|
||||
allowedKeepers := make([]secretv0alpha1.Keeper, 0)
|
||||
|
||||
for _, keeper := range keepersList {
|
||||
if labelSelector.Matches(labels.Set(keeper.Labels)) {
|
||||
allowedKeepers = append(allowedKeepers, keeper)
|
||||
}
|
||||
}
|
||||
|
||||
return &secretv0alpha1.KeeperList{
|
||||
Items: allowedKeepers,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Get calls the inner `store` (persistence) and returns a `Keeper` by `name`.
|
||||
@@ -94,7 +110,8 @@ func (s *KeeperRest) Get(ctx context.Context, name string, options *metav1.GetOp
|
||||
return nil, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
kp, err := s.storage.Read(ctx, xkube.Namespace(namespace), name)
|
||||
// TODO: readopts
|
||||
kp, err := s.storage.Read(ctx, xkube.Namespace(namespace), name, contracts.ReadOpts{})
|
||||
if err != nil {
|
||||
if errors.Is(err, contracts.ErrKeeperNotFound) {
|
||||
return nil, s.resource.NewNotFound(name)
|
||||
@@ -121,7 +138,7 @@ func (s *KeeperRest) Create(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdKeeper, err := s.storage.Create(ctx, kp)
|
||||
createdKeeper, err := s.storage.Create(ctx, kp, "todo-user")
|
||||
if err != nil {
|
||||
var kErr xkube.ErrorLister
|
||||
if errors.As(err, &kErr) {
|
||||
@@ -172,7 +189,7 @@ func (s *KeeperRest) Update(
|
||||
newKeeper.Annotations = xkube.CleanAnnotations(newKeeper.Annotations)
|
||||
|
||||
// Current implementation replaces everything passed in the spec, so it is not a PATCH. Do we want/need to support that?
|
||||
updatedKeeper, err := s.storage.Update(ctx, newKeeper)
|
||||
updatedKeeper, err := s.storage.Update(ctx, newKeeper, "todo-user")
|
||||
if err != nil {
|
||||
var kErr xkube.ErrorLister
|
||||
if errors.As(err, &kErr) {
|
||||
@@ -193,7 +210,11 @@ func (s *KeeperRest) Delete(ctx context.Context, name string, deleteValidation r
|
||||
return nil, false, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
if err := s.storage.Delete(ctx, xkube.Namespace(namespace), name); err != nil {
|
||||
err := s.storage.Delete(ctx, xkube.Namespace(namespace), name)
|
||||
if err != nil {
|
||||
if errors.Is(err, contracts.ErrKeeperNotFound) {
|
||||
return nil, false, s.resource.NewNotFound(name)
|
||||
}
|
||||
return nil, false, fmt.Errorf("failed to delete keeper: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@ import (
|
||||
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"k8s.io/apiserver/pkg/admission"
|
||||
@@ -79,12 +81,35 @@ func (s *SecureValueRest) List(ctx context.Context, options *internalversion.Lis
|
||||
return nil, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
secureValueList, err := s.storage.List(ctx, xkube.Namespace(namespace), options)
|
||||
secureValueList, err := s.storage.List(ctx, xkube.Namespace(namespace))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list secure values: %w", err)
|
||||
}
|
||||
|
||||
return secureValueList, nil
|
||||
labelSelector := options.LabelSelector
|
||||
|
||||
if labelSelector == nil {
|
||||
labelSelector = labels.Everything()
|
||||
}
|
||||
|
||||
fieldSelector := options.FieldSelector
|
||||
if fieldSelector == nil {
|
||||
fieldSelector = fields.Everything()
|
||||
}
|
||||
|
||||
allowedSecureValues := make([]secretv0alpha1.SecureValue, 0, len(secureValueList.Items))
|
||||
|
||||
for _, secureValue := range secureValueList.Items {
|
||||
// Filter by label
|
||||
if labelSelector.Matches(labels.Set(secureValue.Labels)) {
|
||||
// Filter by status.phase
|
||||
if fieldSelector.Matches(fields.Set{"status.phase": string(secureValue.Status.Phase)}) {
|
||||
allowedSecureValues = append(allowedSecureValues, secureValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &secretv0alpha1.SecureValueList{Items: allowedSecureValues}, nil
|
||||
}
|
||||
|
||||
// Get calls the inner `store` (persistence) and returns a `securevalue` by `name`. It will NOT return the decrypted `value`.
|
||||
@@ -94,7 +119,7 @@ func (s *SecureValueRest) Get(ctx context.Context, name string, options *metav1.
|
||||
return nil, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
sv, err := s.storage.Read(ctx, xkube.Namespace(namespace), name)
|
||||
sv, err := s.storage.Read(ctx, xkube.Namespace(namespace), name, contracts.ReadOpts{})
|
||||
if err != nil {
|
||||
if errors.Is(err, contracts.ErrSecureValueNotFound) {
|
||||
return nil, s.resource.NewNotFound(name)
|
||||
@@ -122,7 +147,7 @@ func (s *SecureValueRest) Create(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
createdSecureValue, err := s.storage.Create(ctx, sv)
|
||||
createdSecureValue, err := s.storage.Create(ctx, sv, "todo-user")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create secure value: %w", err)
|
||||
}
|
||||
@@ -166,7 +191,7 @@ func (s *SecureValueRest) Update(
|
||||
newSecureValue.Annotations = xkube.CleanAnnotations(newSecureValue.Annotations)
|
||||
|
||||
// Current implementation replaces everything passed in the spec, so it is not a PATCH. Do we want/need to support that?
|
||||
updatedSecureValue, err := s.storage.Update(ctx, newSecureValue)
|
||||
updatedSecureValue, err := s.storage.Update(ctx, newSecureValue, "todo-user")
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("failed to update secure value: %w", err)
|
||||
}
|
||||
@@ -176,17 +201,20 @@ func (s *SecureValueRest) Update(
|
||||
|
||||
// Delete calls the inner `store` (persistence) in order to delete the `securevalue`.
|
||||
// The second return parameter `bool` indicates whether the delete was instant or not. It always is for `securevalues`.
|
||||
func (s *SecureValueRest) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
|
||||
func (s *SecureValueRest) Delete(ctx context.Context, name string, _ rest.ValidateObjectFunc, _ *metav1.DeleteOptions) (runtime.Object, bool, error) {
|
||||
namespace, ok := request.NamespaceFrom(ctx)
|
||||
if !ok {
|
||||
return nil, false, fmt.Errorf("missing namespace")
|
||||
}
|
||||
|
||||
if err := s.storage.Delete(ctx, xkube.Namespace(namespace), name); err != nil {
|
||||
return nil, false, fmt.Errorf("delete secure value: %w", err)
|
||||
if errors.Is(err, contracts.ErrSecureValueNotFound) {
|
||||
return nil, false, s.resource.NewNotFound(name)
|
||||
}
|
||||
return nil, false, fmt.Errorf("deleting secure value: %+w", err)
|
||||
}
|
||||
|
||||
return nil, true, nil
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// ValidateSecureValue does basic spec validation of a securevalue.
|
||||
|
||||
@@ -1,45 +1,32 @@
|
||||
package secretkeeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
secretv0alpha1 "github.com/grafana/grafana/pkg/apis/secret/v0alpha1"
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/secretkeeper/sqlkeeper"
|
||||
)
|
||||
|
||||
// Service is the interface for secret keeper services.
|
||||
// This exists because OSS and Enterprise have different amounts of keepers available.
|
||||
type Service interface {
|
||||
GetKeepers() (map[contracts.KeeperType]contracts.Keeper, error)
|
||||
}
|
||||
|
||||
// OSSKeeperService is the OSS implementation of the Service interface.
|
||||
type OSSKeeperService struct {
|
||||
tracer tracing.Tracer
|
||||
encryptionManager contracts.EncryptionManager
|
||||
store contracts.EncryptedValueStorage
|
||||
systemKeeper *sqlkeeper.SQLKeeper
|
||||
}
|
||||
|
||||
var _ contracts.KeeperService = (*OSSKeeperService)(nil)
|
||||
|
||||
func ProvideService(
|
||||
tracer tracing.Tracer,
|
||||
store contracts.EncryptedValueStorage,
|
||||
encryptionManager contracts.EncryptionManager,
|
||||
) (OSSKeeperService, error) {
|
||||
return OSSKeeperService{
|
||||
tracer: tracer,
|
||||
encryptionManager: encryptionManager,
|
||||
store: store,
|
||||
) (*OSSKeeperService, error) {
|
||||
return &OSSKeeperService{
|
||||
// TODO: rename to system keeper or something like that
|
||||
systemKeeper: sqlkeeper.NewSQLKeeper(tracer, encryptionManager, store),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (ks OSSKeeperService) GetKeepers() (map[contracts.KeeperType]contracts.Keeper, error) {
|
||||
sqlKeeper, err := sqlkeeper.NewSQLKeeper(ks.tracer, ks.encryptionManager, ks.store)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create sql keeper: %w", err)
|
||||
}
|
||||
|
||||
return map[contracts.KeeperType]contracts.Keeper{
|
||||
contracts.SQLKeeperType: sqlKeeper,
|
||||
}, nil
|
||||
// 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) {
|
||||
return k.systemKeeper, nil
|
||||
}
|
||||
|
||||
@@ -7,27 +7,30 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/tracing"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/contracts"
|
||||
"github.com/grafana/grafana/pkg/registry/apis/secret/secretkeeper/sqlkeeper"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tests/testsuite"
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
testsuite.Run(m)
|
||||
}
|
||||
|
||||
func Test_OSSKeeperService_GetKeepers(t *testing.T) {
|
||||
cfg := setting.NewCfg()
|
||||
keeperService, err := setupTestService(t, cfg)
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Run("GetKeepers should return a map with a sql keeper", func(t *testing.T) {
|
||||
keeperMap, err := keeperService.GetKeepers()
|
||||
t.Run("KeeperForConfig should return the system keeper", func(t *testing.T) {
|
||||
keeper, err := keeperService.KeeperForConfig(nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotNil(t, keeperMap)
|
||||
assert.Equal(t, 1, len(keeperMap))
|
||||
assert.IsType(t, &sqlkeeper.SQLKeeper{}, keeperMap[contracts.SQLKeeperType])
|
||||
assert.NotNil(t, keeper)
|
||||
assert.IsType(t, &sqlkeeper.SQLKeeper{}, keeper)
|
||||
})
|
||||
}
|
||||
|
||||
func setupTestService(t *testing.T, cfg *setting.Cfg) (OSSKeeperService, error) {
|
||||
func setupTestService(t *testing.T, cfg *setting.Cfg) (*OSSKeeperService, error) {
|
||||
// Initialize the keeper service
|
||||
keeperService, err := ProvideService(tracing.InitializeTracerForTest(), nil, nil)
|
||||
|
||||
|
||||
@@ -21,12 +21,12 @@ func NewSQLKeeper(
|
||||
tracer tracing.Tracer,
|
||||
encryptionManager contracts.EncryptionManager,
|
||||
store contracts.EncryptedValueStorage,
|
||||
) (*SQLKeeper, error) {
|
||||
) *SQLKeeper {
|
||||
return &SQLKeeper{
|
||||
tracer: tracer,
|
||||
encryptionManager: encryptionManager,
|
||||
store: store,
|
||||
}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (s *SQLKeeper) Store(ctx context.Context, cfg secretv0alpha1.KeeperConfig, namespace string, exposedValueOrRef string) (contracts.ExternalID, error) {
|
||||
|
||||
@@ -143,9 +143,9 @@ func setupTestService(t *testing.T, cfg *setting.Cfg) (*SQLKeeper, error) {
|
||||
encValueStore := newInMemoryEncryptedValueStorage()
|
||||
|
||||
// Initialize the SQLKeeper
|
||||
sqlKeeper, err := NewSQLKeeper(tracing.InitializeTracerForTest(), encMgr, encValueStore)
|
||||
sqlKeeper := NewSQLKeeper(tracing.InitializeTracerForTest(), encMgr, encValueStore)
|
||||
|
||||
return sqlKeeper, err
|
||||
return sqlKeeper, nil
|
||||
}
|
||||
|
||||
// While we don't have the real implementation, use an in-memory one
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
"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"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
)
|
||||
|
||||
func ProvideKeeperMetadataStorage(db db.DB, features featuremgmt.FeatureToggles, accessClient claims.AccessClient) (contracts.KeeperMetadataStorage, error) {
|
||||
@@ -27,15 +26,15 @@ type keeperMetadataStorage struct {
|
||||
accessClient claims.AccessClient
|
||||
}
|
||||
|
||||
func (s *keeperMetadataStorage) Create(ctx context.Context, keeper *secretv0alpha1.Keeper) (*secretv0alpha1.Keeper, error) {
|
||||
func (s *keeperMetadataStorage) Create(ctx context.Context, keeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *keeperMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.Keeper, error) {
|
||||
func (s *keeperMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv0alpha1.Keeper, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *keeperMetadataStorage) Update(ctx context.Context, newKeeper *secretv0alpha1.Keeper) (*secretv0alpha1.Keeper, error) {
|
||||
func (s *keeperMetadataStorage) Update(ctx context.Context, newKeeper *secretv0alpha1.Keeper, actorUID string) (*secretv0alpha1.Keeper, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -43,6 +42,10 @@ func (s *keeperMetadataStorage) Delete(ctx context.Context, namespace xkube.Name
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namespace, options *internalversion.ListOptions) (*secretv0alpha1.KeeperList, error) {
|
||||
func (s *keeperMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) ([]secretv0alpha1.Keeper, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *keeperMetadataStorage) GetKeeperConfig(ctx context.Context, namespace string, name *string, opts contracts.ReadOpts) (secretv0alpha1.KeeperConfig, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"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"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/internalversion"
|
||||
)
|
||||
|
||||
func ProvideSecureValueMetadataStorage(db db.DB, features featuremgmt.FeatureToggles, accessClient claims.AccessClient) (contracts.SecureValueMetadataStorage, error) {
|
||||
@@ -28,15 +27,15 @@ type secureValueMetadataStorage struct {
|
||||
accessClient claims.AccessClient
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) Create(ctx context.Context, sv *secretv0alpha1.SecureValue) (*secretv0alpha1.SecureValue, error) {
|
||||
func (s *secureValueMetadataStorage) Create(ctx context.Context, sv *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string) (*secretv0alpha1.SecureValue, error) {
|
||||
func (s *secureValueMetadataStorage) Read(ctx context.Context, namespace xkube.Namespace, name string, opts contracts.ReadOpts) (*secretv0alpha1.SecureValue, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) Update(ctx context.Context, newSecureValue *secretv0alpha1.SecureValue) (*secretv0alpha1.SecureValue, error) {
|
||||
func (s *secureValueMetadataStorage) Update(ctx context.Context, newSecureValue *secretv0alpha1.SecureValue, actorUID string) (*secretv0alpha1.SecureValue, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -44,6 +43,18 @@ func (s *secureValueMetadataStorage) Delete(ctx context.Context, namespace xkube
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.Namespace, options *internalversion.ListOptions) (*secretv0alpha1.SecureValueList, error) {
|
||||
func (s *secureValueMetadataStorage) List(ctx context.Context, namespace xkube.Namespace) (*secretv0alpha1.SecureValueList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) SetStatus(ctx context.Context, namespace xkube.Namespace, name string, status secretv0alpha1.SecureValueStatus) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) SetExternalID(ctx context.Context, namespace xkube.Namespace, name string, externalID contracts.ExternalID) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *secureValueMetadataStorage) ReadForDecrypt(ctx context.Context, namespace xkube.Namespace, name string) (*contracts.DecryptSecureValue, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user