mirror of
https://github.com/rancher/norman.git
synced 2025-06-01 19:55:08 +00:00
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.
98 lines
2.6 KiB
Go
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
|
|
}
|