1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2024-12-15 17:51:20 +00:00
kyverno/pkg/checker/status.go
2019-11-13 11:55:16 -08:00

130 lines
3.8 KiB
Go

package checker
import (
"fmt"
"strconv"
"github.com/golang/glog"
dclient "github.com/nirmata/kyverno/pkg/dclient"
"github.com/nirmata/kyverno/pkg/event"
)
const deployName string = "kyverno"
const deployNamespace string = "kyverno"
const annCounter string = "kyverno.io/generationCounter"
const annWebhookStats string = "kyverno.io/webhookActive"
//StatusInterface provides api to update webhook active annotations on kyverno deployments
type StatusInterface interface {
// Increments generation counter annotation
IncrementAnnotation() error
// update annotation to inform webhook is active
SuccessStatus() error
// update annotation to inform webhook is inactive
FailedStatus() error
}
//StatusControl controls the webhook status
type StatusControl struct {
client *dclient.Client
eventGen event.Interface
}
//SuccessStatus ...
func (vc StatusControl) SuccessStatus() error {
return vc.setStatus("true")
}
//FailedStatus ...
func (vc StatusControl) FailedStatus() error {
return vc.setStatus("false")
}
// NewVerifyControl ...
func NewVerifyControl(client *dclient.Client, eventGen event.Interface) *StatusControl {
return &StatusControl{
client: client,
eventGen: eventGen,
}
}
func (vc StatusControl) setStatus(status string) error {
glog.Infof("setting deployment %s in ns %s annotation %s to %s", deployName, deployNamespace, annWebhookStats, status)
var ann map[string]string
var err error
deploy, err := vc.client.GetResource("Deployment", deployNamespace, deployName)
if err != nil {
glog.V(4).Infof("failed to get deployment %s in namespace %s: %v", deployName, deployNamespace, err)
return err
}
ann = deploy.GetAnnotations()
if ann == nil {
ann = map[string]string{}
ann[annWebhookStats] = status
}
webhookAction, ok := ann[annWebhookStats]
if ok {
// annotatiaion is present
if webhookAction == status {
glog.V(4).Infof("annotation %s already set to '%s'", annWebhookStats, status)
return nil
}
}
// set the status
ann[annWebhookStats] = status
deploy.SetAnnotations(ann)
// update counter
_, err = vc.client.UpdateResource("Deployment", deployNamespace, deploy, false)
if err != nil {
glog.V(4).Infof("failed to update annotation %s for deployment %s in namespace %s: %v", annWebhookStats, deployName, deployNamespace, err)
return err
}
// create event on kyverno deployment
createStatusUpdateEvent(status, vc.eventGen)
return nil
}
func createStatusUpdateEvent(status string, eventGen event.Interface) {
e := event.Info{}
e.Kind = "Deployment"
e.Namespace = "kyverno"
e.Name = "kyverno"
e.Reason = "Update"
e.Message = fmt.Sprintf("admission control webhook active status changed to %s", status)
eventGen.Add(e)
}
//IncrementAnnotation ...
func (vc StatusControl) IncrementAnnotation() error {
glog.Infof("setting deployment %s in ns %s annotation %s", deployName, deployNamespace, annCounter)
var ann map[string]string
var err error
deploy, err := vc.client.GetResource("Deployment", deployNamespace, deployName)
if err != nil {
glog.V(4).Infof("failed to get deployment %s in namespace %s: %v", deployName, deployNamespace, err)
return err
}
ann = deploy.GetAnnotations()
if ann == nil {
ann = map[string]string{}
ann[annCounter] = "0"
}
counter, err := strconv.Atoi(ann[annCounter])
if err != nil {
glog.V(4).Infof("failed to parse string: %v", err)
return err
}
// increment counter
counter++
ann[annCounter] = strconv.Itoa(counter)
glog.Infof("incrementing annotation %s counter to %d", annCounter, counter)
deploy.SetAnnotations(ann)
// update counter
_, err = vc.client.UpdateResource("Deployment", deployNamespace, deploy, false)
if err != nil {
glog.V(4).Infof("failed to update annotation %s for deployment %s in namespace %s: %v", annCounter, deployName, deployNamespace, err)
return err
}
return nil
}