1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-06 07:57:07 +00:00
kyverno/pkg/webhookconfig/status.go
shuting e9a972a362
feat: HA (#1931)
* 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>
2021-06-08 12:37:19 -07:00

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
}