Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add a flag to silence policy checks comments when there's no error #2405

Merged
merged 10 commits into from
Oct 27, 2022
6 changes: 6 additions & 0 deletions runatlantis.io/docs/server-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,12 @@ Values are chosen in this order:
```
Port to bind to. Defaults to `4141`.

### `--quiet-policy-checks`
```bash
atlantis server --quiet-policy-checks
```
Exclude policy check comments from pull requests unless there's an actual error from conftest. This also excludes warnings. Defaults to `false`.

### `--redis-host`
```bash
atlantis server --redis-host="localhost"
Expand Down
44 changes: 44 additions & 0 deletions server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -653,6 +653,12 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) {
ExpAutomerge bool
// ExpAutoplan is true if we expect Atlantis to autoplan.
ExpAutoplan bool
// ExpQuietPolicyChecks is true if we expect Atlantis to exclude policy check output
// when there's no error
ExpQuietPolicyChecks bool
// ExpQuietPolicyCheckFailure is true when we expect Atlantis to post back policy check failures
// even when QuietPolicyChecks is enabled
ExpQuietPolicyCheckFailure bool
// ExpParallel is true if we expect Atlantis to run parallel plans or applies.
ExpParallel bool
// ExpReplies is a list of files containing the expected replies that
Expand Down Expand Up @@ -737,6 +743,38 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) {
{"exp-output-merge.txt"},
},
},
{
Description: "successful policy checks with quiet flag enabled",
RepoDir: "policy-checks-success-silent",
ModifiedFiles: []string{"main.tf"},
ExpAutoplan: true,
ExpQuietPolicyChecks: true,
Comments: []string{
"atlantis apply",
},
ExpReplies: [][]string{
{"exp-output-autoplan.txt"},
{"exp-output-apply.txt"},
{"exp-output-merge.txt"},
},
},
{
Description: "failing policy checks with quiet flag enabled",
RepoDir: "policy-checks",
ModifiedFiles: []string{"main.tf"},
ExpAutoplan: true,
ExpQuietPolicyChecks: true,
ExpQuietPolicyCheckFailure: true,
Comments: []string{
"atlantis apply",
},
ExpReplies: [][]string{
{"exp-output-autoplan.txt"},
{"exp-output-auto-policy-check.txt"},
{"exp-output-apply-failed.txt"},
{"exp-output-merge.txt"},
},
},
}

