ContainerImage.Pinniped/internal/kubeclient/middleware.go
Ryan Richard c6c2c525a6 Upgrade the linter and fix all new linter warnings
Also fix some tests that were broken by bumping golang and dependencies
in the previous commits.

Note that in addition to changes made to satisfy the linter which do not
impact the behavior of the code, this commit also adds ReadHeaderTimeout
to all usages of http.Server to satisfy the linter (and because it
seemed like a good suggestion).
2022-08-24 14:45:55 -07:00

161 lines
3.8 KiB
Go

// Copyright 2021-2022 the Pinniped contributors. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
package kubeclient
import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
apiequality "k8s.io/apimachinery/pkg/api/equality"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/errors"
)
type Middleware interface {
Handle(ctx context.Context, rt RoundTrip)
}
var _ Middleware = MiddlewareFunc(nil)
type MiddlewareFunc func(ctx context.Context, rt RoundTrip)
func (f MiddlewareFunc) Handle(ctx context.Context, rt RoundTrip) {
f(ctx, rt)
}
var _ Middleware = Middlewares{}
type Middlewares []Middleware
func (m Middlewares) Handle(ctx context.Context, rt RoundTrip) {
for _, middleware := range m {
middleware := middleware
middleware.Handle(ctx, rt)
}
}
type RoundTrip interface {
Verb() Verb
Namespace() string // this is the only valid way to check namespace, Object.GetNamespace() will almost always be empty
NamespaceScoped() bool
Resource() schema.GroupVersionResource
Subresource() string
MutateRequest(f func(obj Object) error)
MutateResponse(f func(obj Object) error)
}
type Object interface {
runtime.Object // generic access to TypeMeta
metav1.Object // generic access to ObjectMeta
}
var _ RoundTrip = &request{}
type request struct {
verb Verb
namespace string
resource schema.GroupVersionResource
reqFuncs, respFuncs []func(obj Object) error
subresource string
}
func (r *request) Verb() Verb {
return r.verb
}
func (r *request) Namespace() string {
return r.namespace
}
//nolint:gochecknoglobals
var namespaceGVR = corev1.SchemeGroupVersion.WithResource("namespaces")
func (r *request) NamespaceScoped() bool {
if r.Resource() == namespaceGVR {
return false // always consider namespaces to be cluster scoped
}
return len(r.Namespace()) != 0
}
func (r *request) Resource() schema.GroupVersionResource {
return r.resource
}
func (r *request) Subresource() string {
return r.subresource
}
func (r *request) MutateRequest(f func(obj Object) error) {
r.reqFuncs = append(r.reqFuncs, f)
}
func (r *request) MutateResponse(f func(obj Object) error) {
r.respFuncs = append(r.respFuncs, f)
}
type mutationResult struct {
origGVK, newGVK schema.GroupVersionKind
gvkChanged, mutated bool
}
func (r *request) mutateRequest(obj Object) (*mutationResult, error) {
origGVK := obj.GetObjectKind().GroupVersionKind()
if origGVK.Empty() {
return nil, fmt.Errorf("invalid empty orig GVK for %T: %#v", obj, r)
}
origObj, ok := obj.DeepCopyObject().(Object)
if !ok {
return nil, fmt.Errorf("invalid deep copy semantics for %T: %#v", obj, r)
}
var errs []error
for _, reqFunc := range r.reqFuncs {
reqFunc := reqFunc
if err := reqFunc(obj); err != nil {
errs = append(errs, err)
}
}
if err := errors.NewAggregate(errs); err != nil {
return nil, fmt.Errorf("request mutation failed: %w", err)
}
newGVK := obj.GetObjectKind().GroupVersionKind()
if newGVK.Empty() {
return nil, fmt.Errorf("invalid empty new GVK for %T: %#v", obj, r)
}
return &mutationResult{
origGVK: origGVK,
newGVK: newGVK,
gvkChanged: origGVK != newGVK,
mutated: len(r.respFuncs) != 0 || !apiequality.Semantic.DeepEqual(origObj, obj),
}, nil
}
func (r *request) mutateResponse(obj Object) (bool, error) {
origObj, ok := obj.DeepCopyObject().(Object)
if !ok {
return false, fmt.Errorf("invalid deep copy semantics for %T: %#v", obj, r)
}
var errs []error
for _, respFunc := range r.respFuncs {
respFunc := respFunc
if err := respFunc(obj); err != nil {
errs = append(errs, err)
}
}
if err := errors.NewAggregate(errs); err != nil {
return false, fmt.Errorf("response mutation failed: %w", err)
}
mutated := !apiequality.Semantic.DeepEqual(origObj, obj)
return mutated, nil
}