Enable --auto-approve for Policy checks on Remote Backend (Terraform Cloud) (#27804)
* Fix auto-approve for soft-policy * Update error handling * update testing string for consistency
This commit is contained in:
parent
b5adc33075
commit
e9c7f37b8c
|
@ -1151,6 +1151,7 @@ func TestRemote_applyPolicySoftFail(t *testing.T) {
|
||||||
"approve": "yes",
|
"approve": "yes",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
op.AutoApprove = false
|
||||||
op.UIIn = input
|
op.UIIn = input
|
||||||
op.UIOut = b.CLI
|
op.UIOut = b.CLI
|
||||||
op.Workspace = backend.DefaultStateName
|
op.Workspace = backend.DefaultStateName
|
||||||
|
@ -1187,16 +1188,14 @@ func TestRemote_applyPolicySoftFail(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemote_applyPolicySoftFailAutoApprove(t *testing.T) {
|
func TestRemote_applyPolicySoftFailAutoApproveSuccess(t *testing.T) {
|
||||||
b, bCleanup := testBackendDefault(t)
|
b, bCleanup := testBackendDefault(t)
|
||||||
defer bCleanup()
|
defer bCleanup()
|
||||||
|
|
||||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply-policy-soft-failed")
|
op, configCleanup, done := testOperationApply(t, "./testdata/apply-policy-soft-failed")
|
||||||
defer configCleanup()
|
defer configCleanup()
|
||||||
|
|
||||||
input := testInput(t, map[string]string{
|
input := testInput(t, map[string]string{})
|
||||||
"override": "override",
|
|
||||||
})
|
|
||||||
|
|
||||||
op.AutoApprove = true
|
op.AutoApprove = true
|
||||||
op.UIIn = input
|
op.UIIn = input
|
||||||
|
@ -1210,34 +1209,33 @@ func TestRemote_applyPolicySoftFailAutoApprove(t *testing.T) {
|
||||||
|
|
||||||
<-run.Done()
|
<-run.Done()
|
||||||
viewOutput := done(t)
|
viewOutput := done(t)
|
||||||
if run.Result == backend.OperationSuccess {
|
if run.Result != backend.OperationSuccess {
|
||||||
t.Fatal("expected apply operation to fail")
|
t.Fatal("expected apply operation to success due to auto-approve")
|
||||||
}
|
|
||||||
if !run.PlanEmpty {
|
|
||||||
t.Fatalf("expected plan to be empty")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(input.answers) != 1 {
|
if run.PlanEmpty {
|
||||||
t.Fatalf("expected an unused answers, got: %v", input.answers)
|
t.Fatalf("expected plan to not be empty, plan opertion completed without error")
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(input.answers) != 0 {
|
||||||
|
t.Fatalf("expected no answers, got: %v", input.answers)
|
||||||
}
|
}
|
||||||
|
|
||||||
errOutput := viewOutput.Stderr()
|
errOutput := viewOutput.Stderr()
|
||||||
if !strings.Contains(errOutput, "soft failed") {
|
if strings.Contains(errOutput, "soft failed") {
|
||||||
t.Fatalf("expected a policy check error, got: %v", errOutput)
|
t.Fatalf("expected no policy check errors, instead got: %v", errOutput)
|
||||||
}
|
}
|
||||||
|
|
||||||
output := b.CLI.(*cli.MockUi).OutputWriter.String()
|
output := b.CLI.(*cli.MockUi).OutputWriter.String()
|
||||||
if !strings.Contains(output, "Running apply in the remote backend") {
|
|
||||||
t.Fatalf("expected remote backend header in output: %s", output)
|
|
||||||
}
|
|
||||||
if !strings.Contains(output, "1 to add, 0 to change, 0 to destroy") {
|
|
||||||
t.Fatalf("expected plan summery in output: %s", output)
|
|
||||||
}
|
|
||||||
if !strings.Contains(output, "Sentinel Result: false") {
|
if !strings.Contains(output, "Sentinel Result: false") {
|
||||||
t.Fatalf("expected policy check result in output: %s", output)
|
t.Fatalf("expected policy check to be false, insead got: %s", output)
|
||||||
}
|
}
|
||||||
if strings.Contains(output, "1 added, 0 changed, 0 destroyed") {
|
if !strings.Contains(output, "Apply complete!") {
|
||||||
t.Fatalf("unexpected apply summery in output: %s", output)
|
t.Fatalf("expected apply to be complete, instead got: %s", output)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.Contains(output, "Resources: 1 added, 0 changed, 0 destroyed") {
|
||||||
|
t.Fatalf("expected resources, instead got: %s", output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,34 +414,45 @@ func (b *Remote) checkPolicy(stopCtx, cancelCtx context.Context, op *backend.Ope
|
||||||
case tfe.PolicyHardFailed:
|
case tfe.PolicyHardFailed:
|
||||||
return fmt.Errorf(msgPrefix + " hard failed.")
|
return fmt.Errorf(msgPrefix + " hard failed.")
|
||||||
case tfe.PolicySoftFailed:
|
case tfe.PolicySoftFailed:
|
||||||
|
runUrl := fmt.Sprintf(runHeader, b.hostname, b.organization, op.Workspace, r.ID)
|
||||||
|
|
||||||
if op.Type == backend.OperationTypePlan || op.UIOut == nil || op.UIIn == nil ||
|
if op.Type == backend.OperationTypePlan || op.UIOut == nil || op.UIIn == nil ||
|
||||||
op.AutoApprove || !pc.Actions.IsOverridable || !pc.Permissions.CanOverride {
|
!pc.Actions.IsOverridable || !pc.Permissions.CanOverride {
|
||||||
return fmt.Errorf(msgPrefix + " soft failed.")
|
return fmt.Errorf(msgPrefix + " soft failed.\n" + runUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
if op.AutoApprove {
|
||||||
|
if _, err = b.client.PolicyChecks.Override(stopCtx, pc.ID); err != nil {
|
||||||
|
return generalError(fmt.Sprintf("Failed to override policy check.\n%s", runUrl), err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
opts := &terraform.InputOpts{
|
||||||
|
Id: "override",
|
||||||
|
Query: "\nDo you want to override the soft failed policy check?",
|
||||||
|
Description: "Only 'override' will be accepted to override.",
|
||||||
|
}
|
||||||
|
err = b.confirm(stopCtx, op, opts, r, "override")
|
||||||
|
if err != nil && err != errRunOverridden {
|
||||||
|
return fmt.Errorf(
|
||||||
|
fmt.Sprintf("Failed to override: %s\n%s\n", err.Error(), runUrl),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != errRunOverridden {
|
||||||
|
if _, err = b.client.PolicyChecks.Override(stopCtx, pc.ID); err != nil {
|
||||||
|
return generalError(fmt.Sprintf("Failed to override policy check.\n%s", runUrl), err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
b.CLI.Output(fmt.Sprintf("The run needs to be manually overridden or discarded.\n%s\n", runUrl))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.CLI != nil {
|
||||||
|
b.CLI.Output("------------------------------------------------------------------------")
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("Unknown or unexpected policy state: %s", pc.Status)
|
return fmt.Errorf("Unknown or unexpected policy state: %s", pc.Status)
|
||||||
}
|
}
|
||||||
|
|
||||||
opts := &terraform.InputOpts{
|
|
||||||
Id: "override",
|
|
||||||
Query: "\nDo you want to override the soft failed policy check?",
|
|
||||||
Description: "Only 'override' will be accepted to override.",
|
|
||||||
}
|
|
||||||
|
|
||||||
err = b.confirm(stopCtx, op, opts, r, "override")
|
|
||||||
if err != nil && err != errRunOverridden {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err != errRunOverridden {
|
|
||||||
if _, err = b.client.PolicyChecks.Override(stopCtx, pc.ID); err != nil {
|
|
||||||
return generalError("Failed to override policy check", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if b.CLI != nil {
|
|
||||||
b.CLI.Output("------------------------------------------------------------------------")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in New Issue