1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-05 15:37:19 +00:00
kyverno/pkg/checker/checker.go
Shivkumar Dudhani ffd2179b03
538 (#587)
* initial commit

* background policy validation

* correct message

* skip non-background policy process for add/update

* add Generate Request CR

* generate Request Generator Initial

* test generate request CR generation

* initial commit gr generator

* generate controller initial framework

* add crd for generate request

* gr cleanup controller initial commit

* cleanup controller initial

* generate mid-commit

* generate rule processing

* create PV on generate error

* embed resource type

* testing phase 1- generate resources with variable substitution

* fix tests

* comment broken test #586

* add printer column for state

* return if existing resource for clone

* set resync time to 2 mins & remove resource version check in update handler for gr

* generate events for reporting

* fix logs

* cleanup

* CR fixes

* fix logs
2020-01-07 10:33:28 -08:00

118 lines
3.5 KiB
Go

package checker
import (
"sync"
"time"
"github.com/golang/glog"
kyvernolister "github.com/nirmata/kyverno/pkg/client/listers/kyverno/v1"
dclient "github.com/nirmata/kyverno/pkg/dclient"
"github.com/nirmata/kyverno/pkg/event"
"k8s.io/apimachinery/pkg/labels"
)
//MaxRetryCount defines the max deadline count
const (
MaxRetryCount int = 3
DefaultDeadline time.Duration = 60 * time.Second
DefaultResync time.Duration = 60 * time.Second
)
// LastReqTime
type LastReqTime struct {
t time.Time
mu sync.RWMutex
}
func (t *LastReqTime) Time() time.Time {
t.mu.RLock()
defer t.mu.RUnlock()
return t.t
}
func (t *LastReqTime) SetTime(tm time.Time) {
t.mu.Lock()
defer t.mu.Unlock()
t.t = tm
}
func NewLastReqTime() *LastReqTime {
return &LastReqTime{
t: time.Now(),
}
}
func checkIfPolicyWithMutateAndGenerateExists(pLister kyvernolister.ClusterPolicyLister) bool {
policies, err := pLister.ListResources(labels.NewSelector())
if err != nil {
glog.Error()
}
for _, policy := range policies {
if policy.HasMutateOrValidateOrGenerate() {
// as there exists one policy with mutate or validate rule
// so there must be a webhook configuration on resource
return true
}
}
return false
}
//Run runs the checker and verify the resource update
func (t *LastReqTime) Run(pLister kyvernolister.ClusterPolicyLister, eventGen event.Interface, client *dclient.Client, defaultResync time.Duration, deadline time.Duration, stopCh <-chan struct{}) {
glog.V(2).Infof("starting default resync for webhook checker with resync time %d nanoseconds", defaultResync)
maxDeadline := deadline * time.Duration(MaxRetryCount)
ticker := time.NewTicker(defaultResync)
var statuscontrol StatusInterface
/// interface to update and increment kyverno webhook status via annotations
statuscontrol = NewVerifyControl(client, eventGen)
// send the initial update status
if checkIfPolicyWithMutateAndGenerateExists(pLister) {
if err := statuscontrol.SuccessStatus(); err != nil {
glog.Error(err)
}
}
defer ticker.Stop()
// - has recieved request -> set webhookstatus as "True"
// - no requests recieved
// -> if greater than deadline, send update request
// -> if greater than maxDeadline, send failed status update
for {
select {
case <-ticker.C:
// if there are no policies then we dont have a webhook on resource.
// we indirectly check if the resource
if !checkIfPolicyWithMutateAndGenerateExists(pLister) {
continue
}
// get current time
timeDiff := time.Since(t.Time())
if timeDiff > maxDeadline {
glog.Infof("failed to recieve any request for more than %v ", maxDeadline)
glog.Info("Admission Control failing: Webhook is not recieving requests forwarded by api-server as per webhook configurations")
// set the status unavailable
if err := statuscontrol.FailedStatus(); err != nil {
glog.Error(err)
}
continue
}
if timeDiff > deadline {
glog.Info("Admission Control failing: Webhook is not recieving requests forwarded by api-server as per webhook configurations")
// send request to update the kyverno deployment
if err := statuscontrol.IncrementAnnotation(); err != nil {
glog.Error(err)
}
continue
}
// if the status was false before then we update it to true
// send request to update the kyverno deployment
if err := statuscontrol.SuccessStatus(); err != nil {
glog.Error(err)
}
case <-stopCh:
// handler termination signal
glog.V(2).Infof("stopping default resync for webhook checker")
return
}
}
}