Plugins: Add plugin settings DTO (#46283)
* add clearer service layer * re-order frontend settings for clarity * fix fetch fail * fix API response * fix mockstore * in -> where
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
package pluginsettings
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type DTO struct {
|
||||
ID int64
|
||||
OrgID int64
|
||||
PluginID string
|
||||
PluginVersion string
|
||||
JSONData map[string]interface{}
|
||||
SecureJSONData map[string][]byte
|
||||
Enabled bool
|
||||
Pinned bool
|
||||
Updated time.Time
|
||||
}
|
||||
|
||||
type UpdateArgs struct {
|
||||
Enabled bool
|
||||
Pinned bool
|
||||
JSONData map[string]interface{}
|
||||
SecureJSONData map[string]string
|
||||
PluginVersion string
|
||||
PluginID string
|
||||
OrgID int64
|
||||
EncryptedSecureJSONData map[string][]byte
|
||||
}
|
||||
|
||||
type UpdatePluginVersionArgs struct {
|
||||
PluginVersion string
|
||||
PluginID string
|
||||
OrgID int64
|
||||
}
|
||||
|
||||
type GetArgs struct {
|
||||
OrgID int64
|
||||
}
|
||||
|
||||
type GetByPluginIDArgs struct {
|
||||
PluginID string
|
||||
OrgID int64
|
||||
}
|
||||
@@ -2,20 +2,18 @@ package pluginsettings
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
// GetPluginSettings returns all Plugin Settings for the provided Org
|
||||
GetPluginSettings(ctx context.Context, orgID int64) ([]*models.PluginSettingInfoDTO, error)
|
||||
// GetPluginSettingById returns a Plugin Settings by Plugin ID
|
||||
GetPluginSettingById(ctx context.Context, query *models.GetPluginSettingByIdQuery) error
|
||||
GetPluginSettings(ctx context.Context, args *GetArgs) ([]*DTO, error)
|
||||
// GetPluginSettingByPluginID returns a Plugin Settings by Plugin ID
|
||||
GetPluginSettingByPluginID(ctx context.Context, args *GetByPluginIDArgs) (*DTO, error)
|
||||
// UpdatePluginSetting updates a Plugin Setting
|
||||
UpdatePluginSetting(ctx context.Context, cmd *models.UpdatePluginSettingCmd) error
|
||||
// UpdatePluginSettingVersion updates a Plugin Setting's plugin version
|
||||
UpdatePluginSettingVersion(ctx context.Context, cmd *models.UpdatePluginSettingVersionCmd) error
|
||||
UpdatePluginSetting(ctx context.Context, args *UpdateArgs) error
|
||||
// UpdatePluginSettingPluginVersion updates a Plugin Setting's plugin version
|
||||
UpdatePluginSettingPluginVersion(ctx context.Context, args *UpdatePluginVersionArgs) error
|
||||
// DecryptedValues decrypts the encrypted secureJSONData of the provided plugin setting and
|
||||
// returns the decrypted values.
|
||||
DecryptedValues(ps *models.PluginSetting) map[string]string
|
||||
DecryptedValues(ps *DTO) map[string]string
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
)
|
||||
@@ -42,43 +43,95 @@ type secureJSONDecryptionCache struct {
|
||||
sync.Mutex
|
||||
}
|
||||
|
||||
func (s *Service) GetPluginSettings(ctx context.Context, orgID int64) ([]*models.PluginSettingInfoDTO, error) {
|
||||
return s.sqlStore.GetPluginSettings(ctx, orgID)
|
||||
func (s *Service) GetPluginSettings(ctx context.Context, args *pluginsettings.GetArgs) ([]*pluginsettings.DTO, error) {
|
||||
ps, err := s.sqlStore.GetPluginSettings(ctx, args.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var result []*pluginsettings.DTO
|
||||
for _, p := range ps {
|
||||
result = append(result, &pluginsettings.DTO{
|
||||
ID: p.Id,
|
||||
OrgID: p.OrgId,
|
||||
PluginID: p.PluginId,
|
||||
PluginVersion: p.PluginVersion,
|
||||
JSONData: p.JsonData,
|
||||
SecureJSONData: p.SecureJsonData,
|
||||
Enabled: p.Enabled,
|
||||
Pinned: p.Pinned,
|
||||
Updated: p.Updated,
|
||||
})
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetPluginSettingById(ctx context.Context, query *models.GetPluginSettingByIdQuery) error {
|
||||
return s.sqlStore.GetPluginSettingById(ctx, query)
|
||||
func (s *Service) GetPluginSettingByPluginID(ctx context.Context, args *pluginsettings.GetByPluginIDArgs) (*pluginsettings.DTO, error) {
|
||||
query := &models.GetPluginSettingByIdQuery{
|
||||
OrgId: args.OrgID,
|
||||
PluginId: args.PluginID,
|
||||
}
|
||||
|
||||
err := s.sqlStore.GetPluginSettingById(ctx, query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &pluginsettings.DTO{
|
||||
ID: query.Result.Id,
|
||||
OrgID: query.Result.OrgId,
|
||||
PluginID: query.Result.PluginId,
|
||||
PluginVersion: query.Result.PluginVersion,
|
||||
JSONData: query.Result.JsonData,
|
||||
SecureJSONData: query.Result.SecureJsonData,
|
||||
Enabled: query.Result.Enabled,
|
||||
Pinned: query.Result.Pinned,
|
||||
Updated: query.Result.Updated,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) UpdatePluginSetting(ctx context.Context, cmd *models.UpdatePluginSettingCmd) error {
|
||||
var err error
|
||||
cmd.EncryptedSecureJsonData, err = s.secretsService.EncryptJsonData(ctx, cmd.SecureJsonData, secrets.WithoutScope())
|
||||
func (s *Service) UpdatePluginSetting(ctx context.Context, args *pluginsettings.UpdateArgs) error {
|
||||
encryptedSecureJsonData, err := s.secretsService.EncryptJsonData(ctx, args.SecureJSONData, secrets.WithoutScope())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return s.sqlStore.UpdatePluginSetting(ctx, cmd)
|
||||
return s.sqlStore.UpdatePluginSetting(ctx, &models.UpdatePluginSettingCmd{
|
||||
Enabled: args.Enabled,
|
||||
Pinned: args.Pinned,
|
||||
JsonData: args.JSONData,
|
||||
SecureJsonData: args.SecureJSONData,
|
||||
PluginVersion: args.PluginVersion,
|
||||
PluginId: args.PluginID,
|
||||
OrgId: args.OrgID,
|
||||
EncryptedSecureJsonData: encryptedSecureJsonData,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Service) UpdatePluginSettingVersion(ctx context.Context, cmd *models.UpdatePluginSettingVersionCmd) error {
|
||||
return s.sqlStore.UpdatePluginSettingVersion(ctx, cmd)
|
||||
func (s *Service) UpdatePluginSettingPluginVersion(ctx context.Context, args *pluginsettings.UpdatePluginVersionArgs) error {
|
||||
return s.sqlStore.UpdatePluginSettingVersion(ctx, &models.UpdatePluginSettingVersionCmd{
|
||||
PluginVersion: args.PluginVersion,
|
||||
PluginId: args.PluginID,
|
||||
OrgId: args.OrgID,
|
||||
})
|
||||
}
|
||||
|
||||
func (s *Service) DecryptedValues(ps *models.PluginSetting) map[string]string {
|
||||
func (s *Service) DecryptedValues(ps *pluginsettings.DTO) map[string]string {
|
||||
s.decryptionCache.Lock()
|
||||
defer s.decryptionCache.Unlock()
|
||||
|
||||
if item, present := s.decryptionCache.cache[ps.Id]; present && ps.Updated.Equal(item.updated) {
|
||||
if item, present := s.decryptionCache.cache[ps.ID]; present && ps.Updated.Equal(item.updated) {
|
||||
return item.json
|
||||
}
|
||||
|
||||
json, err := s.secretsService.DecryptJsonData(context.Background(), ps.SecureJsonData)
|
||||
json, err := s.secretsService.DecryptJsonData(context.Background(), ps.SecureJSONData)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to decrypt secure json data", "error", err)
|
||||
return map[string]string{}
|
||||
}
|
||||
|
||||
s.decryptionCache.cache[ps.Id] = cachedDecryptedJSON{
|
||||
s.decryptionCache.cache[ps.ID] = cachedDecryptedJSON{
|
||||
updated: ps.Updated,
|
||||
json: json,
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/pluginsettings"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/fakes"
|
||||
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||
@@ -27,10 +27,10 @@ func TestService_DecryptedValuesCache(t *testing.T) {
|
||||
}, secrets.WithoutScope())
|
||||
require.NoError(t, err)
|
||||
|
||||
ps := models.PluginSetting{
|
||||
Id: 1,
|
||||
JsonData: map[string]interface{}{},
|
||||
SecureJsonData: encryptedJsonData,
|
||||
ps := pluginsettings.DTO{
|
||||
ID: 1,
|
||||
JSONData: map[string]interface{}{},
|
||||
SecureJSONData: encryptedJsonData,
|
||||
}
|
||||
|
||||
// Populate cache
|
||||
@@ -45,7 +45,7 @@ func TestService_DecryptedValuesCache(t *testing.T) {
|
||||
}, secrets.WithoutScope())
|
||||
require.NoError(t, err)
|
||||
|
||||
ps.SecureJsonData = encryptedJsonData
|
||||
ps.SecureJSONData = encryptedJsonData
|
||||
|
||||
password, ok = psService.DecryptedValues(&ps)["password"]
|
||||
require.Equal(t, "password", password)
|
||||
@@ -65,10 +65,10 @@ func TestService_DecryptedValuesCache(t *testing.T) {
|
||||
}, secrets.WithoutScope())
|
||||
require.NoError(t, err)
|
||||
|
||||
ps := models.PluginSetting{
|
||||
Id: 1,
|
||||
JsonData: map[string]interface{}{},
|
||||
SecureJsonData: encryptedJsonData,
|
||||
ps := pluginsettings.DTO{
|
||||
ID: 1,
|
||||
JSONData: map[string]interface{}{},
|
||||
SecureJSONData: encryptedJsonData,
|
||||
}
|
||||
|
||||
// Populate cache
|
||||
@@ -83,7 +83,7 @@ func TestService_DecryptedValuesCache(t *testing.T) {
|
||||
}, secrets.WithoutScope())
|
||||
require.NoError(t, err)
|
||||
|
||||
ps.SecureJsonData = encryptedJsonData
|
||||
ps.SecureJSONData = encryptedJsonData
|
||||
ps.Updated = time.Now()
|
||||
|
||||
password, ok = psService.DecryptedValues(&ps)["password"]
|
||||
|
||||
Reference in New Issue
Block a user