ensure atomicity by adding secret management as a step to sql operations and rolling back if necessary

This commit is contained in:
Michael Mandrus committed 2022-06-08 13:03:44 -04:00
1 parent dc55242319
commit 1622a57f41
3 files changed
+51 -14

No files matched your search

+7
View File
@@ -104,6 +104,7 @@ type AddDataSourceCommand struct {
UserId int64 `json:"-"`
ReadOnly bool `json:"-"`
EncryptedSecureJsonData map[string][]byte `json:"-"`
UpdateSecretFn UpdateSecretFn `json:"-"`
Result *DataSource `json:"-"`
}
@@ -129,6 +130,7 @@ type UpdateDataSourceCommand struct {
Id int64 `json:"-"`
ReadOnly bool `json:"-"`
EncryptedSecureJsonData map[string][]byte `json:"-"`
UpdateSecretFn UpdateSecretFn `json:"-"`
Result *DataSource `json:"-"`
}
@@ -143,8 +145,13 @@ type DeleteDataSourceCommand struct {
OrgID int64
DeletedDatasourcesCount int64
UpdateSecretFn UpdateSecretFn
}
// Function for updating secrets along with datasources, to ensure atomicity
type UpdateSecretFn func() error
// ---------------------
// QUERIES
@@ -152,17 +152,16 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCo
return err
}
if err := s.SQLStore.AddDataSource(ctx, cmd); err != nil {
return err
}
secret, err := json.Marshal(cmd.SecureJsonData)
if err != nil {
return err
}
err = s.SecretsStore.Set(ctx, cmd.OrgId, cmd.Name, secretType, string(secret))
if err != nil {
cmd.UpdateSecretFn = func() error {
return s.SecretsStore.Set(ctx, cmd.OrgId, cmd.Name, secretType, string(secret))
}
if err := s.SQLStore.AddDataSource(ctx, cmd); err != nil {
return err
}
@@ -188,11 +187,15 @@ func (s *Service) AddDataSource(ctx context.Context, cmd *models.AddDataSourceCo
}
func (s *Service) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSourceCommand) error {
cmd.UpdateSecretFn = func() error {
return s.SecretsStore.Del(ctx, cmd.OrgID, cmd.Name, secretType)
}
err := s.SQLStore.DeleteDataSource(ctx, cmd)
if err != nil {
return err
}
return s.SecretsStore.Del(ctx, cmd.OrgID, cmd.Name, secretType)
return nil
}
func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error {
@@ -212,11 +215,19 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSo
return err
}
err = s.SQLStore.UpdateDataSource(ctx, cmd)
secret, err := json.Marshal(cmd.SecureJsonData)
if err != nil {
return err
}
cmd.UpdateSecretFn = func() error {
return s.SecretsStore.Set(ctx, cmd.OrgId, cmd.Name, secretType, string(secret))
}
if err = s.SQLStore.UpdateDataSource(ctx, cmd); err != nil {
return err
}
if query.Result.Name != cmd.Name {
err = s.SecretsStore.Rename(ctx, cmd.OrgId, query.Result.Name, secretType, cmd.Name)
if err != nil {
@@ -224,12 +235,7 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSo
}
}
secret, err := json.Marshal(cmd.SecureJsonData)
if err != nil {
return err
}
return s.SecretsStore.Set(ctx, cmd.OrgId, cmd.Name, secretType, string(secret))
return nil
}
func (s *Service) GetDefaultDataSource(ctx context.Context, query *models.GetDefaultDataSourceQuery) error {
+24
View File
@@ -116,6 +116,14 @@ func (ss *SQLStore) DeleteDataSource(ctx context.Context, cmd *models.DeleteData
}
}
if cmd.UpdateSecretFn != nil {
if err := cmd.UpdateSecretFn(); err != nil {
sess.Rollback()
sqlog.Error("Failed to update datasource secrets -- rolling back update", "UID", cmd.UID, "name", cmd.Name, "orgId", cmd.OrgID)
return err
}
}
// Publish data source deletion event
sess.publishAfterCommit(&events.DataSourceDeleted{
Timestamp: time.Now(),
@@ -181,6 +189,14 @@ func (ss *SQLStore) AddDataSource(ctx context.Context, cmd *models.AddDataSource
return err
}
if cmd.UpdateSecretFn != nil {
if err := cmd.UpdateSecretFn(); err != nil {
sess.Rollback()
sqlog.Error("Failed to update datasource secrets -- rolling back update", "name", cmd.Name, "type", cmd.Type, "orgId", cmd.OrgId)
return err
}
}
cmd.Result = ds
sess.publishAfterCommit(&events.DataSourceCreated{
@@ -263,6 +279,14 @@ func (ss *SQLStore) UpdateDataSource(ctx context.Context, cmd *models.UpdateData
err = updateIsDefaultFlag(ds, sess)
if cmd.UpdateSecretFn != nil {
if err := cmd.UpdateSecretFn(); err != nil {
sess.Rollback()
sqlog.Error("Failed to update datasource secrets -- rolling back update", "UID", cmd.Uid, "name", cmd.Name, "type", cmd.Type, "orgId", cmd.OrgId)
return err
}
}
cmd.Result = ds
return err
})