From 9a62973052d4f4523eb1b489e37fd127ddabdbe6 Mon Sep 17 00:00:00 2001 From: Quang Nguyen Date: Fri, 15 Mar 2024 14:50:57 -0400 Subject: [PATCH] chore: remove deprecated code (#50) --- pkg/deprecated/cache/cache.go | 245 ------------------- pkg/deprecated/cache/cache_test.go | 368 ----------------------------- 2 files changed, 613 deletions(-) delete mode 100644 pkg/deprecated/cache/cache.go delete mode 100644 pkg/deprecated/cache/cache_test.go diff --git a/pkg/deprecated/cache/cache.go b/pkg/deprecated/cache/cache.go deleted file mode 100644 index eccaf3ba29..0000000000 --- a/pkg/deprecated/cache/cache.go +++ /dev/null @@ -1,245 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -package cache - -import ( - "context" - "errors" - "time" - - "github.com/microsoft/retina/pkg/log" - "go.uber.org/zap" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/client-go/informers" - v1 "k8s.io/client-go/informers/core/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - crmgr "sigs.k8s.io/controller-runtime/pkg/manager" -) - -type Cache struct { - // local cache containing services + pods - objCache map[string]client.Object - // informer to track pod events - podInformer v1.PodInformer - // informer to track service events - svcInformer v1.ServiceInformer - // mgr mostly used to start the cache in this pkg - mgr crmgr.Manager - informerFactory informers.SharedInformerFactory - logger *log.ZapLogger -} - -const ( - ResyncTime time.Duration = 5 * time.Minute -) - -func (c *Cache) add(obj interface{}) { - cObj, ok := obj.(client.Object) - if !ok { - c.logger.Error("Failed to cast to Kubernetes client object") - return - } - objIP, err := GetObjectIP(cObj) - if err != nil { - c.logger.Error("Failed to get IP", zap.Error(err)) - return - } - if len(objIP) > 0 { - c.objCache[objIP] = cObj - } -} - -func (c *Cache) update(old, new interface{}) { - oObj, ook := old.(client.Object) - nObj, nok := new.(client.Object) - if !ook || !nok { - c.logger.Error("Failed to cast to Kubernetes client object") - return - } - oObjIP, oerr := GetObjectIP(oObj) - nObjIP, nerr := GetObjectIP(nObj) - if oerr != nil || nerr != nil { - c.logger.Error("Failed to get IP", zap.Error(oerr), zap.Error(nerr)) - return - } - if len(nObjIP) > 0 { - if len(oObjIP) > 0 && oObjIP != nObjIP { - delete(c.objCache, oObjIP) - } - c.objCache[nObjIP] = nObj - } -} - -func (c *Cache) delete(obj interface{}) { - cObj, ok := obj.(client.Object) - if !ok { - c.logger.Error("Failed to cast to Kubernetes client object") - return - } - objIP, err := GetObjectIP(cObj) - if err != nil { - c.logger.Error("Failed to get IP", zap.Error(err)) - return - } - delete(c.objCache, objIP) -} - -func New(logger *log.ZapLogger, mgr crmgr.Manager, cl kubernetes.Interface, factory informers.SharedInformerFactory) *Cache { - cacheMap := make(map[string]client.Object) - return &Cache{ - objCache: cacheMap, - mgr: mgr, - informerFactory: factory, - logger: logger, - } -} - -func (lc *Cache) Start(ctx context.Context) error { - lc.logger.Info("Starting cache...") - lc.SetInformers(lc.informerFactory) - err := lc.mgr.GetCache().Start(ctx) - return err -} - -func (lc *Cache) SetInformers(informerFactory informers.SharedInformerFactory) { - lc.SetPodInformer(informerFactory) - lc.SetServiceInformer(informerFactory) -} - -func (lc *Cache) SetPodInformer(informerFactory informers.SharedInformerFactory) { - podInformer := informerFactory.Core().V1().Pods() - _, err := podInformer.Informer().AddEventHandler( - &cache.ResourceEventHandlerFuncs{ - AddFunc: lc.add, - UpdateFunc: lc.update, - DeleteFunc: lc.delete, - }, - ) - if err != nil { - lc.logger.Error("Failed to add pod event handler", zap.Error(err)) - } - lc.podInformer = podInformer -} - -func (lc *Cache) SetServiceInformer(informerFactory informers.SharedInformerFactory) { - svcInformer := informerFactory.Core().V1().Services() - lc.svcInformer = svcInformer - _, err := svcInformer.Informer().AddEventHandler( - &cache.ResourceEventHandlerFuncs{ - AddFunc: lc.add, - UpdateFunc: lc.update, - DeleteFunc: lc.delete, - }, - ) - if err != nil { - lc.logger.Error("Failed to add service event handler", zap.Error(err)) - } -} - -func (c *Cache) LookupObjectByIP(ip string) (client.Object, error) { - obj, ok := c.objCache[ip] - if ok { - return obj, nil - } - // check cache podlist - var podList corev1.PodList - obj, _ = c.CacheLookupObjectByIP(ip, &podList) - if obj != nil { - return obj, nil - } - // check cache service list - var svcList corev1.ServiceList - obj, _ = c.CacheLookupObjectByIP(ip, &svcList) - if obj != nil { - return obj, nil - } - return nil, errors.New("Pod or service not found") -} - -func (c *Cache) CacheLookupObjectByIP(ip string, list client.ObjectList) (client.Object, error) { - err := c.mgr.GetCache().List(context.TODO(), list) - if err != nil { - return nil, err - } - switch list.(type) { - case *corev1.PodList: - return c.LookupPodByIP(list, ip) - case *corev1.ServiceList: - return c.LookupServiceByIP(list, ip) - default: - return nil, errors.New("List type not supported") - } -} - -func (c *Cache) LookupServiceByIP(list client.ObjectList, ip string) (client.Object, error) { - v, ok := list.(*corev1.ServiceList) - if !ok { - return nil, errors.New("Object is not a Service List") - } - for _, obj := range v.Items { - if oip, err := GetObjectIP(&obj); err == nil && (oip == ip) { - c.add(&obj) - return c.objCache[ip], nil - } - } - return nil, errors.New("Service not found") -} - -func (c *Cache) LookupPodByIP(list client.ObjectList, ip string) (client.Object, error) { - v, ok := list.(*corev1.PodList) - if !ok { - return nil, errors.New("Object is not a PodList") - } - for _, obj := range v.Items { - if oip, err := GetObjectIP(&obj); err == nil && (oip == ip) { - c.add(&obj) - return c.objCache[ip], nil - } - } - return nil, errors.New("Pod not found") -} - -func (c *Cache) GetPodOwner(obj interface{}) (string, string) { - var name, kind string - switch p := obj.(type) { - case *corev1.Pod: - if len(p.OwnerReferences) == 0 { - return name, kind - } - name = p.OwnerReferences[0].Name - switch v := p.OwnerReferences[0].Kind; v { - case "DaemonSet", "StatefulSet": - kind = v - case "ReplicaSet": - kind = v - rs := &appsv1.ReplicaSet{} - rk := types.NamespacedName{ - Namespace: p.Namespace, - Name: name, - } - err := c.mgr.GetClient().Get(context.TODO(), rk, rs) - if err != nil { - c.logger.Warn("Error finding replicaset", zap.Error(err)) - } - if len(rs.OwnerReferences) > 0 { - kind = "Deployment" - name = rs.OwnerReferences[0].Name - } - } - } - return name, kind -} - -func GetObjectIP(obj interface{}) (string, error) { - switch v := obj.(type) { - case *corev1.Service: - return v.Spec.ClusterIP, nil - case *corev1.Pod: - return v.Status.PodIP, nil - } - return "", errors.New("Non supported type") -} diff --git a/pkg/deprecated/cache/cache_test.go b/pkg/deprecated/cache/cache_test.go deleted file mode 100644 index 545a71a744..0000000000 --- a/pkg/deprecated/cache/cache_test.go +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright (c) Microsoft Corporation. -// Licensed under the MIT license. -//go:build unit -// +build unit - -package cache - -import ( - "context" - "testing" - - "github.com/microsoft/retina/pkg/log" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/informers" - v1 "k8s.io/client-go/informers/core/v1" - k8sfake "k8s.io/client-go/kubernetes/fake" - "k8s.io/client-go/rest" - crc "sigs.k8s.io/controller-runtime/pkg/cache" - "sigs.k8s.io/controller-runtime/pkg/client" - crmgr "sigs.k8s.io/controller-runtime/pkg/manager" -) - -type mockMgr struct { - crmgr.Manager -} - -type mockCache struct { - crc.Cache -} - -type mockClient struct { - client.Client -} - -func (mm *mockMgr) GetCache() crc.Cache { - var mc crc.Cache = &mockCache{} - return mc -} - -func (mm *mockMgr) GetClient() client.Client { - var mc client.Client = &mockClient{} - return mc -} - -func (mc *mockClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error { - obj.SetOwnerReferences([]metav1.OwnerReference{ - { - Name: "Test", - }, - }) - return nil -} - -func (mm *mockMgr) GetConfig() *rest.Config { - return &rest.Config{} -} - -func (mc *mockCache) Start(ctx context.Context) error { - return nil -} - -func (mc *mockCache) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error { - podItems := make([]corev1.Pod, 1) - podItems[0] = corev1.Pod{ - Status: corev1.PodStatus{ - PodIP: "0.0.0.1", - }, - } - svcItems := make([]corev1.Service, 1) - svcItems[0] = corev1.Service{ - Spec: corev1.ServiceSpec{ - ClusterIP: "0.0.0.2", - }, - } - switch list.(type) { - case *corev1.PodList: - listPtr := (list).(*corev1.PodList) - listPtr.Items = podItems - case *corev1.ServiceList: - listPtr := (list).(*corev1.ServiceList) - listPtr.Items = svcItems - } - return nil -} - -func TestCache_LookupObjectByIP(t *testing.T) { - type fields struct { - objCache map[string]client.Object - podInformer v1.PodInformer - svcInformer v1.ServiceInformer - } - type args struct { - ip string - } - var mm crmgr.Manager = &mockMgr{} - tests := []struct { - name string - fields fields - args args - wantIP string - wantErr bool - }{ - { - name: "Pod in local cache", - fields: fields{ - objCache: map[string]client.Object{ - "0.0.0.01": &corev1.Pod{ - Status: corev1.PodStatus{ - PodIP: "0.0.0.01", - }, - }, - }, - }, - args: args{ - ip: "0.0.0.01", - }, - wantIP: "0.0.0.01", - wantErr: false, - }, - { - name: "Pod in cache", - fields: fields{ - objCache: map[string]client.Object{}, - }, - args: args{ - ip: "0.0.0.1", - }, - wantIP: "0.0.0.1", - wantErr: false, - }, - { - name: "Service in cache", - fields: fields{ - objCache: map[string]client.Object{}, - }, - args: args{ - ip: "0.0.0.2", - }, - wantIP: "0.0.0.2", - wantErr: false, - }, - { - name: "Pod/Svc not found", - fields: fields{ - objCache: map[string]client.Object{}, - }, - args: args{ - ip: "0.0.0.3", - }, - wantIP: "0.0.0.3", - wantErr: true, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &Cache{ - objCache: tt.fields.objCache, - podInformer: tt.fields.podInformer, - svcInformer: tt.fields.svcInformer, - mgr: mm, - } - c.SetInformers(informers.NewSharedInformerFactory(nil, 0)) - got, err := c.LookupObjectByIP(tt.args.ip) - if err != nil && tt.wantErr { - return - } - if (err != nil) != tt.wantErr { - t.Errorf("Cache.LookupObjectByIP() error = %v, wantErr %v", err, tt.wantErr) - return - } - switch v := got.(type) { - case *corev1.Pod: - if v.Status.PodIP != tt.wantIP { - t.Errorf("Cache.LookupObjectByIP() = %v, want %v", got, tt.wantIP) - } - case *corev1.Service: - if v.Spec.ClusterIP != tt.wantIP { - t.Errorf("Cache.LookupObjectByIP() = %v, want %v", got, tt.wantIP) - } - } - }) - } -} - -func TestCache_update(t *testing.T) { - type fields struct { - objCache map[string]client.Object - podInformer v1.PodInformer - svcInformer v1.ServiceInformer - } - type args struct { - old interface{} - new interface{} - } - cObj := corev1.Pod{ - Status: corev1.PodStatus{ - PodIP: "0.0.0.01", - }, - } - tests := []struct { - name string - fields fields - args args - }{ - { - name: "Test update for object cache where ip > 0", - fields: fields{ - objCache: map[string]client.Object{ - "0.0.0.01": &cObj, - }, - }, - args: args{ - old: &cObj, - new: &cObj, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &Cache{ - objCache: tt.fields.objCache, - podInformer: tt.fields.podInformer, - svcInformer: tt.fields.svcInformer, - } - c.update(tt.args.old, tt.args.new) - }) - } -} - -func TestCache_delete(t *testing.T) { - type fields struct { - objCache map[string]client.Object - podInformer v1.PodInformer - svcInformer v1.ServiceInformer - } - type args struct { - obj interface{} - } - cObj := corev1.Pod{ - Status: corev1.PodStatus{ - PodIP: "0.0.0.01", - }, - } - tests := []struct { - name string - fields fields - args args - }{ - { - name: "Test update for object cache where ip > 0", - fields: fields{ - objCache: map[string]client.Object{ - "0.0.0.01": &cObj, - }, - }, - args: args{ - obj: &cObj, - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - c := &Cache{ - objCache: tt.fields.objCache, - podInformer: tt.fields.podInformer, - svcInformer: tt.fields.svcInformer, - } - c.delete(tt.args.obj) - if c.objCache[cObj.Status.PodIP] != nil { - t.Errorf("Cache.delete() = cache entry was not deleted %v", cObj.Status.PodIP) - } - }) - } -} - -func TestStart(t *testing.T) { - tests := []struct { - name string - wantErr bool - }{ - { - name: "Test new cache", - wantErr: false, - }, - } - cl := k8sfake.NewSimpleClientset() - factory := informers.NewSharedInformerFactory(cl, ResyncTime) - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - log.SetupZapLogger(log.GetDefaultLogOpts()) - c := New(log.Logger(), &mockMgr{}, cl, factory) - err := c.Start(context.TODO()) - if err != nil { - t.Errorf("Error starting the cache %v", err) - } - }) - } -} - -func TestGetPodOwner(t *testing.T) { - type args struct { - obj interface{} - } - tests := []struct { - name string - args args - ownerName string - ownerKind string - }{ - { - name: "Test daemonset", - args: args{ - obj: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "DaemonSet", - Name: "Test", - }, - }, - }, - }, - }, - ownerName: "Test", - ownerKind: "DaemonSet", - }, - { - name: "Test deployment", - args: args{ - obj: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{ - { - Kind: "ReplicaSet", - Name: "Test", - }, - }, - }, - }, - }, - ownerName: "Test", - ownerKind: "Deployment", - }, - { - name: "Test unknown owner", - args: args{ - obj: &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - OwnerReferences: []metav1.OwnerReference{}, - }, - }, - }, - }, - } - mm := &mockMgr{} - c := &Cache{ - mgr: mm, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got1, got2 := c.GetPodOwner(tt.args.obj) - if got1 != tt.ownerName || got2 != tt.ownerKind { - t.Errorf("GetPodOwner() got1 = %v, want1 %v, got2 = %v, want2: %v", got1, tt.ownerName, got2, tt.ownerKind) - } - }) - } -}