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

notification for failures #48

Merged
merged 3 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ _Access policies have been deprecated. Please [read this](./access/README.md) fo

- [Drift Detection with changes](./notification/drift-detection-with-changes.rego)
- [Slack Channels set with labels](./notification/slack-channels-with-labels.rego)
- [Notification for link to failure logs](./notification/notification-failure.rego)

### Plan Policy

Expand Down
44 changes: 44 additions & 0 deletions notification/notification-failure.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package spacelift

import future.keywords.contains
import future.keywords.if
import future.keywords.in

ir := input.run_updated

run := sprintf("https://%s.app.spacelift.io/stack/%s/run/%s", [input.account.name, ir.stack.id, ir.run.id])

failed if {
input.run_updated.run.state == "FAILED"
}

slack contains {
"channel_id": "C05H9PV1TK9",
"message": msg,
} if {
failed
any_deny_or_reject
some pr in ir.policy_receipts
msg := sprintf("The run failed as the %s policy had a %s outcome. Details: %s", [pr.name, pr.outcome, run])
}

slack contains {
"channel_id": "C05H9PV1TK9",
"message": msg,
} if {
failed
not any_deny_or_reject
msg := sprintf("The run failed, you can review the logs to see why here: %s", [run])
}

any_deny_or_reject if {
some pr in ir.policy_receipts
pr.outcome == "deny"
}

any_deny_or_reject if {
some pr in ir.policy_receipts
pr.outcome == "reject"
}

sample := true
62 changes: 62 additions & 0 deletions notification/notification-failure_test.rego
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package spacelift_test

import data.spacelift
import future.keywords.contains
import future.keywords.if
import future.keywords.in

# Test Case 1: Run failed with 'deny' outcome
test_run_failed_with_deny if {
input := {
"account": {"name": "<example>"},
"run_updated": {
"run": {"state": "FAILED", "id": "run123"},
"stack": {"id": "stack123"},
"policy_receipts": [{"name": "deny_policy", "outcome": "deny"}],
},
}
result := spacelift.slack with input as input
count(result) == 1
}

# Test Case 2: Run failed with 'reject' outcome
test_run_failed_with_reject if {
input := {
"account": {"name": "<example>"},
"run_updated": {
"run": {"state": "FAILED", "id": "run123"},
"stack": {"id": "stack123"},
"policy_receipts": [{"name": "reject_policy", "outcome": "reject"}],
},
}
result := spacelift.slack with input as input
count(result) == 1
}

# Test Case 3: Run failed with neither 'deny' nor 'reject' outcome
test_run_failed_with_neither if {
input := {
"account": {"name": "<example>"},
"run_updated": {
"run": {"state": "FAILED", "id": "run123"},
"stack": {"id": "stack123"},
"policy_receipts": [{"name": "null", "outcome": null}],
},
}
result := spacelift.slack with input as input
count(result) == 1
}

# Test Case 4: Run has not failed
test_run_not_failed if {
input := {
"account": {"name": "<example>"},
"run_updated": {
"run": {"state": "PASSED", "id": "run123"},
"stack": {"id": "stack123"},
"policy_receipts": [{"name": "some_policy", "outcome": "deny"}],
},
}
result := spacelift.slack with input as input
count(result) == 0
}