From f5714cb63604a0d352cce7be2cd4421c9dfd06b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wenkai=20Yin=28=E5=B0=B9=E6=96=87=E5=BC=80=29?= Date: Mon, 22 Jan 2024 10:51:36 +0800 Subject: [PATCH] [cherry-pick]Do not attempt restore resource with no available GVK in cluster (#7336) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Specify the Kind explicitly in the API resource Specify the Kind explicitly in the API resource to avoid wrong Kind conversion * Do not attempt restore resource with no available GVK in cluster (#7322) Check for GVK before attempting restore. --------- Signed-off-by: Wenkai Yin(尹文开) Signed-off-by: Tiger Kaovilai Co-authored-by: Tiger Kaovilai --- changelogs/unreleased/7336-kaovilai | 1 + pkg/restore/restore.go | 14 ++++++++++++++ pkg/test/discovery_client.go | 5 +---- pkg/test/resources.go | 16 ++++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-) create mode 100644 changelogs/unreleased/7336-kaovilai diff --git a/changelogs/unreleased/7336-kaovilai b/changelogs/unreleased/7336-kaovilai new file mode 100644 index 000000000..000c28709 --- /dev/null +++ b/changelogs/unreleased/7336-kaovilai @@ -0,0 +1 @@ +Check resource Group Version and Kind is available in cluster before attempting restore to prevent being stuck. \ No newline at end of file diff --git a/pkg/restore/restore.go b/pkg/restore/restore.go index 1a341d1e7..963f690e4 100644 --- a/pkg/restore/restore.go +++ b/pkg/restore/restore.go @@ -1059,6 +1059,16 @@ func (ctx *restoreContext) getResourceClient(groupResource schema.GroupResource, } func (ctx *restoreContext) getResourceLister(groupResource schema.GroupResource, obj *unstructured.Unstructured, namespace string) cache.GenericNamespaceLister { + _, _, err := ctx.discoveryHelper.KindFor(schema.GroupVersionKind{ + Group: obj.GroupVersionKind().Group, + Version: obj.GetAPIVersion(), + Kind: obj.GetKind(), + }) + clusterHasKind := err == nil + if !clusterHasKind { + ctx.log.Errorf("Cannot get resource lister %s because GVK doesn't exist in the cluster", groupResource) + return nil + } informer := ctx.dynamicInformerFactory.factory.ForResource(groupResource.WithVersion(obj.GroupVersionKind().Version)) // if the restore contains CRDs or the RIA returns new resources, need to make sure the corresponding informers are synced if !informer.Informer().HasSynced() { @@ -1084,6 +1094,10 @@ func getResourceID(groupResource schema.GroupResource, namespace, name string) s func (ctx *restoreContext) getResource(groupResource schema.GroupResource, obj *unstructured.Unstructured, namespace, name string) (*unstructured.Unstructured, error) { lister := ctx.getResourceLister(groupResource, obj, namespace) + if lister == nil { + // getResourceLister logs the error, this func returns error to the caller to trigger partiallyFailed. + return nil, errors.Errorf("Error getting lister for %s because no informer for GVK found", getResourceID(groupResource, namespace, name)) + } clusterObj, err := lister.Get(name) if err != nil { return nil, errors.Wrapf(err, "error getting resource from lister for %s, %s/%s", groupResource, namespace, name) diff --git a/pkg/test/discovery_client.go b/pkg/test/discovery_client.go index e492aafc9..3f65cf5ea 100644 --- a/pkg/test/discovery_client.go +++ b/pkg/test/discovery_client.go @@ -19,9 +19,6 @@ package test import ( "strings" - "golang.org/x/text/cases" - "golang.org/x/text/language" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/discovery" discoveryfake "k8s.io/client-go/discovery/fake" @@ -76,7 +73,7 @@ func (c *DiscoveryClient) WithAPIResource(resource *APIResource) *DiscoveryClien Namespaced: resource.Namespaced, Group: resource.Group, Version: resource.Version, - Kind: cases.Title(language.Und).String(strings.TrimSuffix(resource.Name, "s")), + Kind: resource.Kind, Verbs: metav1.Verbs([]string{"list", "create", "get", "delete"}), ShortNames: []string{resource.ShortName}, }) diff --git a/pkg/test/resources.go b/pkg/test/resources.go index 709497fca..fe2ad6352 100644 --- a/pkg/test/resources.go +++ b/pkg/test/resources.go @@ -27,6 +27,7 @@ type APIResource struct { Group string Version string Name string + Kind string ShortName string Namespaced bool Items []metav1.Object @@ -50,6 +51,7 @@ func Pods(items ...metav1.Object) *APIResource { ShortName: "po", Namespaced: true, Items: items, + Kind: "Pod", } } @@ -59,6 +61,7 @@ func PVCs(items ...metav1.Object) *APIResource { Version: "v1", Name: "persistentvolumeclaims", ShortName: "pvc", + Kind: "PersistentVolumeClaim", Namespaced: true, Items: items, } @@ -70,6 +73,7 @@ func PVs(items ...metav1.Object) *APIResource { Version: "v1", Name: "persistentvolumes", ShortName: "pv", + Kind: "PersistentVolume", Namespaced: false, Items: items, } @@ -81,6 +85,7 @@ func Secrets(items ...metav1.Object) *APIResource { Version: "v1", Name: "secrets", ShortName: "secrets", + Kind: "Secret", Namespaced: true, Items: items, } @@ -92,6 +97,7 @@ func Deployments(items ...metav1.Object) *APIResource { Version: "v1", Name: "deployments", ShortName: "deploy", + Kind: "Deployment", Namespaced: true, Items: items, } @@ -103,6 +109,7 @@ func ExtensionsDeployments(items ...metav1.Object) *APIResource { Version: "v1", Name: "deployments", ShortName: "deploy", + Kind: "Deployment", Namespaced: true, Items: items, } @@ -115,6 +122,7 @@ func VeleroDeployments(items ...metav1.Object) *APIResource { Version: "v1", Name: "deployments", ShortName: "deploy", + Kind: "Deployment", Namespaced: true, Items: items, } @@ -126,6 +134,7 @@ func Namespaces(items ...metav1.Object) *APIResource { Version: "v1", Name: "namespaces", ShortName: "ns", + Kind: "Namespace", Namespaced: false, Items: items, } @@ -137,6 +146,7 @@ func ServiceAccounts(items ...metav1.Object) *APIResource { Version: "v1", Name: "serviceaccounts", ShortName: "sa", + Kind: "ServiceAccount", Namespaced: true, Items: items, } @@ -148,6 +158,7 @@ func ConfigMaps(items ...metav1.Object) *APIResource { Version: "v1", Name: "configmaps", ShortName: "cm", + Kind: "ConfigMap", Namespaced: true, Items: items, } @@ -159,6 +170,7 @@ func CRDs(items ...metav1.Object) *APIResource { Version: "v1beta1", Name: "customresourcedefinitions", ShortName: "crd", + Kind: "CustomResourceDefinition", Namespaced: false, Items: items, } @@ -169,6 +181,7 @@ func VSLs(items ...metav1.Object) *APIResource { Group: "velero.io", Version: "v1", Name: "volumesnapshotlocations", + Kind: "VolumeSnapshotLocation", Namespaced: true, Items: items, } @@ -179,6 +192,7 @@ func Backups(items ...metav1.Object) *APIResource { Group: "velero.io", Version: "v1", Name: "backups", + Kind: "Backup", Namespaced: true, Items: items, } @@ -190,6 +204,7 @@ func Services(items ...metav1.Object) *APIResource { Version: "v1", Name: "services", ShortName: "svc", + Kind: "Service", Namespaced: true, Items: items, } @@ -200,6 +215,7 @@ func DataUploads(items ...metav1.Object) *APIResource { Group: "velero.io", Version: "v2alpha1", Name: "datauploads", + Kind: "DataUpload", Namespaced: true, Items: items, }