Skip to content

Commit a170a2a

Browse files
Add default failure policy flag
Agent-Logs-Url: https://github.com/open-policy-agent/gatekeeper/sessions/d4a5e66c-314f-4cec-9b97-cec82e05f12f Co-authored-by: JaydipGabani <20255485+JaydipGabani@users.noreply.github.com>
1 parent 0def22a commit a170a2a

7 files changed

Lines changed: 110 additions & 10 deletions

File tree

pkg/drivers/k8scel/schema/schema.go

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package schema
22

33
import (
4+
"flag"
45
"fmt"
56
"strings"
67

@@ -13,6 +14,8 @@ import (
1314
"k8s.io/apiserver/pkg/admission/plugin/webhook/matchconditions"
1415
)
1516

17+
var DefaultFailurePolicy = flag.String("default-failure-policy", string(admissionv1.Fail), "(beta) Failure policy to use when a K8sNativeValidation source omits failurePolicy. Allowed values are Fail or Ignore.")
18+
1619
const (
1720
// Name is the name of the driver.
1821
Name = "K8sNativeValidation"
@@ -197,38 +200,40 @@ func (in *Source) GetMessageExpressions() ([]cel.ExpressionAccessor, error) {
197200
}
198201

199202
func (in *Source) GetFailurePolicy() (*admissionv1.FailurePolicyType, error) {
200-
if in.FailurePolicy == nil {
201-
return nil, nil
203+
failurePolicy := in.FailurePolicy
204+
if failurePolicy == nil {
205+
failurePolicy = DefaultFailurePolicy
202206
}
203207

204208
var out admissionv1.FailurePolicyType
205209

206-
switch *in.FailurePolicy {
210+
switch *failurePolicy {
207211
case string(admissionv1.Fail):
208212
out = admissionv1.Fail
209213
case string(admissionv1.Ignore):
210214
out = admissionv1.Ignore
211215
default:
212-
return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *in.FailurePolicy)
216+
return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *failurePolicy)
213217
}
214218

215219
return &out, nil
216220
}
217221

218222
func (in *Source) GetV1Beta1FailurePolicy() (*admissionv1beta1.FailurePolicyType, error) {
219-
var out admissionv1beta1.FailurePolicyType
220-
if in.FailurePolicy == nil {
221-
out = admissionv1beta1.Fail
222-
return &out, nil
223+
failurePolicy := in.FailurePolicy
224+
if failurePolicy == nil {
225+
failurePolicy = DefaultFailurePolicy
223226
}
224227

225-
switch *in.FailurePolicy {
228+
var out admissionv1beta1.FailurePolicyType
229+
230+
switch *failurePolicy {
226231
case string(admissionv1.Fail):
227232
out = admissionv1beta1.Fail
228233
case string(admissionv1.Ignore):
229234
out = admissionv1beta1.Ignore
230235
default:
231-
return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *in.FailurePolicy)
236+
return nil, fmt.Errorf("%w: unrecognized failure policy: %s", ErrBadFailurePolicy, *failurePolicy)
232237
}
233238

234239
return &out, nil

pkg/drivers/k8scel/schema/schema_test.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"testing"
77

88
"github.com/open-policy-agent/frameworks/constraint/pkg/core/templates"
9+
admissionv1 "k8s.io/api/admissionregistration/v1"
10+
admissionv1beta1 "k8s.io/api/admissionregistration/v1beta1"
911
"k8s.io/utils/ptr"
1012
)
1113

@@ -182,6 +184,42 @@ func TestValidationErrors(t *testing.T) {
182184
}
183185
}
184186

187+
func TestDefaultFailurePolicy(t *testing.T) {
188+
original := *DefaultFailurePolicy
189+
t.Cleanup(func() { *DefaultFailurePolicy = original })
190+
191+
source := &Source{}
192+
*DefaultFailurePolicy = string(admissionv1.Ignore)
193+
194+
failurePolicy, err := source.GetFailurePolicy()
195+
if err != nil {
196+
t.Fatalf("GetFailurePolicy() returned an unexpected error: %v", err)
197+
}
198+
if failurePolicy == nil || *failurePolicy != admissionv1.Ignore {
199+
t.Fatalf("GetFailurePolicy() = %v, want %s", failurePolicy, admissionv1.Ignore)
200+
}
201+
202+
v1beta1FailurePolicy, err := source.GetV1Beta1FailurePolicy()
203+
if err != nil {
204+
t.Fatalf("GetV1Beta1FailurePolicy() returned an unexpected error: %v", err)
205+
}
206+
if v1beta1FailurePolicy == nil || *v1beta1FailurePolicy != admissionv1beta1.Ignore {
207+
t.Fatalf("GetV1Beta1FailurePolicy() = %v, want %s", v1beta1FailurePolicy, admissionv1beta1.Ignore)
208+
}
209+
}
210+
211+
func TestDefaultFailurePolicyIsValidated(t *testing.T) {
212+
original := *DefaultFailurePolicy
213+
t.Cleanup(func() { *DefaultFailurePolicy = original })
214+
215+
source := &Source{}
216+
*DefaultFailurePolicy = "Unsupported"
217+
218+
if err := source.Validate(); !errors.Is(err, ErrBadFailurePolicy) {
219+
t.Fatalf("Validate() error = %v, want %v", err, ErrBadFailurePolicy)
220+
}
221+
}
222+
185223
func TestHasCELEngine(t *testing.T) {
186224
tests := []struct {
187225
name string

pkg/drivers/k8scel/transform/make_vap_objects_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,57 @@ func TestTemplateToPolicyDefinition(t *testing.T) {
243243
}
244244
}
245245

246+
func TestTemplateToPolicyDefinitionUsesDefaultFailurePolicy(t *testing.T) {
247+
original := *schema.DefaultFailurePolicy
248+
t.Cleanup(func() { *schema.DefaultFailurePolicy = original })
249+
*schema.DefaultFailurePolicy = string(admissionregistrationv1.Ignore)
250+
251+
source := &schema.Source{
252+
Validations: []schema.Validation{
253+
{
254+
Expression: "true",
255+
Message: "always passes",
256+
},
257+
},
258+
}
259+
rawSrc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(source)
260+
if err != nil {
261+
t.Fatalf("unexpected error converting source to unstructured: %v", err)
262+
}
263+
template := &templates.ConstraintTemplate{
264+
ObjectMeta: metav1.ObjectMeta{Name: "somepolicy"},
265+
Spec: templates.ConstraintTemplateSpec{
266+
CRD: templates.CRD{
267+
Spec: templates.CRDSpec{
268+
Names: templates.Names{
269+
Kind: "SomePolicy",
270+
},
271+
},
272+
},
273+
Targets: []templates.Target{
274+
{
275+
Code: []templates.Code{
276+
{
277+
Engine: schema.Name,
278+
Source: &templates.Anything{
279+
Value: rawSrc,
280+
},
281+
},
282+
},
283+
},
284+
},
285+
},
286+
}
287+
288+
policy, err := TemplateToPolicyDefinition(template)
289+
if err != nil {
290+
t.Fatalf("TemplateToPolicyDefinition() returned an unexpected error: %v", err)
291+
}
292+
if policy.Spec.FailurePolicy == nil || *policy.Spec.FailurePolicy != admissionregistrationv1beta1.Ignore {
293+
t.Fatalf("FailurePolicy = %v, want %s", policy.Spec.FailurePolicy, admissionregistrationv1beta1.Ignore)
294+
}
295+
}
296+
246297
func TestTemplateToPolicyDefinitionWithWebhookConfig(t *testing.T) {
247298
baseSource := &schema.Source{
248299
FailurePolicy: ptr.To[string]("Fail"),

website/docs/runtime-flags.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The following flags can be used to configure Gatekeeper's runtime behavior:
3737
| `--log-stats-audit` | `false` | (alpha) Log stats metrics for the audit run. |
3838
| `--default-create-vap-binding-for-constraints` | `true` | (beta) Create VAPBinding resource for constraint of the template containing VAP-style CEL source. Allowed values are false: do not create Validating Admission Policy Binding, true: create Validating Admission Policy Binding. |
3939
| `--default-create-vap-for-templates` | `true` | (beta) Create VAP resource for template containing VAP-style CEL source. Allowed values are false: do not create Validating Admission Policy unless generateVAP: true is set on constraint template explicitly, true: create Validating Admission Policy unless generateVAP: false is set on constraint template explicitly. |
40+
| `--default-failure-policy` | `Fail` | (beta) Failure policy to use when a K8sNativeValidation source omits failurePolicy. Allowed values are Fail or Ignore. |
4041
| `--default-wait-for-vapb-generation` | `30` | (beta) Wait time in seconds before generating a ValidatingAdmissionPolicyBinding after a constraint CRD is created. |
4142
| `--debug-use-fake-pod` | `false` | Use a fake pod name so the Gatekeeper executable can be run outside of Kubernetes. |
4243
| `--enable-violation-export` | `false` | (alpha) Enable exporting violations to external systems. |

website/docs/validating-admission-policy.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ For some policies, you may want admission requests to be handled by the K8s Vali
120120
The K8s Validating Admission Controller requires both the Validating Admission Policy (VAP) and Validating Admission Policy Binding (VAPB) resources to exist to enforce a policy. Gatekeeper can be configured to generate both of these resources. To generate VAP Bindings for all Constraints, ensure the Gatekeeper
121121
`--default-create-vap-binding-for-constraints` flag is set to `true`. To generate VAP as part of all Constraint Templates with the VAP CEL engine `K8sNativeValidation`, ensure the Gatekeeper `--default-create-vap-for-templates=true` flag is set to `true`. By default both flags are set to `true` now that the feature is in beta.
122122

123+
If a K8sNativeValidation source omits `failurePolicy`, Gatekeeper uses `--default-failure-policy`, which defaults to `Fail`, for both Gatekeeper's CEL evaluation and generated VAP resources.
124+
123125
To override the `--default-create-vap-for-templates` flag's behavior for a constraint template, set `generateVAP` to `true` explicitly under the K8sNativeValidation engine's `source` in the constraint template.
124126

125127
```yaml

website/versioned_docs/version-v3.22.x/runtime-flags.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The following flags can be used to configure Gatekeeper's runtime behavior:
3737
| `--log-stats-audit` | `false` | (alpha) Log stats metrics for the audit run. |
3838
| `--default-create-vap-binding-for-constraints` | `true` | (beta) Create VAPBinding resource for constraint of the template containing VAP-style CEL source. Allowed values are false: do not create Validating Admission Policy Binding, true: create Validating Admission Policy Binding. |
3939
| `--default-create-vap-for-templates` | `true` | (beta) Create VAP resource for template containing VAP-style CEL source. Allowed values are false: do not create Validating Admission Policy unless generateVAP: true is set on constraint template explicitly, true: create Validating Admission Policy unless generateVAP: false is set on constraint template explicitly. |
40+
| `--default-failure-policy` | `Fail` | (beta) Failure policy to use when a K8sNativeValidation source omits failurePolicy. Allowed values are Fail or Ignore. |
4041
| `--default-wait-for-vapb-generation` | `30` | (beta) Wait time in seconds before generating a ValidatingAdmissionPolicyBinding after a constraint CRD is created. |
4142
| `--debug-use-fake-pod` | `false` | Use a fake pod name so the Gatekeeper executable can be run outside of Kubernetes. |
4243
| `--enable-violation-export` | `false` | (alpha) Enable exporting violations to external systems. |

website/versioned_docs/version-v3.22.x/validating-admission-policy.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,8 @@ For some policies, you may want admission requests to be handled by the K8s Vali
120120
The K8s Validating Admission Controller requires both the Validating Admission Policy (VAP) and Validating Admission Policy Binding (VAPB) resources to exist to enforce a policy. Gatekeeper can be configured to generate both of these resources. To generate VAP Bindings for all Constraints, ensure the Gatekeeper
121121
`--default-create-vap-binding-for-constraints` flag is set to `true`. To generate VAP as part of all Constraint Templates with the VAP CEL engine `K8sNativeValidation`, ensure the Gatekeeper `--default-create-vap-for-templates=true` flag is set to `true`. By default both flags are set to `true` now that the feature is in beta.
122122

123+
If a K8sNativeValidation source omits `failurePolicy`, Gatekeeper uses `--default-failure-policy`, which defaults to `Fail`, for both Gatekeeper's CEL evaluation and generated VAP resources.
124+
123125
To override the `--default-create-vap-for-templates` flag's behavior for a constraint template, set `generateVAP` to `true` explicitly under the K8sNativeValidation engine's `source` in the constraint template.
124126

125127
```yaml

0 commit comments

Comments
 (0)