Files
grafana/pkg/services/secrets/kvstore/kvstore.go
T
Guilherme Caulada 7924d3b3b5 Secrets: Move license check to secret store plugin (#53185)
* Move license check to secret store plugin

* Use shouldUseRemoteSecretsPlugin for migration

* Encapsulate plugin startup logic in sync.Once

* Remove global logger from startup functions

* Fix issues with wire and secrets plugin check

* Remove todo for plugin fatal error

* Rename fatalErr variable to be less confusing

* Fix merge conflicts

* Fix issue with grafana-cli wire and opentsdb

* Remove duplicated import on remote plugin

* Rename plugin check in favor of error return value

* Remove unnecessary import on grafana-cli wireexts_oss

* Remove unnecessary import on grafana wireexts_oss

* Reset sync.Once during test setup

* Remove unrelated opentsdb change on grafana-cli wire

* Readd opentsdb change on grafana-cli wire
2022-08-10 16:47:03 -03:00

127 lines
4.1 KiB
Go

package kvstore
import (
"context"
"time"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/backendplugin/secretsmanagerplugin"
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
)
const (
// Wildcard to query all organizations
AllOrganizations = -1
)
func ProvideService(
sqlStore sqlstore.Store,
secretsService secrets.Service,
pluginsManager plugins.SecretsPluginManager,
kvstore kvstore.KVStore,
features featuremgmt.FeatureToggles,
cfg *setting.Cfg,
) (SecretsKVStore, error) {
var logger = log.New("secrets.kvstore")
var store SecretsKVStore
store = &secretsKVStoreSQL{
sqlStore: sqlStore,
secretsService: secretsService,
log: logger,
decryptionCache: decryptionCache{
cache: make(map[int64]cachedDecrypted),
},
}
err := EvaluateRemoteSecretsPlugin(pluginsManager, cfg)
if err != nil {
logger.Debug(err.Error())
} else {
// Attempt to start the plugin
var secretsPlugin secretsmanagerplugin.SecretsManagerPlugin
secretsPlugin, err = startAndReturnPlugin(pluginsManager, context.Background())
namespacedKVStore := GetNamespacedKVStore(kvstore)
if err != nil || secretsPlugin == nil {
logger.Error("failed to start remote secrets management plugin", "msg", err.Error())
if isFatal, readErr := isPluginStartupErrorFatal(context.Background(), namespacedKVStore); isFatal || readErr != nil {
// plugin error was fatal or there was an error determining if the error was fatal
logger.Error("secrets management plugin is required to start -- exiting app")
if readErr != nil {
return nil, readErr
}
return nil, err
}
} else {
store = &secretsKVStorePlugin{
secretsPlugin: secretsPlugin,
secretsService: secretsService,
log: logger,
kvstore: namespacedKVStore,
backwardsCompatibilityDisabled: features.IsEnabled(featuremgmt.FlagDisableSecretsCompatibility),
}
}
}
if err != nil {
logger.Debug("secrets kvstore is using the default (SQL) implementation for secrets management")
}
return NewCachedKVStore(store, 5*time.Second, 5*time.Minute), nil
}
// SecretsKVStore is an interface for k/v store.
type SecretsKVStore interface {
Get(ctx context.Context, orgId int64, namespace string, typ string) (string, bool, error)
Set(ctx context.Context, orgId int64, namespace string, typ string, value string) error
Del(ctx context.Context, orgId int64, namespace string, typ string) error
Keys(ctx context.Context, orgId int64, namespace string, typ string) ([]Key, error)
Rename(ctx context.Context, orgId int64, namespace string, typ string, newNamespace string) error
}
// WithType returns a kvstore wrapper with fixed orgId and type.
func With(kv SecretsKVStore, orgId int64, namespace string, typ string) *FixedKVStore {
return &FixedKVStore{
kvStore: kv,
OrgId: orgId,
Namespace: namespace,
Type: typ,
}
}
// FixedKVStore is a SecretsKVStore wrapper with fixed orgId, namespace and type.
type FixedKVStore struct {
kvStore SecretsKVStore
OrgId int64
Namespace string
Type string
}
func (kv *FixedKVStore) Get(ctx context.Context) (string, bool, error) {
return kv.kvStore.Get(ctx, kv.OrgId, kv.Namespace, kv.Type)
}
func (kv *FixedKVStore) Set(ctx context.Context, value string) error {
return kv.kvStore.Set(ctx, kv.OrgId, kv.Namespace, kv.Type, value)
}
func (kv *FixedKVStore) Del(ctx context.Context) error {
return kv.kvStore.Del(ctx, kv.OrgId, kv.Namespace, kv.Type)
}
func (kv *FixedKVStore) Keys(ctx context.Context) ([]Key, error) {
return kv.kvStore.Keys(ctx, kv.OrgId, kv.Namespace, kv.Type)
}
func (kv *FixedKVStore) Rename(ctx context.Context, newNamespace string) error {
err := kv.kvStore.Rename(ctx, kv.OrgId, kv.Namespace, kv.Type, newNamespace)
if err != nil {
return err
}
kv.Namespace = newNamespace
return nil
}