Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce excessive WARN logs for forbidden resource access #4356

Merged
merged 1 commit into from
Dec 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions pkg/podownercache/pod_owner_cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

import (
"context"
"fmt"
"github.com/spidernet-io/spiderpool/pkg/lock"
"github.com/spidernet-io/spiderpool/pkg/logutils"
"go.uber.org/zap"
Expand Down Expand Up @@ -83,21 +82,17 @@
}
owner, err := s.getFinalOwner(pod)
if err != nil {
if errors.IsForbidden(err) {
logger.Sugar().Debugf("forbidden to get owner of pod %s/%s", pod.Namespace, pod.Name)
return
}
logger.Warn("", zap.Error(err))
logger.Warn("failed to get final owner", zap.Error(err))

Check warning on line 85 in pkg/podownercache/pod_owner_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/podownercache/pod_owner_cache.go#L85

Added line #L85 was not covered by tests
return
}
s.cacheLock.Lock()
defer s.cacheLock.Unlock()
key := types.NamespacedName{Namespace: pod.Namespace, Name: pod.Name}
s.pods[key] = Pod{
NamespacedName: key,
OwnerInfo: *owner,
IPs: ips,
item := Pod{NamespacedName: key, IPs: ips}
if owner != nil {
item.OwnerInfo = *owner
}
s.pods[key] = item
for _, ip := range ips {
s.ipToPod[ip] = key
}
Expand Down Expand Up @@ -134,7 +129,8 @@
break
}

ownerRef := ownerRefs[0] // Assuming the first owner reference
// Assuming the first owner reference
ownerRef := ownerRefs[0]
finalOwner = &OwnerInfo{
APIVersion: ownerRef.APIVersion,
Kind: ownerRef.Kind,
Expand All @@ -152,7 +148,11 @@
Name: ownerRef.Name,
}, ownerObj)
if err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一个小的代码风格建议:

可以先 if err == nil , 直接 return。 然后再判断 if errors.IsForbidden(err)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

一个小的代码风格建议:

可以先 if err == nil , 直接 return。 然后再判断 if errors.IsForbidden(err)

这是 for loop 的逻辑,这边 error == nil 不应该直接 return,否则要 continue 处理一下。

		if err != nil {
			if errors.IsForbidden(err) {
				logger.Sugar().Debugf("forbidden to get owner of pod %s/%s", obj.GetNamespace(), obj.GetName())
				return nil, nil
			}
			return nil, err
		}

		// Set obj to the current owner to continue the loop
		obj = ownerObj

after

		if err == nil {
                     obj = ownerObj
                     continue
		}

	        if errors.IsForbidden(err) {
		        logger.Sugar().Debugf("forbidden to get owner of pod %s/%s", obj.GetNamespace(), obj.GetName())
		        return nil, nil
	        }
	        return nil, err		

这个 after 是不是你预期的?我不缺定是否遗漏了什么
除去 for loop,我更愿意 check error first 一点,在较小函数 return 时除外。

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

哦,我没注意有个 for loop, 那这样确实应该 check error first

return nil, fmt.Errorf("error fetching owner: %v", err)
if errors.IsForbidden(err) {
logger.Sugar().Debugf("forbidden to get owner of pod %s/%s", obj.GetNamespace(), obj.GetName())
return nil, nil
}
return nil, err

Check warning on line 155 in pkg/podownercache/pod_owner_cache.go

View check run for this annotation

Codecov / codecov/patch

pkg/podownercache/pod_owner_cache.go#L155

Added line #L155 was not covered by tests
}

// Set obj to the current owner to continue the loop
Expand Down
82 changes: 75 additions & 7 deletions pkg/podownercache/pod_owner_cache_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,22 @@ package podownercache
import (
"context"
"fmt"
"testing"
"time"

appv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
kruntime "k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake"
"sigs.k8s.io/controller-runtime/pkg/client"
k8sfakecli "sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"
"time"

"github.com/spidernet-io/spiderpool/pkg/logutils"
)

// Label(K00002)
Expand All @@ -24,7 +30,6 @@ func TestPodOwnerCache(t *testing.T) {
fakeCli := fake.NewSimpleClientset()
factory := informers.NewSharedInformerFactory(fakeCli, 0*time.Second)
informer := factory.Core().V1().Pods().Informer()
//indexer := informer.GetIndexer()

pod := &corev1.Pod{
ObjectMeta: v1.ObjectMeta{
Expand All @@ -47,10 +52,19 @@ func TestPodOwnerCache(t *testing.T) {
},
}

//err := indexer.Add()
//if err != nil {
// t.Fatal(err)
//}
noOwnerPod := &corev1.Pod{
ObjectMeta: v1.ObjectMeta{
Name: "test-pod-2",
Namespace: "test-ns",
},
Status: corev1.PodStatus{
PodIPs: []corev1.PodIP{
{
IP: "10.6.1.21",
},
},
},
}

stopCh := make(chan struct{})
defer close(stopCh)
Expand Down Expand Up @@ -79,6 +93,10 @@ func TestPodOwnerCache(t *testing.T) {
if err != nil {
t.Fatal(err)
}
_, err = fakeCli.CoreV1().Pods("test-ns").Create(context.Background(), noOwnerPod, v1.CreateOptions{})
if err != nil {
t.Fatal(err)
}

time.Sleep(time.Second * 6)

Expand All @@ -90,6 +108,11 @@ func TestPodOwnerCache(t *testing.T) {
t.Fatal(fmt.Println("res is not equal to test-ns and test-deployment"))
}

res = cache.GetPodByIP("10.6.1.21")
if res == nil {
t.Fatal("res is nil")
}

// case update
_, err = fakeCli.CoreV1().Pods("test-ns").Update(context.Background(), pod, v1.UpdateOptions{})
if err != nil {
Expand Down Expand Up @@ -155,3 +178,48 @@ func getMockObjs() []client.Object {
},
}
}

// MockForbiddenClient is a custom mock implementation of the client.Reader interface
type MockForbiddenClient struct{}

func (m *MockForbiddenClient) Get(ctx context.Context, key client.ObjectKey, obj client.Object, opts ...client.GetOption) error {
return errors.NewForbidden(schema.GroupResource{Group: "apps", Resource: "replicasets"}, "test-rs", nil)
}

func (m *MockForbiddenClient) List(ctx context.Context, list client.ObjectList, opts ...client.ListOption) error {
return nil
}

// TestGetFinalOwnerForbidden tests the getFinalOwner method when the Get call returns a forbidden error.
func TestGetFinalOwnerForbidden(t *testing.T) {
logger = logutils.Logger.Named("PodOwnerCache")

mockClient := &MockForbiddenClient{}
cache := &PodOwnerCache{
ctx: context.Background(),
apiReader: mockClient,
}

// Create a mock pod object
pod := &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test-pod",
Namespace: "test-ns",
OwnerReferences: []metav1.OwnerReference{
{
APIVersion: "apps/v1",
Kind: "ReplicaSet",
Name: "test-rs",
},
},
},
}

ownerInfo, err := cache.getFinalOwner(pod)
if err != nil {
t.Fatalf("expected no error, got %v", err)
}
if ownerInfo != nil {
t.Fatalf("expected ownerInfo to be nil, got %v", ownerInfo)
}
}
Loading