diff --git a/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go b/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go index f45367aee19..387e358aadf 100644 --- a/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go +++ b/chaoscenter/graphql/server/graph/chaos_experiment.resolvers.go @@ -95,7 +95,7 @@ func (r *mutationResolver) SaveChaosExperiment(ctx context.Context, request mode return "", err } - uiResponse, err = r.chaosExperimentHandler.SaveChaosExperiment(ctx, request, projectID, username) + uiResponse, err = r.chaosExperimentHandler.SaveChaosExperiment(ctx, request, projectID, data_store.Store, username) if err != nil { logrus.WithFields(logFields).Error(err) return "", err diff --git a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/fuzz_tests/handler_fuzz_test.go b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/fuzz_tests/handler_fuzz_test.go index 757959853f0..4dc1a80604d 100644 --- a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/fuzz_tests/handler_fuzz_test.go +++ b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/fuzz_tests/handler_fuzz_test.go @@ -91,7 +91,7 @@ func FuzzSaveChaosExperiment(f *testing.F) { mockServices.ChaosExperimentService.On("ProcessExperimentUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, false, mock.Anything, mock.Anything).Return(nil).Once() mockServices.GitOpsService.On("UpsertExperimentToGit", ctx, mock.Anything, mock.Anything).Return(nil).Once() - res, err := mockServices.ChaosExperimentHandler.SaveChaosExperiment(ctx, targetStruct.request, targetStruct.projectID, "") + res, err := mockServices.ChaosExperimentHandler.SaveChaosExperiment(ctx, targetStruct.request, targetStruct.projectID, nil, "") if err != nil { t.Errorf("ChaosExperimentHandler.SaveChaosExperiment() error = %v", err) return diff --git a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go index 29fa70af51d..294671955bb 100644 --- a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go +++ b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler.go @@ -76,7 +76,7 @@ func NewChaosExperimentHandler( } } -func (c *ChaosExperimentHandler) SaveChaosExperiment(ctx context.Context, request model.SaveChaosExperimentRequest, projectID string, username string) (string, error) { +func (c *ChaosExperimentHandler) SaveChaosExperiment(ctx context.Context, request model.SaveChaosExperimentRequest, projectID string, r *store.StateData, username string) (string, error) { var revID = uuid.New().String() @@ -127,11 +127,26 @@ func (c *ChaosExperimentHandler) SaveChaosExperiment(ctx context.Context, reques return "", err } - err = c.chaosExperimentService.ProcessExperimentUpdate(newRequest, username, wfType, revID, false, projectID, nil) + err = c.chaosExperimentService.ProcessExperimentUpdate(newRequest, username, wfType, revID, false, projectID, r) if err != nil { return "", err } + // For CronWorkflow experiments, force delete the existing CR and recreate it so + // the Argo CronWorkflow controller picks up all manifest changes (schedule, spec, etc.). + if r != nil && *wfType == dbChaosExperiment.CronExperiment { + // Delete using the old manifest so the correct CR name is targeted. + if len(wfDetails.Revision) > 0 { + oldManifest := wfDetails.Revision[len(wfDetails.Revision)-1].ExperimentManifest + chaos_infrastructure.SendExperimentToSubscriber(projectID, &model.ChaosExperimentRequest{ + ExperimentID: &wfDetails.ExperimentID, + ExperimentManifest: oldManifest, + InfraID: wfDetails.InfraID, + }, &username, nil, "delete", r) + } + chaos_infrastructure.SendExperimentToSubscriber(projectID, newRequest, &username, nil, "create", r) + } + return fmt.Sprintf("experiment updated successfully with ID %s", wfDetails.ExperimentID), nil } err = c.validateDuplicateExperimentName(ctx, projectID, request.Name) @@ -149,7 +164,7 @@ func (c *ChaosExperimentHandler) SaveChaosExperiment(ctx context.Context, reques return "", err } - err = c.chaosExperimentService.ProcessExperimentCreation(ctx, newRequest, username, projectID, wfType, revID, nil) + err = c.chaosExperimentService.ProcessExperimentCreation(ctx, newRequest, username, projectID, wfType, revID, r) if err != nil { return "", err } diff --git a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler_test.go b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler_test.go index 4341bf111c2..d18bd4ababf 100644 --- a/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler_test.go +++ b/chaoscenter/graphql/server/pkg/chaos_experiment/handler/handler_test.go @@ -200,13 +200,44 @@ func TestChaosExperimentHandler_SaveChaosExperiment(t *testing.T) { mockServices.GitOpsService.On("UpsertExperimentToGit", ctx, mock.Anything, request2).Return(nil).Once() }, }, + { + name: "Save CronWorkflow experiment triggers delete and recreate on subscriber", + args: args{ + projectID: projectId, + request: model.SaveChaosExperimentRequest{ + ID: experimentId, + Type: &model.AllExperimentType[1], + InfraID: infraId, + }, + request2: &model.ChaosExperimentRequest{ + ExperimentID: &experimentId, + InfraID: infraId, + ExperimentType: &model.AllExperimentType[1], + }, + }, + given: func(request2 *model.ChaosExperimentRequest, mockServices *MockServices) { + cronType := dbChaosExperiment.CronExperiment + ctx = context.WithValue(ctx, authorization.AuthKey, username) + findResult := []interface{}{bson.D{ + {Key: "experiment_id", Value: experimentId}, + }} + singleResult := mongo.NewSingleResultFromDocument(findResult[0], nil, nil) + mockServices.MongodbOperator.On("Get", mock.Anything, mongodb.ChaosExperimentCollection, mock.Anything).Return(singleResult, nil).Once() + + mockServices.ChaosExperimentService.On("ProcessExperiment", mock.Anything, request2, mock.Anything, mock.Anything).Return(request2, &cronType, nil).Once() + + mockServices.ChaosExperimentService.On("ProcessExperimentUpdate", request2, mock.Anything, mock.Anything, mock.Anything, false, mock.Anything, mock.Anything).Return(nil).Once() + mockServices.GitOpsService.On("UpsertExperimentToGit", ctx, mock.Anything, request2).Return(nil).Once() + }, + wantErr: false, + }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { mockServices := NewMockServices() tc.given(tc.args.request2, mockServices) - _, err := mockServices.ChaosExperimentHandler.SaveChaosExperiment(ctx, tc.args.request, tc.args.projectID, "") + _, err := mockServices.ChaosExperimentHandler.SaveChaosExperiment(ctx, tc.args.request, tc.args.projectID, nil, "") if (err != nil) != tc.wantErr { t.Errorf("ChaosExperimentHandler.SaveChaosExperiment() error = %v, wantErr %v", err, tc.wantErr) return