mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Provisioning: Fix overwrite SecureJSONData on provisioning (#72395)
* Overwrite SecureJSONData on provisioning
This commit is contained in:
parent
a4a87f6228
commit
a912c970e3
@ -134,6 +134,7 @@ type UpdateDataSourceCommand struct {
|
|||||||
ReadOnly bool `json:"-"`
|
ReadOnly bool `json:"-"`
|
||||||
EncryptedSecureJsonData map[string][]byte `json:"-"`
|
EncryptedSecureJsonData map[string][]byte `json:"-"`
|
||||||
UpdateSecretFn UpdateSecretFn `json:"-"`
|
UpdateSecretFn UpdateSecretFn `json:"-"`
|
||||||
|
IgnoreOldSecureJsonData bool `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteDataSourceCommand will delete a DataSource based on OrgID as well as the UID (preferred), ID, or Name.
|
// DeleteDataSourceCommand will delete a DataSource based on OrgID as well as the UID (preferred), ID, or Name.
|
||||||
|
@ -644,9 +644,11 @@ func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *datasources.U
|
|||||||
cmd.SecureJsonData = make(map[string]string)
|
cmd.SecureJsonData = make(map[string]string)
|
||||||
}
|
}
|
||||||
|
|
||||||
for k, v := range decrypted {
|
if !cmd.IgnoreOldSecureJsonData {
|
||||||
if _, ok := cmd.SecureJsonData[k]; !ok {
|
for k, v := range decrypted {
|
||||||
cmd.SecureJsonData[k] = v
|
if _, ok := cmd.SecureJsonData[k]; !ok {
|
||||||
|
cmd.SecureJsonData[k] = v
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +187,96 @@ func TestService_UpdateDataSource(t *testing.T) {
|
|||||||
_, err = dsService.UpdateDataSource(context.Background(), cmd)
|
_, err = dsService.UpdateDataSource(context.Background(), cmd)
|
||||||
require.ErrorIs(t, err, datasources.ErrDataSourceNameExists)
|
require.ErrorIs(t, err, datasources.ErrDataSourceNameExists)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("should merge cmd.SecureJsonData with db data", func(t *testing.T) {
|
||||||
|
sqlStore := db.InitTestDB(t)
|
||||||
|
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
|
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||||
|
quotaService := quotatest.New(false, nil)
|
||||||
|
mockPermission := acmock.NewMockedPermissionsService()
|
||||||
|
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||||
|
|
||||||
|
expectedDbKey := "db-secure-key"
|
||||||
|
expectedDbValue := "db-secure-value"
|
||||||
|
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Name: "test-datasource",
|
||||||
|
SecureJsonData: map[string]string{
|
||||||
|
expectedDbKey: expectedDbValue,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expectedOgKey := "cmd-secure-key"
|
||||||
|
expectedOgValue := "cmd-secure-value"
|
||||||
|
|
||||||
|
cmd := &datasources.UpdateDataSourceCommand{
|
||||||
|
ID: ds.ID,
|
||||||
|
OrgID: ds.OrgID,
|
||||||
|
Name: "test-datasource-updated",
|
||||||
|
SecureJsonData: map[string]string{
|
||||||
|
expectedOgKey: expectedOgValue,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
ds, err = dsService.UpdateDataSource(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
secret, err := dsService.DecryptedValues(context.Background(), ds)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, secret[expectedDbKey], expectedDbValue)
|
||||||
|
assert.Equal(t, secret[expectedOgKey], expectedOgValue)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("should preserve cmd.SecureJsonData when cmd.IgnoreOldSecureJsonData=true", func(t *testing.T) {
|
||||||
|
sqlStore := db.InitTestDB(t)
|
||||||
|
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
|
||||||
|
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
|
||||||
|
quotaService := quotatest.New(false, nil)
|
||||||
|
mockPermission := acmock.NewMockedPermissionsService()
|
||||||
|
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
|
||||||
|
|
||||||
|
notExpectedDbKey := "db-secure-key"
|
||||||
|
dbValue := "db-secure-value"
|
||||||
|
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
|
||||||
|
OrgID: 1,
|
||||||
|
Name: "test-datasource",
|
||||||
|
SecureJsonData: map[string]string{
|
||||||
|
notExpectedDbKey: dbValue,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expectedOgKey := "cmd-secure-key"
|
||||||
|
expectedOgValue := "cmd-secure-value"
|
||||||
|
|
||||||
|
cmd := &datasources.UpdateDataSourceCommand{
|
||||||
|
ID: ds.ID,
|
||||||
|
OrgID: ds.OrgID,
|
||||||
|
Name: "test-datasource-updated",
|
||||||
|
SecureJsonData: map[string]string{
|
||||||
|
expectedOgKey: expectedOgValue,
|
||||||
|
},
|
||||||
|
IgnoreOldSecureJsonData: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
ds, err = dsService.UpdateDataSource(context.Background(), cmd)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
secret, err := dsService.DecryptedValues(context.Background(), ds)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
assert.Equal(t, secret[expectedOgKey], expectedOgValue)
|
||||||
|
_, ok := secret[notExpectedDbKey]
|
||||||
|
assert.False(t, ok)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestService_NameScopeResolver(t *testing.T) {
|
func TestService_NameScopeResolver(t *testing.T) {
|
||||||
|
@ -242,21 +242,22 @@ func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *datasources.
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &datasources.UpdateDataSourceCommand{
|
return &datasources.UpdateDataSourceCommand{
|
||||||
ID: id,
|
ID: id,
|
||||||
UID: ds.UID,
|
UID: ds.UID,
|
||||||
OrgID: ds.OrgID,
|
OrgID: ds.OrgID,
|
||||||
Name: ds.Name,
|
Name: ds.Name,
|
||||||
Type: ds.Type,
|
Type: ds.Type,
|
||||||
Access: datasources.DsAccess(ds.Access),
|
Access: datasources.DsAccess(ds.Access),
|
||||||
URL: ds.URL,
|
URL: ds.URL,
|
||||||
User: ds.User,
|
User: ds.User,
|
||||||
Database: ds.Database,
|
Database: ds.Database,
|
||||||
BasicAuth: ds.BasicAuth,
|
BasicAuth: ds.BasicAuth,
|
||||||
BasicAuthUser: ds.BasicAuthUser,
|
BasicAuthUser: ds.BasicAuthUser,
|
||||||
WithCredentials: ds.WithCredentials,
|
WithCredentials: ds.WithCredentials,
|
||||||
IsDefault: ds.IsDefault,
|
IsDefault: ds.IsDefault,
|
||||||
JsonData: jsonData,
|
JsonData: jsonData,
|
||||||
SecureJsonData: ds.SecureJSONData,
|
SecureJsonData: ds.SecureJSONData,
|
||||||
ReadOnly: !ds.Editable,
|
ReadOnly: !ds.Editable,
|
||||||
|
IgnoreOldSecureJsonData: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user