package policyStatus import ( "sync" "time" "github.com/golang/glog" "github.com/nirmata/kyverno/pkg/policystore" "k8s.io/apimachinery/pkg/util/wait" "github.com/nirmata/kyverno/pkg/client/clientset/versioned" v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1" ) type Sync struct { cache *cache listener chan statusUpdater client *versioned.Clientset policyStore *policystore.PolicyStore } type cache struct { mutex sync.RWMutex data map[string]v1.PolicyStatus } func NewSync(c *versioned.Clientset, pms *policystore.PolicyStore) *Sync { return &Sync{ cache: &cache{ mutex: sync.RWMutex{}, data: make(map[string]v1.PolicyStatus), }, client: c, policyStore: pms, listener: make(chan statusUpdater), } } func (s *Sync) Run(workers int, stopCh <-chan struct{}) { for i := 0; i < workers; i++ { go s.updateStatusCache(stopCh) } wait.Until(s.updatePolicyStatus, 2*time.Second, stopCh) <-stopCh s.updatePolicyStatus() } func (s *Sync) updateStatusCache(stopCh <-chan struct{}) { for { select { case statusUpdater := <-s.listener: statusUpdater.updateStatus() case <-stopCh: return } } } func (s *Sync) updatePolicyStatus() { s.cache.mutex.Lock() var nameToStatus = make(map[string]v1.PolicyStatus, len(s.cache.data)) for k, v := range s.cache.data { nameToStatus[k] = v } s.cache.mutex.Unlock() for policyName, status := range nameToStatus { policy, err := s.policyStore.Get(policyName) if err != nil { continue } policy.Status = status _, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy) if err != nil { s.cache.mutex.Lock() delete(s.cache.data, policyName) s.cache.mutex.Unlock() glog.V(4).Info(err) } } }