Skip to content

Commit

Permalink
Atlantis e2e tests for policy checks step (#42)
Browse files Browse the repository at this point in the history
* Adding e2e tests for policy checks.

Added project lock for policy approval step.
Moved policy approval into a DefaultProjectCommandRunner

* Fixing these cursed tests

* Adding conftest0.21.0 binary check

* Deleting unused fixtures

* Remove print statement
  • Loading branch information
msarvar committed Feb 1, 2021
1 parent 1acf9bb commit 37fd2a7
Show file tree
Hide file tree
Showing 41 changed files with 548 additions and 401 deletions.
15 changes: 3 additions & 12 deletions server/events/approve_policies_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import (
func NewApprovePoliciesCommandRunner(
commitStatusUpdater CommitStatusUpdater,
prjCommandBuilder ProjectApprovePoliciesCommandBuilder,
prjCommandRunner ProjectPolicyCheckCommandRunner,
prjCommandRunner ProjectApprovePoliciesCommandRunner,
pullUpdater *PullUpdater,
dbUpdater *DBUpdater,
) *ApprovePoliciesCommandRunner {
Expand All @@ -27,7 +27,7 @@ type ApprovePoliciesCommandRunner struct {
pullUpdater *PullUpdater
dbUpdater *DBUpdater
prjCmdBuilder ProjectApprovePoliciesCommandBuilder
prjCmdRunner ProjectPolicyCheckCommandRunner
prjCmdRunner ProjectApprovePoliciesCommandRunner
}

func (a *ApprovePoliciesCommandRunner) Run(ctx *CommandContext, cmd *CommentCommand) {
Expand Down Expand Up @@ -76,16 +76,7 @@ func (a *ApprovePoliciesCommandRunner) buildApprovePolicyCommandResults(ctx *Com
var prjResults []models.ProjectResult

for _, prjCmd := range prjCmds {

prjResult := models.ProjectResult{
Command: models.PolicyCheckCommand,
PolicyCheckSuccess: &models.PolicyCheckSuccess{
PolicyCheckOutput: "Policies approved",
},
RepoRelDir: prjCmd.RepoRelDir,
Workspace: prjCmd.Workspace,
ProjectName: prjCmd.ProjectName,
}
prjResult := a.prjCmdRunner.ApprovePolicies(prjCmd)
prjResults = append(prjResults, prjResult)
}
result.ProjectResults = prjResults
Expand Down
9 changes: 9 additions & 0 deletions server/events/command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,15 @@ func TestApprovedPoliciesUpdateFailedPolicyStatus(t *testing.T) {
},
}, nil)

When(projectCommandRunner.ApprovePolicies(matchers.AnyModelsProjectCommandContext())).Then(func(_ []Param) ReturnValues {
return ReturnValues{
models.ProjectResult{
Command: models.PolicyCheckCommand,
PolicyCheckSuccess: &models.PolicyCheckSuccess{},
},
}
})

When(workingDir.GetPullDir(fixtures.GithubRepo, fixtures.Pull)).ThenReturn(tmp, nil)

ch.RunCommentCommand(fixtures.GithubRepo, &fixtures.GithubRepo, &fixtures.Pull, fixtures.User, fixtures.Pull.Num, &events.CommentCommand{Name: models.ApprovePoliciesCommand})
Expand Down
42 changes: 42 additions & 0 deletions server/events/mocks/mock_project_command_runner.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions server/events/project_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,18 @@ type ProjectPolicyCheckCommandRunner interface {
PolicyCheck(ctx models.ProjectCommandContext) models.ProjectResult
}

type ProjectApprovePoliciesCommandRunner interface {
// Approves any failing OPA policies.
ApprovePolicies(ctx models.ProjectCommandContext) models.ProjectResult
}

// ProjectCommandRunner runs project commands. A project command is a command
// for a specific TF project.
type ProjectCommandRunner interface {
ProjectPlanCommandRunner
ProjectApplyCommandRunner
ProjectPolicyCheckCommandRunner
ProjectApprovePoliciesCommandRunner
}

// DefaultProjectCommandRunner implements ProjectCommandRunner.
Expand Down Expand Up @@ -162,6 +168,36 @@ func (p *DefaultProjectCommandRunner) Apply(ctx models.ProjectCommandContext) mo
}
}

func (p *DefaultProjectCommandRunner) ApprovePolicies(ctx models.ProjectCommandContext) models.ProjectResult {
approvedOut, failure, err := p.doApprovePolicies(ctx)
return models.ProjectResult{
Command: models.PolicyCheckCommand,
Failure: failure,
Error: err,
PolicyCheckSuccess: approvedOut,
RepoRelDir: ctx.RepoRelDir,
Workspace: ctx.Workspace,
ProjectName: ctx.ProjectName,
}
}

func (p *DefaultProjectCommandRunner) doApprovePolicies(ctx models.ProjectCommandContext) (*models.PolicyCheckSuccess, string, error) {
// Acquire Atlantis lock for this repo/dir/workspace.
lockAttempt, err := p.Locker.TryLock(ctx.Log, ctx.Pull, ctx.User, ctx.Workspace, models.NewProject(ctx.Pull.BaseRepo.FullName, ctx.RepoRelDir))
if err != nil {
return nil, "", errors.Wrap(err, "acquiring lock")
}
if !lockAttempt.LockAcquired {
return nil, lockAttempt.LockFailureReason, nil
}
ctx.Log.Debug("acquired lock for project")

return &models.PolicyCheckSuccess{
LockURL: p.LockURLGenerator.GenerateLockURL(lockAttempt.LockKey),
PolicyCheckOutput: "Policies approved",
}, "", nil
}

func (p *DefaultProjectCommandRunner) doPolicyCheck(ctx models.ProjectCommandContext) (*models.PolicyCheckSuccess, string, error) {
// Acquire Atlantis lock for this repo/dir/workspace.
lockAttempt, err := p.Locker.TryLock(ctx.Log, ctx.Pull, ctx.User, ctx.Workspace, models.NewProject(ctx.Pull.BaseRepo.FullName, ctx.RepoRelDir))
Expand Down
Loading

0 comments on commit 37fd2a7

Please sign in to comment.