mirror of
https://github.com/kyverno/kyverno.git
synced 2024-12-14 11:57:48 +00:00
972be16ad3
* refactor: use typed informers and add tombstone support to webhookconfig Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> * refactor: remove unstructured usage from webhookconfig Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
134 lines
3.5 KiB
Go
134 lines
3.5 KiB
Go
package webhookconfig
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
"github.com/kyverno/kyverno/pkg/config"
|
|
"github.com/kyverno/kyverno/pkg/event"
|
|
"github.com/pkg/errors"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
coordinationv1 "k8s.io/client-go/kubernetes/typed/coordination/v1"
|
|
)
|
|
|
|
const (
|
|
leaseName string = "kyverno"
|
|
annWebhookStatus string = "kyverno.io/webhookActive"
|
|
annLastRequestTime string = "kyverno.io/last-request-time"
|
|
)
|
|
|
|
//statusControl controls the webhook status
|
|
type statusControl struct {
|
|
eventGen event.Interface
|
|
log logr.Logger
|
|
leaseClient coordinationv1.LeaseInterface
|
|
}
|
|
|
|
//success ...
|
|
func (vc statusControl) success() error {
|
|
return vc.setStatus("true")
|
|
}
|
|
|
|
//failure ...
|
|
func (vc statusControl) failure() error {
|
|
return vc.setStatus("false")
|
|
}
|
|
|
|
// NewStatusControl creates a new webhook status control
|
|
func newStatusControl(leaseClient coordinationv1.LeaseInterface, eventGen event.Interface, log logr.Logger) *statusControl {
|
|
return &statusControl{
|
|
eventGen: eventGen,
|
|
log: log,
|
|
leaseClient: leaseClient,
|
|
}
|
|
}
|
|
|
|
func (vc statusControl) setStatus(status string) error {
|
|
logger := vc.log.WithValues("name", leaseName, "namespace", config.KyvernoNamespace)
|
|
var ann map[string]string
|
|
var err error
|
|
|
|
lease, err := vc.leaseClient.Get(context.TODO(), "kyverno", metav1.GetOptions{})
|
|
if err != nil {
|
|
vc.log.WithName("UpdateLastRequestTimestmap").Error(err, "Lease 'kyverno' not found. Starting clean-up...")
|
|
return err
|
|
}
|
|
|
|
ann = lease.GetAnnotations()
|
|
if ann == nil {
|
|
ann = map[string]string{}
|
|
ann[annWebhookStatus] = status
|
|
}
|
|
|
|
leaseStatus, ok := ann[annWebhookStatus]
|
|
if ok {
|
|
if leaseStatus == status {
|
|
logger.V(4).Info(fmt.Sprintf("annotation %s already set to '%s'", annWebhookStatus, status))
|
|
return nil
|
|
}
|
|
}
|
|
|
|
ann[annWebhookStatus] = status
|
|
lease.SetAnnotations(ann)
|
|
|
|
_, err = vc.leaseClient.Update(context.TODO(), lease, metav1.UpdateOptions{})
|
|
if err != nil {
|
|
return errors.Wrapf(err, "key %s, val %s", annWebhookStatus, status)
|
|
}
|
|
|
|
logger.Info("updated lease annotation", "key", annWebhookStatus, "val", status)
|
|
|
|
// create event on kyverno deployment
|
|
createStatusUpdateEvent(status, vc.eventGen)
|
|
return nil
|
|
}
|
|
|
|
func createStatusUpdateEvent(status string, eventGen event.Interface) {
|
|
e := event.Info{}
|
|
e.Kind = "Lease"
|
|
e.Namespace = config.KyvernoNamespace
|
|
e.Name = leaseName
|
|
e.Reason = "Update"
|
|
e.Message = fmt.Sprintf("admission control webhook active status changed to %s", status)
|
|
eventGen.Add(e)
|
|
}
|
|
|
|
func (vc statusControl) UpdateLastRequestTimestmap(new time.Time) error {
|
|
|
|
lease, err := vc.leaseClient.Get(context.TODO(), leaseName, metav1.GetOptions{})
|
|
if err != nil {
|
|
vc.log.WithName("UpdateLastRequestTimestmap").Error(err, "Lease 'kyverno' not found. Starting clean-up...")
|
|
return err
|
|
}
|
|
|
|
//add label to lease
|
|
label := lease.GetLabels()
|
|
if len(label) == 0 {
|
|
label = make(map[string]string)
|
|
label["app.kubernetes.io/name"] = "kyverno"
|
|
}
|
|
lease.SetLabels(label)
|
|
|
|
annotation := lease.GetAnnotations()
|
|
if annotation == nil {
|
|
annotation = make(map[string]string)
|
|
}
|
|
|
|
t, err := new.MarshalText()
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to marshal timestamp")
|
|
}
|
|
|
|
annotation[annLastRequestTime] = string(t)
|
|
lease.SetAnnotations(annotation)
|
|
|
|
//update annotations in lease
|
|
_, err = vc.leaseClient.Update(context.TODO(), lease, metav1.UpdateOptions{})
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to update annotation %s for deployment %s in namespace %s", annLastRequestTime, lease.GetName(), lease.GetNamespace())
|
|
}
|
|
|
|
return nil
|
|
}
|