pkg/controller/controllername/controllername.go (68 lines of code) (raw):

package controllername import ( "strings" "unicode" "github.com/go-logr/logr" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/reconcile" ) const ( metricsNameDelimiter = "_" loggerNameDelimiter = "-" ) // ControllerNamer is an interface that returns the name of the controller in all necessary forms type ControllerNamer interface { // String returns the name of the controller in a human-readable form String() string // MetricsName returns the name of the controller in a form that can be used for Prometheus metrics, specifically as a Prometheus label https://prometheus.io/docs/practices/naming/#labels MetricsName() string // LoggerName returns the name of the controller in a form that can be used for logr logger naming LoggerName() string // AddToLogger adds controller name fields to the logger then returns the logger with the added fields AddToLogger(l logr.Logger) logr.Logger // AddToController adds the controller name to the controller builder then returns the builder with the added name. This is useful for naming managed controllers from controller-runtime AddToController(blder *builder.Builder, l logr.Logger) *builder.Builder } // controllerName ex. {"My","Controller", "Name"} -> MyControllerName type controllerName []string // New returns a new controllerName after taking each word of the controller name as a separate argument func New(firstWord string, additionalWords ...string) controllerName { // using a non-variadic for the first word makes it impossible to accidentally pass no arguments in. Accepting variadic versus slices also helps with not accepting empty slices and is easier to use cn := make(controllerName, 0, len(additionalWords)+1) for _, w := range append([]string{firstWord}, additionalWords...) { cleaned := clean(w) if cleaned != "" { cn = append(cn, cleaned) } } return cn } // clean removes spaces and non letters and lowercases func clean(s string) string { rr := make([]rune, 0, len(s)) for _, r := range s { if unicode.IsLetter(r) { rr = append(rr, unicode.ToLower(r)) } } return string(rr) } func (c controllerName) MetricsName() string { return strings.Join(c, metricsNameDelimiter) } func (c controllerName) LoggerName() string { return strings.Join(c, loggerNameDelimiter) } func (c controllerName) String() string { return strings.Join(c, " ") } func (c controllerName) AddToLogger(l logr.Logger) logr.Logger { return l. WithName(c.LoggerName()). WithValues("controller", c.String()). WithValues("controllerMetricsName", c.MetricsName()) // include metrics name, so we can automate creating queries that check Logs based on alerts } func (c controllerName) AddToController(blder *builder.Builder, l logr.Logger) *builder.Builder { return blder. Named(c.MetricsName()). WithLogConstructor(func(req *reconcile.Request) logr.Logger { logger := c.AddToLogger(l) if req != nil { logger.WithValues( "namespace", req.Namespace, "name", req.Name, ) } return logger }) }