From b61e0bcc9a5e6acd8e26e3763a8e69765628889f Mon Sep 17 00:00:00 2001 From: rollwagen Date: Mon, 13 Feb 2023 08:41:52 +0100 Subject: [PATCH] Cleanup AWS resources in case of warm up error (#315) * Cleanup AWS resources in case of warm up error * Add test to validate resource cleanup after warmup error Extend the mock tests with a test case to verify that 'TerraformDestroy' is called in case of an error during 'TerraformInitAndApply'. --- v2/pkg/stratus/runner/runner.go | 2 ++ v2/pkg/stratus/runner/runner_test.go | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/v2/pkg/stratus/runner/runner.go b/v2/pkg/stratus/runner/runner.go index d1a4afe9..ecaaa2b2 100644 --- a/v2/pkg/stratus/runner/runner.go +++ b/v2/pkg/stratus/runner/runner.go @@ -84,6 +84,8 @@ func (m *Runner) WarmUp() (map[string]string, error) { log.Println("Warming up " + m.Technique.ID) outputs, err := m.TerraformManager.TerraformInitAndApply(m.TerraformDir) if err != nil { + log.Println("Error during warm up. Cleaning up technique prerequisites with terraform destroy") + _ = m.TerraformManager.TerraformDestroy(m.TerraformDir) return nil, errors.New("unable to run terraform apply on prerequisite: " + errorMessageFromTerraformError(err)) } diff --git a/v2/pkg/stratus/runner/runner_test.go b/v2/pkg/stratus/runner/runner_test.go index 2adc8d23..ee4ba0fc 100644 --- a/v2/pkg/stratus/runner/runner_test.go +++ b/v2/pkg/stratus/runner/runner_test.go @@ -19,6 +19,7 @@ func TestRunnerWarmUp(t *testing.T) { InitialTechniqueState stratus.AttackTechniqueState TerraformOutputs map[string]string PersistedOutputs map[string]string + Error error // results CheckExpectations func(t *testing.T, terraform *mocks.TerraformManager, state *statemocks.StateManager, outputs map[string]string, err error) } @@ -91,6 +92,18 @@ func TestRunnerWarmUp(t *testing.T) { assert.Equal(t, "old", outputs["myoutput"]) }, }, + { + Name: "Warming up a COLD technique with error", + Technique: &stratus.AttackTechnique{ID: "foo", PrerequisitesTerraformCode: []byte("bar")}, + InitialTechniqueState: stratus.AttackTechniqueStatusCold, + Error: errors.New("error during init and apply"), + CheckExpectations: func(t *testing.T, terraform *mocks.TerraformManager, state *statemocks.StateManager, outputs map[string]string, err error) { + terraform.AssertCalled(t, "TerraformInitAndApply", "/root/foo") + terraform.AssertCalled(t, "TerraformDestroy", "/root/foo") + assert.NotNil(t, err) + assert.Len(t, outputs, 0) + }, + }, } for i := range scenario { @@ -101,7 +114,8 @@ func TestRunnerWarmUp(t *testing.T) { state.On("ExtractTechnique").Return(nil) state.On("GetTechniqueState", mock.Anything).Return(scenario[i].InitialTechniqueState, nil) state.On("GetTerraformOutputs").Return(scenario[i].PersistedOutputs, nil) - terraform.On("TerraformInitAndApply", mock.Anything).Return(scenario[i].TerraformOutputs, nil) + terraform.On("TerraformInitAndApply", mock.Anything).Return(scenario[i].TerraformOutputs, scenario[i].Error) + terraform.On("TerraformDestroy", mock.Anything).Return(nil) state.On("WriteTerraformOutputs", mock.Anything).Return(nil) state.On("SetTechniqueState", mock.Anything).Return(nil)