2020-03-07 12:53:37 +05:30
|
|
|
package policystatus
|
2020-02-25 20:55:07 +05:30
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/golang/glog"
|
|
|
|
|
|
|
|
"k8s.io/apimachinery/pkg/util/wait"
|
|
|
|
|
|
|
|
"github.com/nirmata/kyverno/pkg/client/clientset/versioned"
|
|
|
|
|
|
|
|
v1 "github.com/nirmata/kyverno/pkg/api/kyverno/v1"
|
|
|
|
)
|
|
|
|
|
2020-02-29 22:39:27 +05:30
|
|
|
type statusUpdater interface {
|
2020-03-04 15:45:20 +05:30
|
|
|
PolicyName() string
|
|
|
|
UpdateStatus(status v1.PolicyStatus) v1.PolicyStatus
|
2020-02-29 22:39:27 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
type policyStore interface {
|
|
|
|
Get(policyName string) (*v1.ClusterPolicy, error)
|
|
|
|
}
|
|
|
|
|
2020-03-07 12:53:37 +05:30
|
|
|
type Listener chan statusUpdater
|
|
|
|
|
|
|
|
func (l Listener) Send(s statusUpdater) {
|
|
|
|
l <- s
|
|
|
|
}
|
|
|
|
|
2020-02-25 20:55:07 +05:30
|
|
|
type Sync struct {
|
2020-03-04 15:45:20 +05:30
|
|
|
cache *cache
|
2020-03-07 12:53:37 +05:30
|
|
|
Listener Listener
|
2020-02-25 20:55:07 +05:30
|
|
|
client *versioned.Clientset
|
2020-03-04 15:45:20 +05:30
|
|
|
policyStore policyStore
|
2020-02-25 20:55:07 +05:30
|
|
|
}
|
|
|
|
|
|
|
|
type cache struct {
|
2020-03-04 15:45:20 +05:30
|
|
|
mutex sync.RWMutex
|
|
|
|
data map[string]v1.PolicyStatus
|
2020-02-25 20:55:07 +05:30
|
|
|
}
|
|
|
|
|
2020-02-29 22:39:27 +05:30
|
|
|
func NewSync(c *versioned.Clientset, p policyStore) *Sync {
|
2020-02-25 20:55:07 +05:30
|
|
|
return &Sync{
|
2020-03-04 15:45:20 +05:30
|
|
|
cache: &cache{
|
|
|
|
mutex: sync.RWMutex{},
|
|
|
|
data: make(map[string]v1.PolicyStatus),
|
2020-02-25 20:55:07 +05:30
|
|
|
},
|
|
|
|
client: c,
|
2020-03-04 15:45:20 +05:30
|
|
|
policyStore: p,
|
2020-03-04 13:35:49 +05:30
|
|
|
Listener: make(chan statusUpdater, 20),
|
2020-02-25 20:55:07 +05:30
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-29 17:19:00 +05:30
|
|
|
func (s *Sync) Run(workers int, stopCh <-chan struct{}) {
|
2020-02-25 21:07:00 +05:30
|
|
|
for i := 0; i < workers; i++ {
|
2020-02-29 17:19:00 +05:30
|
|
|
go s.updateStatusCache(stopCh)
|
2020-02-25 21:07:00 +05:30
|
|
|
}
|
|
|
|
|
2020-02-29 17:19:00 +05:30
|
|
|
wait.Until(s.updatePolicyStatus, 2*time.Second, stopCh)
|
|
|
|
<-stopCh
|
2020-02-25 20:55:07 +05:30
|
|
|
}
|
|
|
|
|
2020-02-29 17:19:00 +05:30
|
|
|
func (s *Sync) updateStatusCache(stopCh <-chan struct{}) {
|
2020-02-25 20:55:07 +05:30
|
|
|
for {
|
|
|
|
select {
|
2020-02-29 22:39:27 +05:30
|
|
|
case statusUpdater := <-s.Listener:
|
2020-03-04 15:45:20 +05:30
|
|
|
s.cache.mutex.Lock()
|
|
|
|
|
|
|
|
status, exist := s.cache.data[statusUpdater.PolicyName()]
|
|
|
|
if !exist {
|
|
|
|
policy, _ := s.policyStore.Get(statusUpdater.PolicyName())
|
|
|
|
if policy != nil {
|
|
|
|
status = policy.Status
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
s.cache.data[statusUpdater.PolicyName()] = statusUpdater.UpdateStatus(status)
|
|
|
|
|
|
|
|
s.cache.mutex.Unlock()
|
2020-02-29 17:19:00 +05:30
|
|
|
case <-stopCh:
|
2020-02-25 20:55:07 +05:30
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (s *Sync) updatePolicyStatus() {
|
2020-03-04 15:45:20 +05:30
|
|
|
s.cache.mutex.Lock()
|
|
|
|
var nameToStatus = make(map[string]v1.PolicyStatus, len(s.cache.data))
|
|
|
|
for k, v := range s.cache.data {
|
2020-02-25 20:55:07 +05:30
|
|
|
nameToStatus[k] = v
|
|
|
|
}
|
2020-03-04 15:45:20 +05:30
|
|
|
s.cache.mutex.Unlock()
|
2020-02-25 20:55:07 +05:30
|
|
|
|
|
|
|
for policyName, status := range nameToStatus {
|
2020-03-04 15:45:20 +05:30
|
|
|
policy, err := s.policyStore.Get(policyName)
|
2020-02-25 20:55:07 +05:30
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
policy.Status = status
|
|
|
|
_, err = s.client.KyvernoV1().ClusterPolicies().UpdateStatus(policy)
|
|
|
|
if err != nil {
|
2020-03-04 15:45:20 +05:30
|
|
|
s.cache.mutex.Lock()
|
|
|
|
delete(s.cache.data, policyName)
|
|
|
|
s.cache.mutex.Unlock()
|
2020-02-25 20:55:07 +05:30
|
|
|
glog.V(4).Info(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|