1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-14 11:57:48 +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 (
"context"
"sync"
reportsv1 "github.com/kyverno/kyverno/api/reports/v1"
watchtools "github.com/kyverno/kyverno/cmd/kyverno/watch"
"github.com/kyverno/kyverno/pkg/client/informers/externalversions/internalinterfaces"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/watch"
metadataclient "k8s.io/client-go/metadata"
"k8s.io/client-go/tools/cache"
)
type resourceUIDGetter interface {
GetUID() types.UID
}
type Counter interface {
Count() (int, bool)
}
type counter struct {
count int
lock sync.RWMutex
entries sets.Set[types.UID]
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) {
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) {
@ -43,17 +65,26 @@ func StartResourceCounter(ctx context.Context, client metadataclient.Interface,
if err != nil {
return nil, err
}
entries := sets.New[types.UID]()
for _, entry := range objs.Items {
entries.Insert(entry.GetUID())
}
w := &counter{
count: len(objs.Items),
entries: entries,
retryWatcher: watchInterface,
}
go func() {
for event := range watchInterface.ResultChan() {
switch event.Type {
case watch.Added:
w.count = w.count + 1
case watch.Deleted:
w.count = w.count - 1
getter, ok := event.Object.(resourceUIDGetter)
if ok {
switch event.Type {
case watch.Added:
w.Record(getter.GetUID())
case watch.Modified:
w.Record(getter.GetUID())
case watch.Deleted:
w.Forget(getter.GetUID())
}
}
}
}()