lint: unchecked-type-assertion

Adds a generic wrapper around lru.Cache

Signed-off-by: Brad Davidson <brad.davidson@rancher.com>
This commit is contained in:
Brad Davidson 2025-12-16 00:11:04 +00:00 committed by Brad Davidson
parent 83feb3c31d
commit 62d2737faa
5 changed files with 92 additions and 26 deletions

View file

@ -33,7 +33,6 @@ import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/utils/lru"
)
var (
@ -65,7 +64,7 @@ type Controller struct {
tokenHash string
nodeName string
core core.Interface
clientCache *lru.Cache
clientCache *util.Cache[*Client]
}
// Client holds state for a given configuration - a preconfigured minio client,
@ -83,7 +82,7 @@ type Client struct {
func Start(ctx context.Context, config *config.Control) (*Controller, error) {
once.Do(func() {
c := &Controller{
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
nodeName: os.Getenv("NODE_NAME"),
}
@ -161,7 +160,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli
// print the endpoint and bucket name to avoid leaking creds into the logs.
if client, ok := c.clientCache.Get(*etcdS3); ok {
logrus.Infof("Reusing cached S3 client for endpoint=%q bucket=%q folder=%q", scheme+etcdS3.Endpoint, etcdS3.Bucket, etcdS3.Folder)
return client.(*Client), nil
return client, nil
}
logrus.Infof("Attempting to create new S3 client for endpoint=%q bucket=%q folder=%q", scheme+etcdS3.Endpoint, etcdS3.Bucket, etcdS3.Folder)

View file

@ -17,6 +17,7 @@ import (
"github.com/gorilla/mux"
"github.com/k3s-io/k3s/pkg/daemons/config"
"github.com/k3s-io/k3s/pkg/etcd/snapshot"
"github.com/k3s-io/k3s/pkg/util"
"github.com/k3s-io/k3s/tests/mock"
"github.com/rancher/dynamiclistener/cert"
"github.com/rancher/wrangler/v3/pkg/generated/controllers/core"
@ -24,7 +25,6 @@ import (
"go.uber.org/mock/gomock"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/utils/lru"
)
var gmt = time.FixedZone("GMT", 0)
@ -65,7 +65,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID string
tokenHash string
nodeName string
clientCache *lru.Cache
clientCache *util.Cache[*Client]
}
type args struct {
ctx context.Context
@ -88,7 +88,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -113,7 +113,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -139,7 +139,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -163,7 +163,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -190,7 +190,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -231,7 +231,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -287,7 +287,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -338,7 +338,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -364,7 +364,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -389,7 +389,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -412,7 +412,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
want: &Client{},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -465,7 +465,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
want: &Client{},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -495,7 +495,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -522,7 +522,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -550,7 +550,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
@ -577,7 +577,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {
coreMock := mock.NewCore(gomock.NewController(t))
@ -603,7 +603,7 @@ func Test_UnitControllerGetClient(t *testing.T) {
clusterID: "1234",
tokenHash: "abcd",
nodeName: "server01",
clientCache: lru.New(5),
clientCache: util.NewCache[*Client](5),
},
wantErr: true,
setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) {

View file

@ -257,7 +257,12 @@ func signAndSend(resp http.ResponseWriter, req *http.Request, caCertFile, caKeyF
util.SendError(err, resp, req)
return
}
key = pk.(crypto.Signer)
k, ok := pk.(crypto.Signer)
if !ok {
util.SendError(errors.New("type assertion failed"), resp, req)
return
}
key = k
}
// create the signed cert using dynamiclistener cert utils
@ -298,7 +303,12 @@ func getCACertAndKey(caCertFile, caKeyFile string) ([]*x509.Certificate, crypto.
return nil, nil, err
}
return caCert, caKey.(crypto.Signer), nil
k, ok := caKey.(crypto.Signer)
if !ok {
return nil, nil, errors.New("type assertion failed")
}
return caCert, k, nil
}
// getCSR decodes a x509.CertificateRequest from a POST request body.

View file

@ -28,7 +28,10 @@ func mapLevel(level int) logrus.Level {
func mapKV(kvs []any) logrus.Fields {
fields := logrus.Fields{}
for i := 0; i < len(kvs); i += 2 {
k := kvs[i].(string)
k, ok := kvs[i].(string)
if !ok {
k = fmt.Sprint(kvs[i])
}
if len(kvs) > i+1 {
fields[k] = kvs[i+1]
} else {

54
pkg/util/lru.go Normal file
View file

@ -0,0 +1,54 @@
package util
import "k8s.io/utils/lru"
// Cache is a generic wrapper around lru.Cache that handles type assertions when
// retrieving cached entries.
type Cache[T any] struct {
cache *lru.Cache
}
func NewCache[T any](size int) *Cache[T] {
return &Cache[T]{
cache: lru.New(size),
}
}
func NewCacheWithEvictionFunc[T any](size int, f lru.EvictionFunc) *Cache[T] {
return &Cache[T]{
cache: lru.NewWithEvictionFunc(size, f),
}
}
func (c *Cache[T]) Add(key lru.Key, value T) {
c.cache.Add(key, value)
}
func (c *Cache[T]) Clear() {
c.cache.Clear()
}
func (c *Cache[T]) Get(key lru.Key) (value T, ok bool) {
v, ok := c.cache.Get(key)
if !ok {
return value, ok
}
value, ok = v.(T)
return value, ok
}
func (c *Cache[T]) Len() int {
return c.cache.Len()
}
func (c *Cache[T]) Remove(key lru.Key) {
c.cache.Remove(key)
}
func (c *Cache[T]) RemoveOldest() {
c.cache.RemoveOldest()
}
func (c *Cache[T]) SetEvictionFunc(f lru.EvictionFunc) {
c.cache.SetEvictionFunc(f)
}