Files
atlantis/server/events/approve_policies_command_runner.go
Sarvar Muminov 90e92e3a13 chore: move CommandContext and CommandResult to models (#193) (#2093)
* Moved CommandContext and CommandResult to models (#193)

* Moved CommandContext and CommandResult to models

* move from models to command

rename CommandContext -> Context
rename CommandResult -> Result

* moved command related helpers into command package

* move ProjectCommandContext and ProjectResult to command/project package

* move project command context and project result

* revert unrelated code

* move tests

* fix left over

* fix linting

* fix tests

* remove unused import

* fix project context dependencies

* fix depenedecies

* fix typo
2022-03-21 10:36:13 -07:00

125 lines
4.2 KiB
Go

package events
import (
"fmt"
"github.com/runatlantis/atlantis/server/events/command"
"github.com/runatlantis/atlantis/server/events/models"
)
func NewApprovePoliciesCommandRunner(
commitStatusUpdater CommitStatusUpdater,
prjCommandBuilder ProjectApprovePoliciesCommandBuilder,
prjCommandRunner ProjectApprovePoliciesCommandRunner,
pullUpdater *PullUpdater,
dbUpdater *DBUpdater,
SilenceNoProjects bool,
silenceVCSStatusNoProjects bool,
) *ApprovePoliciesCommandRunner {
return &ApprovePoliciesCommandRunner{
commitStatusUpdater: commitStatusUpdater,
prjCmdBuilder: prjCommandBuilder,
prjCmdRunner: prjCommandRunner,
pullUpdater: pullUpdater,
dbUpdater: dbUpdater,
SilenceNoProjects: SilenceNoProjects,
silenceVCSStatusNoProjects: silenceVCSStatusNoProjects,
}
}
type ApprovePoliciesCommandRunner struct {
commitStatusUpdater CommitStatusUpdater
pullUpdater *PullUpdater
dbUpdater *DBUpdater
prjCmdBuilder ProjectApprovePoliciesCommandBuilder
prjCmdRunner ProjectApprovePoliciesCommandRunner
// SilenceNoProjects is whether Atlantis should respond to PRs if no projects
// are found
SilenceNoProjects bool
silenceVCSStatusNoProjects bool
}
func (a *ApprovePoliciesCommandRunner) Run(ctx *command.Context, cmd *CommentCommand) {
baseRepo := ctx.Pull.BaseRepo
pull := ctx.Pull
if err := a.commitStatusUpdater.UpdateCombined(baseRepo, pull, models.PendingCommitStatus, command.PolicyCheck); err != nil {
ctx.Log.Warn("unable to update commit status: %s", err)
}
projectCmds, err := a.prjCmdBuilder.BuildApprovePoliciesCommands(ctx, cmd)
if err != nil {
if statusErr := a.commitStatusUpdater.UpdateCombined(ctx.Pull.BaseRepo, ctx.Pull, models.FailedCommitStatus, command.PolicyCheck); statusErr != nil {
ctx.Log.Warn("unable to update commit status: %s", statusErr)
}
a.pullUpdater.updatePull(ctx, cmd, command.Result{Error: err})
return
}
if len(projectCmds) == 0 && a.SilenceNoProjects {
ctx.Log.Info("determined there was no project to run approve_policies in")
if !a.silenceVCSStatusNoProjects {
// If there were no projects modified, we set successful commit statuses
// with 0/0 projects approve_policies successfully because some users require
// the Atlantis status to be passing for all pull requests.
ctx.Log.Debug("setting VCS status to success with no projects found")
if err := a.commitStatusUpdater.UpdateCombinedCount(ctx.Pull.BaseRepo, ctx.Pull, models.SuccessCommitStatus, command.PolicyCheck, 0, 0); err != nil {
ctx.Log.Warn("unable to update commit status: %s", err)
}
}
return
}
result := a.buildApprovePolicyCommandResults(ctx, projectCmds)
a.pullUpdater.updatePull(
ctx,
cmd,
result,
)
pullStatus, err := a.dbUpdater.updateDB(ctx, pull, result.ProjectResults)
if err != nil {
ctx.Log.Err("writing results: %s", err)
return
}
a.updateCommitStatus(ctx, pullStatus)
}
func (a *ApprovePoliciesCommandRunner) buildApprovePolicyCommandResults(ctx *command.Context, prjCmds []command.ProjectContext) (result command.Result) {
// Check if vcs user is in the owner list of the PolicySets. All projects
// share the same Owners list at this time so no reason to iterate over each
// project.
if len(prjCmds) > 0 && !prjCmds[0].PolicySets.IsOwner(ctx.User.Username) {
result.Error = fmt.Errorf("contact policy owners to approve failing policies")
return
}
var prjResults []command.ProjectResult
for _, prjCmd := range prjCmds {
prjResult := a.prjCmdRunner.ApprovePolicies(prjCmd)
prjResults = append(prjResults, prjResult)
}
result.ProjectResults = prjResults
return
}
func (a *ApprovePoliciesCommandRunner) updateCommitStatus(ctx *command.Context, pullStatus models.PullStatus) {
var numSuccess int
var numErrored int
status := models.SuccessCommitStatus
numSuccess = pullStatus.StatusCount(models.PassedPolicyCheckStatus)
numErrored = pullStatus.StatusCount(models.ErroredPolicyCheckStatus)
if numErrored > 0 {
status = models.FailedCommitStatus
}
if err := a.commitStatusUpdater.UpdateCombinedCount(ctx.Pull.BaseRepo, ctx.Pull, status, command.PolicyCheck, numSuccess, len(pullStatus.Projects)); err != nil {
ctx.Log.Warn("unable to update commit status: %s", err)
}
}