1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-15 12:17:56 +00:00

feat: don't rely on events unicity in resource counters (#10613)

Signed-off-by: Charles-Edouard Brétéché <charles.edouard@nirmata.com>
This commit is contained in:
Charles-Edouard Brétéché 2024-07-05 12:33:45 +02:00 committed by GitHub
parent 13fc9881d5
commit ff192f3dc3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -2,28 +2,50 @@ package main
import ( import (
"context" "context"
"sync"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1" reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
watchtools "github.com/kyverno/kyverno/cmd/kyverno/watch" watchtools "github.com/kyverno/kyverno/cmd/kyverno/watch"
"github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces" "github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch" "k8s.io/apimachinery/pkg/watch"
metadataclient "k8s.io/client-go/metadata" metadataclient "k8s.io/client-go/metadata"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
) )
type resourceUIDGetter interface {
GetUID() types.UID
}
type Counter interface { type Counter interface {
Count() (int, bool) Count() (int, bool)
} }
type counter struct { type counter struct {
count int lock sync.RWMutex
entries sets.Set[types.UID]
retryWatcher *watchtools.RetryWatcher retryWatcher *watchtools.RetryWatcher
} }
func (c *counter) Record(uid types.UID) {
c.lock.Lock()
defer c.lock.Unlock()
c.entries.Insert(uid)
}
func (c *counter) Forget(uid types.UID) {
c.lock.Lock()
defer c.lock.Unlock()
c.entries.Delete(uid)
}
func (c *counter) Count() (int, bool) { func (c *counter) Count() (int, bool) {
return c.count, c.retryWatcher.IsRunning() c.lock.RLock()
defer c.lock.RUnlock()
return c.entries.Len(), c.retryWatcher.IsRunning()
} }
func StartResourceCounter(ctx context.Context, client metadataclient.Interface, gvr schema.GroupVersionResource, tweakListOptions internalinterfaces.TweakListOptionsFunc) (*counter, error) { func StartResourceCounter(ctx context.Context, client metadataclient.Interface, gvr schema.GroupVersionResource, tweakListOptions internalinterfaces.TweakListOptionsFunc) (*counter, error) {
@ -43,17 +65,26 @@ func StartResourceCounter(ctx context.Context, client metadataclient.Interface,
if err != nil { if err != nil {
return nil, err return nil, err
} }
entries := sets.New[types.UID]()
for _, entry := range objs.Items {
entries.Insert(entry.GetUID())
}
w := &counter{ w := &counter{
count: len(objs.Items), entries: entries,
retryWatcher: watchInterface, retryWatcher: watchInterface,
} }
go func() { go func() {
for event := range watchInterface.ResultChan() { for event := range watchInterface.ResultChan() {
switch event.Type { getter, ok := event.Object.(resourceUIDGetter)
case watch.Added: if ok {
w.count = w.count + 1 switch event.Type {
case watch.Deleted: case watch.Added:
w.count = w.count - 1 w.Record(getter.GetUID())
case watch.Modified:
w.Record(getter.GetUID())
case watch.Deleted:
w.Forget(getter.GetUID())
}
} }
} }
}() }()