Skip to content

Commit

Permalink
Handle K8s empty resource list for K8s 1.26+ (#1194)
Browse files Browse the repository at this point in the history
  • Loading branch information
pkosiec authored Aug 18, 2023
1 parent 3b92a12 commit b34d85e
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
27 changes: 21 additions & 6 deletions internal/command/guard.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,21 +233,26 @@ func (g *CommandGuard) getAllSupportedVerbs(resourceType string, inVerbs v1.Verb
return verbs
}

// ignoredResourceListErrors contains errors which should be ignored when getting resource list from K8s API.
var ignoredResourceListErrors = map[string]struct{}{
"Got empty response for": {}, // See https://github.com/kubernetes/client-go/blob/release-1.25/discovery/cached/memory/memcache.go#L228 (and below)
"received empty response for": {}, // See https://github.com/kubernetes/client-go/blob/release-1.26/discovery/cached/memory/memcache.go#L71
}

// shouldIgnoreResourceListError returns true if the error should be ignored. This is a workaround for client-go behavior,
// which reports error on empty resource lists. However, some components can register empty lists for their resources.
// See
// Unfortunately there isn't a nicer way to do this, as the error type from K8s Go API is not exported.
//
// See: https://github.com/kyverno/kyverno/issues/2267
func shouldIgnoreResourceListError(err error) bool {
groupDiscoFailedErr, ok := err.(*discovery.ErrGroupDiscoveryFailed)
var groupDiscoFailedErr *discovery.ErrGroupDiscoveryFailed
ok := errors.As(err, &groupDiscoFailedErr)
if !ok {
return false
}

for _, currentErr := range groupDiscoFailedErr.Groups {
// Unfortunately there isn't a nicer way to do this.
// See https://github.com/kubernetes/client-go/blob/release-1.25/discovery/cached/memory/memcache.go#L228
if strings.Contains(currentErr.Error(), "Got empty response for") {
// ignore it as it isn't necessarily an error
if isErrorMsgOnIgnoredList(currentErr.Error(), ignoredResourceListErrors) {
continue
}

Expand All @@ -256,3 +261,13 @@ func shouldIgnoreResourceListError(err error) bool {

return true
}

func isErrorMsgOnIgnoredList[T any](in string, patterns map[string]T) bool {
for pattern := range patterns {
if strings.Contains(in, pattern) {
return true
}
}

return false
}
23 changes: 23 additions & 0 deletions internal/command/guard_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,29 @@ func TestCommandGuard_GetAllowedResourcesForVerb(t *testing.T) {
},
ExpectedErrMessage: "",
},
{
Name: "Discovery API resource list ignored error 2",
SelectedVerb: "get",
AllConfiguredResources: []string{"pods"},
FakeDiscoClient: &fakeDisco{
list: []*v1.APIResourceList{
{
GroupVersion: "v1",
APIResources: []v1.APIResource{
{Name: "pods", Namespaced: true, Kind: "Pod", Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}},
},
},
},
err: &discovery.ErrGroupDiscoveryFailed{
Groups: map[schema.GroupVersion]error{
{Group: "", Version: "external.metrics.k8s.io/v1beta1"}: errors.New("received empty response for: external.metrics.k8s.io/v1beta1"),
},
}},
ExpectedResult: []Resource{
{Name: "pods", Namespaced: true, SlashSeparatedInCommand: false},
},
ExpectedErrMessage: "",
},
{
Name: "Verb not supported",
SelectedVerb: "create",
Expand Down

0 comments on commit b34d85e

Please sign in to comment.