Skip to content

Commit 8b5048a

Browse files
committed
address review comments
Signed-off-by: Rita Zhang <rita.z.zhang@gmail.com>
1 parent 766e1ff commit 8b5048a

File tree

9 files changed

+137
-171
lines changed

9 files changed

+137
-171
lines changed

.github/workflows/workflow.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ jobs:
138138
build_test:
139139
name: "Build and Test"
140140
runs-on: ubuntu-22.04
141-
timeout-minutes: 15
141+
timeout-minutes: 20
142142
strategy:
143143
matrix:
144144
KUBERNETES_VERSION: ["1.25.8", "1.26.3", "1.27.1", "1.28.0"]
@@ -177,7 +177,7 @@ jobs:
177177
IMG=gatekeeper-e2e:latest \
178178
USE_LOCAL_IMG=true
179179
180-
make test-e2e
180+
make test-e2e KUBERNETES_VERSION=${{ matrix.KUBERNETES_VERSION }}
181181
182182
- name: Save logs
183183
if: ${{ always() }}
@@ -263,7 +263,7 @@ jobs:
263263
build_test_generator_expansion:
264264
name: "[Generator Resource Expansion] Build and Test"
265265
runs-on: ubuntu-22.04
266-
timeout-minutes: 15
266+
timeout-minutes: 20
267267

268268
steps:
269269
- name: Harden Runner

pkg/controller/constraint/constraint_controller.go

