1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

fix: mark ur retry on conflict (#3961)

Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-05-18 08:07:13 +02:00 committed by GitHub
parent 8026d5b09d
commit c988d519b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 46 deletions

View file

@ -284,7 +284,7 @@ func main() {
stopCh, stopCh,
log.Log.WithName("UpdateRequestGenerator")) log.Log.WithName("UpdateRequestGenerator"))
urc, err := background.NewController( urc := background.NewController(
kubeClient, kubeClient,
kyvernoClient, kyvernoClient,
dynamicClient, dynamicClient,
@ -296,10 +296,6 @@ func main() {
log.Log.WithName("BackgroundController"), log.Log.WithName("BackgroundController"),
configuration, configuration,
) )
if err != nil {
setupLog.Error(err, "Failed to create generate controller")
os.Exit(1)
}
grcc, err := generatecleanup.NewController( grcc, err := generatecleanup.NewController(
kubeClient, kubeClient,

View file

@ -15,7 +15,7 @@ import (
"k8s.io/client-go/util/retry" "k8s.io/client-go/util/retry"
) )
func (c *Controller) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error { func (c *Controller) processUR(ur *kyvernov1beta1.UpdateRequest) error {
switch ur.Spec.Type { switch ur.Spec.Type {
case kyvernov1beta1.Mutate: case kyvernov1beta1.Mutate:
ctrl, _ := mutate.NewMutateExistingController(c.kyvernoClient, c.client, ctrl, _ := mutate.NewMutateExistingController(c.kyvernoClient, c.client,
@ -31,29 +31,22 @@ func (c *Controller) ProcessUR(ur *kyvernov1beta1.UpdateRequest) error {
return nil return nil
} }
func (c *Controller) MarkUR(ur *kyvernov1beta1.UpdateRequest) (*kyvernov1beta1.UpdateRequest, bool, error) { func (c *Controller) markUR(ur *kyvernov1beta1.UpdateRequest) (*kyvernov1beta1.UpdateRequest, bool, error) {
handler := ur.Status.Handler ur = ur.DeepCopy()
if handler != "" { if ur.Status.Handler != "" {
if handler != config.KyvernoPodName() { return ur, ur.Status.Handler == config.KyvernoPodName(), nil
return ur, false, nil
} }
return ur, true, nil
}
handler = config.KyvernoPodName()
ur.Status.Handler = handler
var updateRequest *kyvernov1beta1.UpdateRequest
err := retry.RetryOnConflict(common.DefaultRetry, func() error { err := retry.RetryOnConflict(common.DefaultRetry, func() error {
var retryError error var retryError error
updateRequest, retryError = c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{}) ur.Status.Handler = config.KyvernoPodName()
ur, retryError = c.kyvernoClient.KyvernoV1beta1().UpdateRequests(config.KyvernoNamespace()).UpdateStatus(context.TODO(), ur, metav1.UpdateOptions{})
return retryError return retryError
}) })
return ur, true, err
return updateRequest, true, err
} }
func (c *Controller) UnmarkUR(ur *kyvernov1beta1.UpdateRequest) error { func (c *Controller) unmarkUR(ur *kyvernov1beta1.UpdateRequest) error {
if _, err := c.PatchHandler(ur, ""); err != nil { if _, err := c.patchHandler(ur, ""); err != nil {
return err return err
} }
if ur.Spec.Type == kyvernov1beta1.Mutate && ur.Status.State == kyvernov1beta1.Completed { if ur.Spec.Type == kyvernov1beta1.Mutate && ur.Status.State == kyvernov1beta1.Completed {
@ -62,7 +55,7 @@ func (c *Controller) UnmarkUR(ur *kyvernov1beta1.UpdateRequest) error {
return nil return nil
} }
func (c *Controller) PatchHandler(ur *kyvernov1beta1.UpdateRequest, val string) (*kyvernov1beta1.UpdateRequest, error) { func (c *Controller) patchHandler(ur *kyvernov1beta1.UpdateRequest, val string) (*kyvernov1beta1.UpdateRequest, error) {
patch := jsonutils.NewPatch( patch := jsonutils.NewPatch(
"/status/handler", "/status/handler",
"replace", "replace",

View file

@ -81,7 +81,7 @@ func NewController(
namespaceInformer corev1informers.NamespaceInformer, namespaceInformer corev1informers.NamespaceInformer,
log logr.Logger, log logr.Logger,
dynamicConfig config.Configuration, dynamicConfig config.Configuration,
) (*Controller, error) { ) *Controller {
c := Controller{ c := Controller{
client: client, client: client,
kyvernoClient: kyvernoClient, kyvernoClient: kyvernoClient,
@ -90,21 +90,18 @@ func NewController(
queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request"), queue: workqueue.NewNamedRateLimitingQueue(workqueue.DefaultControllerRateLimiter(), "generate-request"),
log: log, log: log,
Config: dynamicConfig, Config: dynamicConfig,
statusControl: common.StatusControl{Client: kyvernoClient},
policyLister: policyInformer.Lister(),
npolicyLister: npolicyInformer.Lister(),
urLister: urInformer.Lister().UpdateRequests(config.KyvernoNamespace()),
nsLister: namespaceInformer.Lister(),
} }
c.statusControl = common.StatusControl{Client: kyvernoClient}
urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ urInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: c.addUR, AddFunc: c.addUR,
UpdateFunc: c.updateUR, UpdateFunc: c.updateUR,
DeleteFunc: c.deleteUR, DeleteFunc: c.deleteUR,
}) })
return &c
c.policyLister = policyInformer.Lister()
c.npolicyLister = npolicyInformer.Lister()
c.urLister = urInformer.Lister().UpdateRequests(config.KyvernoNamespace())
c.nsLister = namespaceInformer.Lister()
return &c, nil
} }
// Run starts workers // Run starts workers
@ -178,39 +175,32 @@ func (c *Controller) syncUpdateRequest(key string) error {
defer func() { defer func() {
logger.V(4).Info("completed sync update request", "key", key, "processingTime", time.Since(startTime).String()) logger.V(4).Info("completed sync update request", "key", key, "processingTime", time.Since(startTime).String())
}() }()
_, urName, err := cache.SplitMetaNamespaceKey(key) _, urName, err := cache.SplitMetaNamespaceKey(key)
if err != nil { if err != nil {
return err return err
} }
ur, err := c.urLister.Get(urName) ur, err := c.urLister.Get(urName)
if err != nil { if err != nil {
if apierrors.IsNotFound(err) { if apierrors.IsNotFound(err) {
return nil return nil
} }
return fmt.Errorf("failed to fetch update request %s: %v", key, err) return fmt.Errorf("failed to fetch update request %s: %v", key, err)
} }
ur, ok, err := c.markUR(ur)
ur, ok, err := c.MarkUR(ur) if err != nil {
return fmt.Errorf("failed to mark handler for UR %s: %v", key, err)
}
if !ok { if !ok {
logger.V(3).Info("another instance is handling the UR", "handler", ur.Status.Handler) logger.V(3).Info("another instance is handling the UR", "handler", ur.Status.Handler)
return nil return nil
} }
if err != nil {
return fmt.Errorf("failed to mark handler for UR %s: %v", key, err)
}
logger.V(3).Info("UR is marked successfully", "ur", ur.GetName(), "resourceVersion", ur.GetResourceVersion()) logger.V(3).Info("UR is marked successfully", "ur", ur.GetName(), "resourceVersion", ur.GetResourceVersion())
if err := c.ProcessUR(ur); err != nil { if err := c.processUR(ur); err != nil {
return fmt.Errorf("failed to process UR %s: %v", key, err) return fmt.Errorf("failed to process UR %s: %v", key, err)
} }
if err = c.unmarkUR(ur); err != nil {
if err = c.UnmarkUR(ur); err != nil {
return fmt.Errorf("failed to unmark UR %s: %v", key, err) return fmt.Errorf("failed to unmark UR %s: %v", key, err)
} }
return nil return nil
} }