1
0
mirror of https://github.com/rancher/norman.git synced 2025-04-29 20:04:03 +00:00
norman/controller/generic_controller.go

102 lines
2.7 KiB
Go
Raw Normal View History

2017-11-11 04:44:02 +00:00
package controller
import (
"context"
2018-03-22 22:53:36 +00:00
"strings"
2017-11-11 04:44:02 +00:00
"time"
2018-03-22 22:53:36 +00:00
errors2 "github.com/pkg/errors"
"github.com/rancher/lasso/pkg/controller"
"github.com/rancher/norman/metrics"
2017-11-11 04:44:02 +00:00
"github.com/sirupsen/logrus"
2018-03-22 22:53:36 +00:00
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
2017-11-11 04:44:02 +00:00
"k8s.io/client-go/tools/cache"
)
2018-10-30 16:54:49 +00:00
type HandlerFunc func(key string, obj interface{}) (interface{}, error)
2017-11-11 04:44:02 +00:00
type GenericController interface {
Informer() cache.SharedIndexInformer
2018-10-30 16:54:49 +00:00
AddHandler(ctx context.Context, name string, handler HandlerFunc)
2017-11-11 04:44:02 +00:00
Enqueue(namespace, name string)
2020-02-06 04:15:26 +00:00
EnqueueAfter(namespace, name string, after time.Duration)
2018-01-16 05:08:36 +00:00
}
2017-11-11 04:44:02 +00:00
type genericController struct {
2020-05-16 00:38:28 +00:00
controller controller.SharedController
informer cache.SharedIndexInformer
name string
namespace string
2017-11-11 04:44:02 +00:00
}
func NewGenericController(namespace, name string, controller controller.SharedController) GenericController {
2017-11-11 04:44:02 +00:00
return &genericController{
2020-05-16 00:38:28 +00:00
controller: controller,
informer: controller.Informer(),
name: name,
namespace: namespace,
2017-11-13 19:50:25 +00:00
}
2017-11-11 04:44:02 +00:00
}
func (g *genericController) Informer() cache.SharedIndexInformer {
return g.informer
}
func (g *genericController) Enqueue(namespace, name string) {
2020-05-16 00:38:28 +00:00
g.controller.Enqueue(namespace, name)
2017-11-11 04:44:02 +00:00
}
2020-02-06 04:15:26 +00:00
func (g *genericController) EnqueueAfter(namespace, name string, after time.Duration) {
2020-05-16 00:38:28 +00:00
g.controller.EnqueueAfter(namespace, name, after)
2020-02-06 04:15:26 +00:00
}
2018-10-30 16:54:49 +00:00
func (g *genericController) AddHandler(ctx context.Context, name string, handler HandlerFunc) {
2020-05-16 00:38:28 +00:00
g.controller.RegisterHandler(ctx, name, controller.SharedControllerHandlerFunc(func(key string, obj runtime.Object) (runtime.Object, error) {
if !isNamespace(g.namespace, obj) {
return obj, nil
}
2020-05-16 00:38:28 +00:00
logrus.Tracef("%s calling handler %s %s", g.name, name, key)
metrics.IncTotalHandlerExecution(g.name, name)
result, err := handler(key, obj)
runtimeObject, _ := result.(runtime.Object)
if err != nil && !ignoreError(err, false) {
metrics.IncTotalHandlerFailure(g.name, name, key)
2018-10-22 17:51:15 +00:00
}
2020-05-16 00:38:28 +00:00
if _, ok := err.(*ForgetError); ok {
2020-03-11 21:48:52 +00:00
logrus.Tracef("%v %v completed with dropped err: %v", g.name, key, err)
2020-05-16 00:38:28 +00:00
return runtimeObject, controller.ErrIgnore
2018-01-16 05:08:36 +00:00
}
2020-05-16 00:38:28 +00:00
return runtimeObject, err
}))
2017-11-11 04:44:02 +00:00
}
func isNamespace(namespace string, obj runtime.Object) bool {
if namespace == "" {
return true
}
meta, err := meta.Accessor(obj)
if err != nil {
return false
}
return meta.GetNamespace() == namespace
}
2018-03-22 22:53:36 +00:00
func ignoreError(err error, checkString bool) bool {
err = errors2.Cause(err)
if errors.IsConflict(err) {
return true
}
2020-05-16 00:38:28 +00:00
if err == controller.ErrIgnore {
return true
}
2018-03-22 22:53:36 +00:00
if _, ok := err.(*ForgetError); ok {
return true
}
if checkString {
return strings.HasSuffix(err.Error(), "please apply your changes to the latest version and try again")
}
return false
}