mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-06 07:57:07 +00:00
* Fix Dev setup * webhook monitor - start webhook monitor in main process Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add leaderelection Signed-off-by: Jim Bugwadia <jim@nirmata.com> * - add isLeader; - update to use configmap lock Signed-off-by: Shuting Zhao <shutting06@gmail.com> * - add initialization method - add methods to get attributes Signed-off-by: Shuting Zhao <shutting06@gmail.com> * address comments Signed-off-by: Shuting Zhao <shutting06@gmail.com> * remove newContext in runLeaderElection Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add leader election to GenerateController Signed-off-by: Jim Bugwadia <jim@nirmata.com> * skip processing for non-leaders Signed-off-by: Jim Bugwadia <jim@nirmata.com> * skip processing for non-leaders Signed-off-by: Jim Bugwadia <jim@nirmata.com> * add leader election to generate cleanup controller Signed-off-by: Jim Bugwadia <jim@nirmata.com> * Gracefully drain request * HA - Webhook Register / Webhook Monitor / Certificate Renewer (#1920) * enable leader election for webhook register Signed-off-by: Shuting Zhao <shutting06@gmail.com> * extract certManager to its own process Signed-off-by: Shuting Zhao <shutting06@gmail.com> * leader election for cert manager Signed-off-by: Shuting Zhao <shutting06@gmail.com> * certManager - init certs by the leader Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add leader election to webhook monitor Signed-off-by: Shuting Zhao <shutting06@gmail.com> * update log message Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add leader election to policy controller Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add leader election to policy report controller Signed-off-by: Shuting Zhao <shutting06@gmail.com> * rebuild leader election config Signed-off-by: Shuting Zhao <shutting06@gmail.com> * start informers in leaderelection Signed-off-by: Shuting Zhao <shutting06@gmail.com> * start policy informers in main Signed-off-by: Shuting Zhao <shutting06@gmail.com> * enable leader election in main Signed-off-by: Shuting Zhao <shutting06@gmail.com> * move eventHandler to the leader election start method Signed-off-by: Shuting Zhao <shutting06@gmail.com> * address reviewdog comments Signed-off-by: Shuting Zhao <shutting06@gmail.com> * add clusterrole leaderelection Signed-off-by: Shuting Zhao <shutting06@gmail.com> * fixed generate flow (#1936) Signed-off-by: NoSkillGirl <singhpooja240393@gmail.com> * - init separate kubeclient for leaderelection - fix webhook monitor Signed-off-by: Shuting Zhao <shutting06@gmail.com> * address reviewdog comments Signed-off-by: Shuting Zhao <shutting06@gmail.com> * cleanup Kyverno managed resources on stopLeading Signed-off-by: Shuting Zhao <shutting06@gmail.com> * tag v1.4.0-beta1 Signed-off-by: Shuting Zhao <shutting06@gmail.com> * fix cleanup process on Kyverno stops Signed-off-by: Shuting Zhao <shutting06@gmail.com> * bump kind to 0.11.0, k8s v1.21 (#1980) Co-authored-by: vyankatesh <vyankatesh@neualto.com> Co-authored-by: vyankatesh <vyankateshkd@gmail.com> Co-authored-by: Jim Bugwadia <jim@nirmata.com> Co-authored-by: Pooja Singh <36136335+NoSkillGirl@users.noreply.github.com>
171 lines
4.6 KiB
Go
171 lines
4.6 KiB
Go
package webhookconfig
|
|
|
|
import (
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/go-logr/logr"
|
|
"github.com/kyverno/kyverno/pkg/config"
|
|
"github.com/kyverno/kyverno/pkg/event"
|
|
"github.com/pkg/errors"
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
)
|
|
|
|
var deployName string = config.KyvernoDeploymentName
|
|
var deployNamespace string = config.KyvernoNamespace
|
|
|
|
const (
|
|
annCounter string = "kyverno.io/generationCounter"
|
|
annWebhookStatus string = "kyverno.io/webhookActive"
|
|
annLastRequestTime string = "kyverno.io/last-request-time"
|
|
)
|
|
|
|
//statusControl controls the webhook status
|
|
type statusControl struct {
|
|
register *Register
|
|
eventGen event.Interface
|
|
log logr.Logger
|
|
}
|
|
|
|
//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(register *Register, eventGen event.Interface, log logr.Logger) *statusControl {
|
|
return &statusControl{
|
|
register: register,
|
|
eventGen: eventGen,
|
|
log: log,
|
|
}
|
|
}
|
|
|
|
func (vc statusControl) setStatus(status string) error {
|
|
logger := vc.log.WithValues("name", deployName, "namespace", deployNamespace)
|
|
var ann map[string]string
|
|
var err error
|
|
deploy, err := vc.register.client.GetResource("", "Deployment", deployNamespace, deployName)
|
|
if err != nil {
|
|
logger.Error(err, "failed to get deployment")
|
|
return err
|
|
}
|
|
|
|
ann = deploy.GetAnnotations()
|
|
if ann == nil {
|
|
ann = map[string]string{}
|
|
ann[annWebhookStatus] = status
|
|
}
|
|
|
|
deployStatus, ok := ann[annWebhookStatus]
|
|
if ok {
|
|
if deployStatus == status {
|
|
logger.V(4).Info(fmt.Sprintf("annotation %s already set to '%s'", annWebhookStatus, status))
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// set the status
|
|
logger.Info("updating deployment annotation", "key", annWebhookStatus, "val", status)
|
|
ann[annWebhookStatus] = status
|
|
deploy.SetAnnotations(ann)
|
|
|
|
// update counter
|
|
_, err = vc.register.client.UpdateResource("", "Deployment", deployNamespace, deploy, false)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "key %s, val %s", annWebhookStatus, status)
|
|
}
|
|
|
|
// 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 = deployNamespace
|
|
e.Name = deployName
|
|
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 {
|
|
logger := vc.log
|
|
var ann map[string]string
|
|
var err error
|
|
deploy, err := vc.register.client.GetResource("", "Deployment", deployNamespace, deployName)
|
|
if err != nil {
|
|
logger.Error(err, "failed to find Kyverno", "deployment", deployName, "namespace", deployNamespace)
|
|
return err
|
|
}
|
|
|
|
ann = deploy.GetAnnotations()
|
|
if ann == nil {
|
|
ann = map[string]string{}
|
|
}
|
|
|
|
if ann[annCounter] == "" {
|
|
ann[annCounter] = "0"
|
|
}
|
|
|
|
counter, err := strconv.Atoi(ann[annCounter])
|
|
if err != nil {
|
|
logger.Error(err, "Failed to parse string", "name", annCounter, "value", ann[annCounter])
|
|
return err
|
|
}
|
|
|
|
// increment counter
|
|
counter++
|
|
ann[annCounter] = strconv.Itoa(counter)
|
|
|
|
logger.V(3).Info("updating webhook test annotation", "key", annCounter, "value", counter, "deployment", deployName, "namespace", deployNamespace)
|
|
deploy.SetAnnotations(ann)
|
|
|
|
// update counter
|
|
_, err = vc.register.client.UpdateResource("", "Deployment", deployNamespace, deploy, false)
|
|
if err != nil {
|
|
logger.Error(err, fmt.Sprintf("failed to update annotation %s for deployment %s in namespace %s", annCounter, deployName, deployNamespace))
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (vc statusControl) UpdateLastRequestTimestmap(new time.Time) error {
|
|
_, deploy, err := vc.register.GetKubePolicyDeployment()
|
|
if err != nil {
|
|
return errors.Wrap(err, "unable to get Kyverno deployment")
|
|
}
|
|
|
|
annotation, ok, err := unstructured.NestedStringMap(deploy.UnstructuredContent(), "metadata", "annotations")
|
|
if err != nil {
|
|
return errors.Wrap(err, "unable to get annotation")
|
|
}
|
|
|
|
if !ok {
|
|
annotation = make(map[string]string)
|
|
}
|
|
|
|
t, err := new.MarshalText()
|
|
if err != nil {
|
|
return errors.Wrap(err, "failed to marshal timestamp")
|
|
}
|
|
|
|
annotation[annLastRequestTime] = string(t)
|
|
deploy.SetAnnotations(annotation)
|
|
_, err = vc.register.client.UpdateResource("", "Deployment", deploy.GetNamespace(), deploy, false)
|
|
if err != nil {
|
|
return errors.Wrapf(err, "failed to update annotation %s for deployment %s in namespace %s", annLastRequestTime, deploy.GetName(), deploy.GetNamespace())
|
|
}
|
|
|
|
return nil
|
|
}
|