mirror of
https://git.vectorsigma.ru/public/atlantis.git
synced 2026-08-01 03:38:44 +00:00
* 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
125 lines
4.2 KiB
Go
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)
|
|
}
|
|
}
|