for _, c := range cases {
Expand All @@ -746,6 +784,7 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) {
// reset userConfig
userConfig = server.UserConfig{}
userConfig.EnablePolicyChecksFlag = true
userConfig.QuietPolicyChecks = c.ExpQuietPolicyChecks

ctrl, vcsClient, githubGetter, atlantisWorkspace := setupE2E(t, c.RepoDir)

Expand Down Expand Up @@ -805,6 +844,10 @@ func TestGitHubWorkflowWithPolicyCheck(t *testing.T) {
expNumReplies++
}

if c.ExpQuietPolicyChecks && !c.ExpQuietPolicyCheckFailure {
expNumReplies--
}

_, _, actReplies, _ := vcsClient.VerifyWasCalled(Times(expNumReplies)).CreateComment(AnyRepo(), AnyInt(), AnyString(), AnyString()).GetAllCapturedArguments()
Assert(t, len(c.ExpReplies) == len(actReplies), "missing expected replies, got %d but expected %d", len(actReplies), len(c.ExpReplies))
for i, expReply := range c.ExpReplies {
Expand Down Expand Up @@ -1008,6 +1051,7 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
projectCommandRunner,
parallelPoolSize,
false,
userConfig.QuietPolicyChecks,
)

planCommandRunner := events.NewPlanCommandRunner(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
version: 3
projects:
- dir: .
workspace: default
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Ran Apply for dir: `.` workspace: `default`

```diff

Apply complete! Resources: 0 added, 0 changed, 0 destroyed.

Outputs:

workspace = "default"

```

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Ran Plan for dir: `.` workspace: `default`

```diff

Changes to Outputs:
+ workspace = "default"

You can apply this plan to save these new output values to the Terraform
state, without changing any real infrastructure.

```

* :arrow_forward: To **apply** this plan, comment:
* `atlantis apply -d .`
* :put_litter_in_its_place: To **delete** this plan click [here](lock-url)
* :repeat: To **plan** this project again, comment:
* `atlantis plan -d .`

---
* :fast_forward: To **apply** all unapplied plans from this pull request, comment:
* `atlantis apply`
* :put_litter_in_its_place: To delete all plans and locks for the PR, comment:
* `atlantis unlock`
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Locks and plans deleted for the projects and workspaces modified in this pull request:

- dir: `.` workspace: `default`
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
output "workspace" {
value = terraform.workspace
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package main

import input as tfplan

deny[reason] {
num_deletes.null_resource > 0
reason := "WARNING: Null Resource creation is prohibited."
}

resource_types = {"null_resource"}

resources[resource_type] = all {
some resource_type
resource_types[resource_type]
all := [name |
name := tfplan.resource_changes[_]
name.type == resource_type
]
}

# number of deletions of resources of a given type
num_deletes[resource_type] = num {
some resource_type
resource_types[resource_type]
all := resources[resource_type]
deletions := [res | res := all[_]; res.change.actions[_] == "create"]
num := count(deletions)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
repos:
- id: /.*/
apply_requirements: [approved]
policies:
owners:
users:
- runatlantis
policy_sets:
- name: test_policy
path: policies/policy.rego
source: local

1 change: 1 addition & 0 deletions server/events/command_runner_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ func setup(t *testing.T) *vcsmocks.MockClient {
projectCommandRunner,
parallelPoolSize,
false,
false,
)

planCommandRunner = events.NewPlanCommandRunner(
Expand Down
8 changes: 7 additions & 1 deletion server/events/policy_check_command_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ func NewPolicyCheckCommandRunner(
projectCommandRunner ProjectPolicyCheckCommandRunner,
parallelPoolSize int,
silenceVCSStatusNoProjects bool,
quietPolicyChecks bool,
) *PolicyCheckCommandRunner {
return &PolicyCheckCommandRunner{
dbUpdater: dbUpdater,
Expand All @@ -20,6 +21,7 @@ func NewPolicyCheckCommandRunner(
prjCmdRunner: projectCommandRunner,
parallelPoolSize: parallelPoolSize,
silenceVCSStatusNoProjects: silenceVCSStatusNoProjects,
quietPolicyChecks: quietPolicyChecks,
}
}

Expand All @@ -32,6 +34,7 @@ type PolicyCheckCommandRunner struct {
// SilenceVCSStatusNoProjects is whether any plan should set commit status if no projects
// are found
silenceVCSStatusNoProjects bool
quietPolicyChecks bool
}

func (p *PolicyCheckCommandRunner) Run(ctx *command.Context, cmds []command.ProjectContext) {
Expand Down Expand Up @@ -62,7 +65,10 @@ func (p *PolicyCheckCommandRunner) Run(ctx *command.Context, cmds []command.Proj
result = runProjectCmds(cmds, p.prjCmdRunner.PolicyCheck)
}

p.pullUpdater.updatePull(ctx, PolicyCheckCommand{}, result)
// Quiet policy checks unless there's an error
if result.HasErrors() || !p.quietPolicyChecks {
p.pullUpdater.updatePull(ctx, PolicyCheckCommand{}, result)
}

pullStatus, err := p.dbUpdater.updateDB(ctx, ctx.Pull, result.ProjectResults)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -621,6 +621,7 @@ func NewServer(userConfig UserConfig, config Config) (*Server, error) {
instrumentedProjectCmdRunner,
userConfig.ParallelPoolSize,
userConfig.SilenceVCSStatusNoProjects,
userConfig.QuietPolicyChecks,
)

planCommandRunner := events.NewPlanCommandRunner(
Expand Down
1 change: 1 addition & 0 deletions server/user_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type UserConfig struct {
StatsNamespace string `mapstructure:"stats-namespace"`
PlanDrafts bool `mapstructure:"allow-draft-prs"`
Port int `mapstructure:"port"`
QuietPolicyChecks bool `mapstructure:"quiet-policy-checks"`
RedisDB int `mapstructure:"redis-db"`
RedisHost string `mapstructure:"redis-host"`
RedisPassword string `mapstructure:"redis-password"`
Expand Down