Lines changed: 38 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,14 @@ import (
1919
"context"
2020
"errors"
2121
"fmt"
22+
"reflect"
2223
"strings"
2324
"sync"
2425

2526
"github.com/go-logr/logr"
2627
v1beta1 "github.com/open-policy-agent/frameworks/constraint/pkg/apis/templates/v1beta1"
2728
constraintclient "github.com/open-policy-agent/frameworks/constraint/pkg/client"
2829
"github.com/open-policy-agent/frameworks/constraint/pkg/client/drivers/k8scel/transform"
29-
"github.com/open-policy-agent/frameworks/constraint/pkg/core/constraints"
3030
constraintstatusv1beta1 "github.com/open-policy-agent/gatekeeper/v3/apis/status/v1beta1"
3131
"github.com/open-policy-agent/gatekeeper/v3/pkg/controller/config/process"
3232
"github.com/open-policy-agent/gatekeeper/v3/pkg/controller/constraintstatus"
@@ -36,7 +36,7 @@ import (
3636
"github.com/open-policy-agent/gatekeeper/v3/pkg/readiness"
3737
"github.com/open-policy-agent/gatekeeper/v3/pkg/util"
3838
"github.com/open-policy-agent/gatekeeper/v3/pkg/watch"
39-
admissionregistrationv1alpha1 "k8s.io/api/admissionregistration/v1alpha1"
39+
admissionregistrationv1beta1 "k8s.io/api/admissionregistration/v1beta1"
4040
corev1 "k8s.io/api/core/v1"
4141
apierrors "k8s.io/apimachinery/pkg/api/errors"
4242
"k8s.io/apimachinery/pkg/api/meta"
@@ -59,6 +59,8 @@ import (
5959

6060
var log = logf.Log.WithName("controller").WithValues(logging.Process, "constraint_controller")
6161

62+
var vapMux sync.RWMutex
63+
6264
var VapAPIEnabled *bool
6365

6466
var VapEnforcement VapFlagType
@@ -85,6 +87,15 @@ func (v *VapFlagType) Set(value string) error {
8587
return fmt.Errorf("invalid value %s. Allowed values are %s, %s, %s", value, VapFlagNone, VapFlagGatekeeperDefault, VapFlagVapDefault)
8688
}
8789

90+
// setting defaults when not set; required for unit test
91+
func (v *VapFlagType) SetDefaultIfEmpty() {
92+
if *v == "" {
93+
*v = VapFlagType(VapFlagGatekeeperDefault)
94+
VapAPIEnabled = new(bool)
95+
*VapAPIEnabled = true
96+
}
97+
}
98+
8899
type Adder struct {
89100
CFClient *constraintclient.Client
90101
ConstraintsCache *ConstraintsCache
@@ -145,9 +156,8 @@ type ConstraintsCache struct {
145156
}
146157

147158
type tags struct {
148-
enforcementAction util.EnforcementAction
149-
status metrics.Status
150-
generateVapBinding bool
159+
enforcementAction util.EnforcementAction
160+
status metrics.Status
151161
}
152162

153163
// newReconciler returns a new reconcile.Reconciler.
@@ -230,8 +240,7 @@ type ReconcileConstraint struct {
230240
// that would otherwise trigger a watch. The bool returns whether
231241
// the function was executed, which can be used to determine
232242
// whether the reconciler should infer the object has been deleted
233-
ifWatching func(schema.GroupVersionKind, func() error) (bool, error)
234-
generateVapBinding bool
243+
ifWatching func(schema.GroupVersionKind, func() error) (bool, error)
235244
}
236245

237246
// +kubebuilder:rbac:groups=constraints.gatekeeper.sh,resources=*,verbs=get;list;watch;create;update;patch;delete
@@ -263,6 +272,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
263272
return reconcile.Result{}, nil
264273
}
265274

275+
generateVapBinding := false
266276
deleted := false
267277
instance := &unstructured.Unstructured{}
268278
instance.SetGroupVersionKind(gvk)
@@ -294,7 +304,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
294304
}
295305
// unless constraint vap label is false, default to parent
296306
if useVap == "no" {
297-
r.generateVapBinding = false
307+
generateVapBinding = false
298308
} else {
299309
log.Info("constraint resource use-vap label is not no; will default to parent constraint template label")
300310
parentCTUseVap, err := r.getCTVapLabel(ctx, instance.GetKind())
@@ -303,8 +313,8 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
303313
return reconcile.Result{}, err
304314
}
305315
log.Info("constraint resource", "parentCTUseVap", parentCTUseVap)
306-
r.generateVapBinding = ShouldGenerateVap(parentCTUseVap)
307-
log.Info("constraint resource", "generateVapBinding", r.generateVapBinding)
316+
generateVapBinding = ShouldGenerateVap(parentCTUseVap)
317+
log.Info("constraint resource", "generateVapBinding", generateVapBinding)
308318
}
309319
constraintKey := strings.Join([]string{instance.GetKind(), instance.GetName()}, "/")
310320
enforcementAction, err := util.GetEnforcementAction(instance.Object)
@@ -329,23 +339,20 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
329339
status.Status.ConstraintUID = instance.GetUID()
330340
status.Status.ObservedGeneration = instance.GetGeneration()
331341
status.Status.Errors = nil
332-
cachedTags := r.constraintsCache.getTagsByConstraintKey(constraintKey)
333-
cachedGenerateVapBinding := cachedTags.generateVapBinding
334-
log.Info("constraint", "cachedGenerateVapBinding", cachedGenerateVapBinding)
335342

336-
if c, err := r.cfClient.GetConstraint(instance); err != nil || !constraints.SemanticEqual(instance, c) || r.generateVapBinding != cachedGenerateVapBinding {
343+
if c, err := r.cfClient.GetConstraint(instance); err != nil || !reflect.DeepEqual(instance, c) {
337344
// generate vapbinding resources
338-
if r.generateVapBinding && IsVapAPIEnabled() {
339-
currentVapBinding := &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}
345+
if generateVapBinding && IsVapAPIEnabled() {
346+
currentVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{}
340347
vapBindingName := fmt.Sprintf("gatekeeper-%s", instance.GetName())
341348
log.Info("check if vapbinding exists", "vapBindingName", vapBindingName)
342349
if err := r.reader.Get(ctx, types.NamespacedName{Name: vapBindingName}, currentVapBinding); err != nil {
343-
if !apierrors.IsNotFound(err) {
350+
if !apierrors.IsNotFound(err) && !strings.Contains(err.Error(), "failed to get API group resources") {
344351
return reconcile.Result{}, err
345352
}
346353
currentVapBinding = nil
347354
}
348-
newVapBinding := &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}
355+
newVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{}
349356
transformedVapBinding, err := transform.ConstraintToBinding(instance)
350357
if err != nil {
351358
status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()})
@@ -375,18 +382,7 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
375382
return reconcile.Result{}, err
376383
}
377384
} else {
378-
uc, err := runtime.DefaultUnstructuredConverter.ToUnstructured(currentVapBinding)
379-
if err != nil {
380-
log.Error(err, "error converting to unstructured")
381-
return reconcile.Result{}, err
382-
}
383-
un, err := runtime.DefaultUnstructuredConverter.ToUnstructured(newVapBinding)
384-
if err != nil {
385-
log.Error(err, "error converting to unstructured")
386-
return reconcile.Result{}, err
387-
}
388-
389-
if !constraints.SemanticEqual(&unstructured.Unstructured{Object: un}, &unstructured.Unstructured{Object: uc}) {
385+
if !reflect.DeepEqual(currentVapBinding, newVapBinding) {
390386
log.Info("updating vapbinding")
391387
if err := r.writer.Update(ctx, newVapBinding); err != nil {
392388
status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()})
@@ -400,12 +396,12 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
400396
}
401397
// do not generate vapbinding resources
402398
// remove if exists
403-
if !r.generateVapBinding && r.generateVapBinding != cachedGenerateVapBinding && IsVapAPIEnabled() {
404-
currentVapBinding := &admissionregistrationv1alpha1.ValidatingAdmissionPolicyBinding{}
399+
if !generateVapBinding && IsVapAPIEnabled() {
400+
currentVapBinding := &admissionregistrationv1beta1.ValidatingAdmissionPolicyBinding{}
405401
vapBindingName := fmt.Sprintf("gatekeeper-%s", instance.GetName())
406402
log.Info("check if vapbinding exists", "vapBindingName", vapBindingName)
407403
if err := r.reader.Get(ctx, types.NamespacedName{Name: vapBindingName}, currentVapBinding); err != nil {
408-
if !apierrors.IsNotFound(err) {
404+
if !apierrors.IsNotFound(err) && !strings.Contains(err.Error(), "failed to get API group resources") {
409405
return reconcile.Result{}, err
410406
}
411407
currentVapBinding = nil
@@ -423,9 +419,8 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
423419
}
424420
if err := r.cacheConstraint(ctx, instance); err != nil {
425421
r.constraintsCache.addConstraintKey(constraintKey, tags{
426-
enforcementAction: enforcementAction,
427-
status: metrics.ErrorStatus,
428-
generateVapBinding: r.generateVapBinding,
422+
enforcementAction: enforcementAction,
423+
status: metrics.ErrorStatus,
429424
})
430425
status.Status.Errors = append(status.Status.Errors, constraintstatusv1beta1.Error{Message: err.Error()})
431426
if err2 := r.writer.Update(ctx, status); err2 != nil {
@@ -444,9 +439,8 @@ func (r *ReconcileConstraint) Reconcile(ctx context.Context, request reconcile.R
444439

445440
// adding constraint to cache and sending metrics
446441
r.constraintsCache.addConstraintKey(constraintKey, tags{
447-
enforcementAction: enforcementAction,
448-
status: metrics.ActiveStatus,
449-
generateVapBinding: r.generateVapBinding,
442+
enforcementAction: enforcementAction,
443+
status: metrics.ActiveStatus,
450444
})
451445
reportMetrics = true
452446
} else {
@@ -586,9 +580,8 @@ func (c *ConstraintsCache) addConstraintKey(constraintKey string, t tags) {
586580
defer c.mux.Unlock()
587581

588582
c.cache[constraintKey] = tags{
589-
enforcementAction: t.enforcementAction,
590-
status: t.status,
591-
generateVapBinding: t.generateVapBinding,
583+
enforcementAction: t.enforcementAction,
584+
status: t.status,
592585
}
593586
}
594587

@@ -599,13 +592,6 @@ func (c *ConstraintsCache) deleteConstraintKey(constraintKey string) {
599592
delete(c.cache, constraintKey)
600593
}
601594

602-
func (c *ConstraintsCache) getTagsByConstraintKey(constraintKey string) tags {
603-
c.mux.Lock()
604-
defer c.mux.Unlock()
605-
606-
return c.cache[constraintKey]
607-
}
608-
609595
func (c *ConstraintsCache) reportTotalConstraints(ctx context.Context, reporter StatsReporter) {
610596
c.mux.RLock()
611597
defer c.mux.RUnlock()
@@ -640,6 +626,9 @@ func ShouldGenerateVap(useVapLabel string) bool {
640626
}
641627

642628
func IsVapAPIEnabled() bool {
629+
vapMux.Lock()
630+
defer vapMux.Unlock()
631+
643632
if VapAPIEnabled != nil {
644633
return *VapAPIEnabled
645634
}

0 commit comments

Comments
 (0)