1
0
mirror of https://github.com/rancher/norman.git synced 2025-06-01 19:55:08 +00:00
norman/controller/generic_controller.go
Ricardo Weir 20335edec8 Remove controller metrics
Norman metrics' labels have too high of a cardinality as they
include object key as a label. This is a problem because metrics
produces a data row for every combination of labels. This can
have a large impact on performance and is cautioned against in
the prometheus docs. Norman now uses lasso which has metrics with
matching functionality apart from the object key, so norman
metrics will be removed in favor of lasso metrics.
2022-04-27 11:45:54 -07:00

98 lines
2.6 KiB
Go

package controller
import (
"context"
"strings"
"time"
errors2 "github.com/pkg/errors"
"github.com/rancher/lasso/pkg/controller"
"github.com/sirupsen/logrus"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/cache"
)
type HandlerFunc func(key string, obj interface{}) (interface{}, error)
type GenericController interface {
Informer() cache.SharedIndexInformer
AddHandler(ctx context.Context, name string, handler HandlerFunc)
Enqueue(namespace, name string)
EnqueueAfter(namespace, name string, after time.Duration)
}
type genericController struct {
controller controller.SharedController
informer cache.SharedIndexInformer
name string
namespace string
}
func NewGenericController(namespace, name string, controller controller.SharedController) GenericController {
return &genericController{
controller: controller,
informer: controller.Informer(),
name: name,
namespace: namespace,
}
}
func (g *genericController) Informer() cache.SharedIndexInformer {
return g.informer
}
func (g *genericController) Enqueue(namespace, name string) {
g.controller.Enqueue(namespace, name)
}
func (g *genericController) EnqueueAfter(namespace, name string, after time.Duration) {
g.controller.EnqueueAfter(namespace, name, after)
}
func (g *genericController) AddHandler(ctx context.Context, name string, handler HandlerFunc) {
g.controller.RegisterHandler(ctx, name, controller.SharedControllerHandlerFunc(func(key string, obj runtime.Object) (runtime.Object, error) {
if !isNamespace(g.namespace, obj) {
return obj, nil
}
logrus.Tracef("%s calling handler %s %s", g.name, name, key)
result, err := handler(key, obj)
runtimeObject, _ := result.(runtime.Object)
if _, ok := err.(*ForgetError); ok {
logrus.Tracef("%v %v completed with dropped err: %v", g.name, key, err)
return runtimeObject, controller.ErrIgnore
}
return runtimeObject, err
}))
}
func isNamespace(namespace string, obj runtime.Object) bool {
if namespace == "" || obj == nil {
return true
}
meta, err := meta.Accessor(obj)
if err != nil {
// if you can't figure out the namespace, just let it through
return true
}
return meta.GetNamespace() == namespace
}
func ignoreError(err error, checkString bool) bool {
err = errors2.Cause(err)
if errors.IsConflict(err) {
return true
}
if err == controller.ErrIgnore {
return true
}
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
}