Skip to content

Commit

Permalink
feat: sort policies in alphabetical order before executing (#254)
Browse files Browse the repository at this point in the history
Signed-off-by: Vishal Choudhary <[email protected]>
Signed-off-by: Vishal Choudhary <[email protected]>
Co-authored-by: Charles-Edouard Brétéché <[email protected]>
  • Loading branch information
vishal-chdhry and eddycharly authored Dec 17, 2024
1 parent 87d2f3b commit a8eed56
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ require (
github.com/stoewer/go-strcase v1.3.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect
golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c
golang.org/x/net v0.30.0 // indirect
golang.org/x/oauth2 v0.23.0 // indirect
golang.org/x/sys v0.26.0 // indirect
Expand Down
55 changes: 39 additions & 16 deletions pkg/policy/provider.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
package policy

import (
"cmp"
"context"
"fmt"
"slices"
"sync"

"github.com/kyverno/kyverno-envoy-plugin/apis/v1alpha1"
"golang.org/x/exp/maps"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
)
Expand All @@ -25,28 +27,54 @@ func NewKubeProvider(mgr ctrl.Manager, compiler Compiler) (Provider, error) {
}

type policyReconciler struct {
client client.Client
compiler Compiler
lock *sync.RWMutex
policies map[types.NamespacedName]PolicyFunc
client client.Client
compiler Compiler
lock *sync.Mutex
policies map[string]PolicyFunc
sortPolicies func() []PolicyFunc
}

func newPolicyReconciler(client client.Client, compiler Compiler) *policyReconciler {
return &policyReconciler{
client: client,
compiler: compiler,
lock: &sync.RWMutex{},
policies: map[types.NamespacedName]PolicyFunc{},
lock: &sync.Mutex{},
policies: map[string]PolicyFunc{},
sortPolicies: func() []PolicyFunc {
return nil
},
}
}

func mapToSortedSlice[K cmp.Ordered, V any](in map[K]V) []V {
if in == nil {
return nil
}
out := make([]V, 0, len(in))
keys := maps.Keys(in)
slices.Sort(keys)
for _, key := range keys {
out = append(out, in[key])
}
return out
}

func (r *policyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var policy v1alpha1.AuthorizationPolicy
// Reset the sorted func on every reconcile so the policies get resorted in next call
resetSortPolicies := func() {
r.sortPolicies = sync.OnceValue(func() []PolicyFunc {
r.lock.Lock()
defer r.lock.Unlock()
return mapToSortedSlice(r.policies)
})
}
err := r.client.Get(ctx, req.NamespacedName, &policy)
if errors.IsNotFound(err) {
r.lock.Lock()
defer r.lock.Unlock()
delete(r.policies, req.NamespacedName)
defer resetSortPolicies()
delete(r.policies, req.NamespacedName.String())
return ctrl.Result{}, nil
}
if err != nil {
Expand All @@ -60,16 +88,11 @@ func (r *policyReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}
r.lock.Lock()
defer r.lock.Unlock()
r.policies[req.NamespacedName] = compiled
r.policies[req.NamespacedName.String()] = compiled
resetSortPolicies()
return ctrl.Result{}, nil
}

func (r *policyReconciler) CompiledPolicies(ctx context.Context) ([]PolicyFunc, error) {
r.lock.RLock()
defer r.lock.RUnlock()
out := make([]PolicyFunc, 0, len(r.policies))
for _, policy := range r.policies {
out = append(out, policy)
}
return out, nil
return slices.Clone(r.sortPolicies()), nil
}

0 comments on commit a8eed56

Please sign in to comment.