1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 16:06:56 +00:00
kyverno/pkg/webhookconfig/status.go
Mritunjay Kumar Sharma e303dddf86
adds lease objects for storing last-request-time and set-status annotations in deployment (#3447)
* funcs to patch last request time and status

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* instead of patch, updating status

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* added lease object appraoch

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* cleanup

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* attempt to solve panic issue

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* fixes lease updates for both annotations

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* minor cleanups in log messages

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* clean up

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* add object selector

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>

* fixed leases and object selector

Signed-off-by: Mritunjay Sharma <mritunjaysharma394@gmail.com>
2022-03-25 21:42:01 +08:00

136 lines
3.6 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"
)
var leaseName string = "kyverno"
var leaseNamespace string = config.KyvernoNamespace
const (
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", leaseNamespace)
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 = leaseNamespace
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
}