Skip to content

Commit

Permalink
Create admin mode on Terraform Workflows (#724)
Browse files Browse the repository at this point in the history
Modifications within admin mode help for exploring more details around
generated plans. More specifically:
1. Supports clone, init, plan steps as normal
2. Skips validate/apply steps
3. Skips automated cleanup
  • Loading branch information
samrabelachew authored Jan 28, 2024
1 parent 663b806 commit 89ea322
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 0 deletions.
1 change: 1 addition & 0 deletions server/neptune/workflows/activities/terraform/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,5 @@ type WorkflowMode int
const (
Deploy WorkflowMode = iota
PR
Admin
)
4 changes: 4 additions & 0 deletions server/neptune/workflows/internal/terraform/root_fetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ func (r *RootFetcher) Fetch(ctx workflow.Context) (*terraform.LocalRoot, func(wo
return nil, func(_ workflow.Context) error { return nil }, err
}

if r.Request.WorkflowMode == terraform.Admin {
return fetchRootResponse.LocalRoot, func(c workflow.Context) error { return nil }, nil
}

return fetchRootResponse.LocalRoot, func(c workflow.Context) error {
var cleanupResponse activities.CleanupResponse
err = workflow.ExecuteActivity(c, r.Ta.Cleanup, activities.CleanupRequest{ //nolint:gosimple // unnecessary to add a method to convert reponses
Expand Down
4 changes: 4 additions & 0 deletions server/neptune/workflows/internal/terraform/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,10 @@ func (r *Runner) run(ctx workflow.Context) (Response, error) {
return Response{}, r.toExternalError(err, "running plan job")
}

if r.Request.WorkflowMode == terraform.Admin {
return Response{}, nil
}

if r.Request.WorkflowMode == terraform.PR {
validationResults, err := r.Validate(ctx, root, response.ServerURL, planResponse.PlanJSONFile)
if err != nil {
Expand Down
86 changes: 86 additions & 0 deletions server/neptune/workflows/internal/terraform/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,10 @@ func testTerraformWorkflow(ctx workflow.Context, req request) (*response, error)
WorkflowMode: req.WorkflowMode,
}

if req.WorkflowMode == terraformModel.Admin {
tAct = nil
}

subject := &terraform.Runner{
ReviewGate: &gate.Review{
Timeout: 30 * time.Second,
Expand Down Expand Up @@ -615,6 +619,88 @@ func TestSuccess_PRMode(t *testing.T) {
}, resp.States)
}

func TestSuccess_AdminMode(t *testing.T) {
var suite testsuite.WorkflowTestSuite
env := suite.NewTestWorkflowEnvironment()
ga := &githubActivities{}
ta := &terraformActivities{}
env.RegisterActivity(ga)
env.RegisterActivity(ta)

outputURL, err := url.Parse("www.test.com/jobs/1235")
assert.NoError(t, err)

// set activity expectations
env.OnActivity(ga.GithubFetchRoot, mock.MatchedBy(func(ctx context.Context) bool {
info := activity.GetInfo(ctx)

assert.Equal(t, "taskqueue", info.TaskQueue)
assert.Equal(t, 1*time.Minute, info.HeartbeatTimeout)

return true
}), activities.FetchRootRequest{
Repo: testGithubRepo,
Root: testLocalRoot.Root,
DeploymentID: testDeploymentID,
}).Return(activities.FetchRootResponse{
LocalRoot: testLocalRoot,
DeployDirectory: DeployDir,
}, nil)

// execute workflow
env.ExecuteWorkflow(testTerraformWorkflow, request{
WorkflowMode: terraformModel.Admin,
})
assert.True(t, env.IsWorkflowCompleted())

var resp response
err = env.GetWorkflowResult(&resp)
assert.NoError(t, err)

// assert results are expected
env.AssertExpectations(t)
assert.Equal(t, []state.Workflow{
{
Plan: &state.Job{
Status: state.WaitingJobStatus,
Output: &state.JobOutput{
URL: outputURL,
},
},
},
{
Plan: &state.Job{
Status: state.InProgressJobStatus,
Output: &state.JobOutput{
URL: outputURL,
},
},
},
{
Plan: &state.Job{
Status: state.SuccessJobStatus,
Output: &state.JobOutput{
URL: outputURL,
PlanSummary: planSummary,
},
},
},
{
Plan: &state.Job{
Status: state.SuccessJobStatus,
Output: &state.JobOutput{
URL: outputURL,
PlanSummary: planSummary,
},
},
Result: state.WorkflowResult{
Reason: state.SuccessfulCompletionReason,
Status: state.CompleteWorkflowStatus,
},
},
}, resp.States)
}

func TestSuccess_PRMode_FailedPolicy(t *testing.T) {
var suite testsuite.WorkflowTestSuite
env := suite.NewTestWorkflowEnvironment()
Expand Down

0 comments on commit 89ea322

Please sign in to comment.