mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-04 23:17:50 +00:00
Tolerate partial discovery in garbage collector
Allow the garbage collector to tolerate partial discovery failures. On a partial failure, use whatever was discovered, log the failures, and allow the resync logic to try again later. Fixes #55022.
This commit is contained in:
@@ -17,6 +17,7 @@ limitations under the License.
|
||||
package garbagecollector
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"reflect"
|
||||
@@ -37,6 +38,7 @@ import (
|
||||
"k8s.io/apimachinery/pkg/util/json"
|
||||
"k8s.io/apimachinery/pkg/util/sets"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/client-go/discovery"
|
||||
"k8s.io/client-go/dynamic"
|
||||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
@@ -671,3 +673,109 @@ func TestOrphanDependentsFailure(t *testing.T) {
|
||||
t.Errorf("expected error contains text %s, got %v", expected, err)
|
||||
}
|
||||
}
|
||||
|
||||
// TestGetDeletableResources ensures GetDeletableResources always returns
|
||||
// something usable regardless of discovery output.
|
||||
func TestGetDeletableResources(t *testing.T) {
|
||||
tests := map[string]struct {
|
||||
serverResources []*metav1.APIResourceList
|
||||
err error
|
||||
deletableResources map[schema.GroupVersionResource]struct{}
|
||||
}{
|
||||
"no error": {
|
||||
serverResources: []*metav1.APIResourceList{
|
||||
{
|
||||
// Valid GroupVersion
|
||||
GroupVersion: "apps/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod", Verbs: metav1.Verbs{"delete"}},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
},
|
||||
},
|
||||
{
|
||||
// Invalid GroupVersion, should be ignored
|
||||
GroupVersion: "foo//whatever",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "bars", Namespaced: true, Kind: "Bar", Verbs: metav1.Verbs{"delete"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: nil,
|
||||
deletableResources: map[schema.GroupVersionResource]struct{}{
|
||||
{Group: "apps", Version: "v1", Resource: "pods"}: {},
|
||||
},
|
||||
},
|
||||
"nonspecific failure, includes usable results": {
|
||||
serverResources: []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "apps/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod", Verbs: metav1.Verbs{"delete"}},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: fmt.Errorf("internal error"),
|
||||
deletableResources: map[schema.GroupVersionResource]struct{}{
|
||||
{Group: "apps", Version: "v1", Resource: "pods"}: {},
|
||||
},
|
||||
},
|
||||
"partial discovery failure, includes usable results": {
|
||||
serverResources: []*metav1.APIResourceList{
|
||||
{
|
||||
GroupVersion: "apps/v1",
|
||||
APIResources: []metav1.APIResource{
|
||||
{Name: "pods", Namespaced: true, Kind: "Pod", Verbs: metav1.Verbs{"delete"}},
|
||||
{Name: "services", Namespaced: true, Kind: "Service"},
|
||||
},
|
||||
},
|
||||
},
|
||||
err: &discovery.ErrGroupDiscoveryFailed{
|
||||
Groups: map[schema.GroupVersion]error{
|
||||
{Group: "foo", Version: "v1"}: fmt.Errorf("discovery failure"),
|
||||
},
|
||||
},
|
||||
deletableResources: map[schema.GroupVersionResource]struct{}{
|
||||
{Group: "apps", Version: "v1", Resource: "pods"}: {},
|
||||
},
|
||||
},
|
||||
"discovery failure, no results": {
|
||||
serverResources: nil,
|
||||
err: fmt.Errorf("internal error"),
|
||||
deletableResources: map[schema.GroupVersionResource]struct{}{},
|
||||
},
|
||||
}
|
||||
|
||||
for name, test := range tests {
|
||||
t.Logf("testing %q", name)
|
||||
client := &fakeServerResources{
|
||||
PreferredResources: test.serverResources,
|
||||
Error: test.err,
|
||||
}
|
||||
actual := GetDeletableResources(client)
|
||||
if !reflect.DeepEqual(test.deletableResources, actual) {
|
||||
t.Errorf("expected resources:\n%v\ngot:\n%v", test.deletableResources, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type fakeServerResources struct {
|
||||
PreferredResources []*metav1.APIResourceList
|
||||
Error error
|
||||
}
|
||||
|
||||
func (_ *fakeServerResources) ServerResourcesForGroupVersion(groupVersion string) (*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (_ *fakeServerResources) ServerResources() ([]*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (f *fakeServerResources) ServerPreferredResources() ([]*metav1.APIResourceList, error) {
|
||||
return f.PreferredResources, f.Error
|
||||
}
|
||||
|
||||
func (_ *fakeServerResources) ServerPreferredNamespacedResources() ([]*metav1.APIResourceList, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user