Skip to content

Commit

Permalink
Perform GVK check in getGenericInformerInternal, return error in getR…
Browse files Browse the repository at this point in the history
…esource if nil

Signed-off-by: Tiger Kaovilai <[email protected]>
  • Loading branch information
kaovilai committed Jan 18, 2024
1 parent 4cbdce2 commit 94f9e89
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
6 changes: 5 additions & 1 deletion pkg/discovery/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,8 @@ type helper struct {
mapper meta.RESTMapper
resources []*metav1.APIResourceList
resourcesMap map[schema.GroupVersionResource]metav1.APIResource
// kindMap stores APIResources keyed by GroupVersionKind used by KindFor()
// Group and Kind are case insensitive so we will store as lowercase so hits are consistent
kindMap map[schema.GroupVersionKind]metav1.APIResource
apiGroups []metav1.APIGroup
serverVersion *version.Info
Expand Down Expand Up @@ -117,6 +119,7 @@ func (h *helper) ResourceFor(input schema.GroupVersionResource) (schema.GroupVer
return gvr, apiResource, nil
}

// KindFor expects input where kind is lowercased to hit the map
func (h *helper) KindFor(input schema.GroupVersionKind) (schema.GroupVersionResource, metav1.APIResource, error) {
h.lock.RLock()
defer h.lock.RUnlock()
Expand Down Expand Up @@ -193,7 +196,8 @@ func (h *helper) Refresh() error {

for _, resource := range resourceGroup.APIResources {
gvr := gv.WithResource(resource.Name)
gvk := gv.WithKind(resource.Kind)
// gvk kind is lowercased for consistency of hits in KindFor()
gvk := gv.WithKind(strings.ToLower(resource.Kind))
h.resourcesMap[gvr] = resource
h.kindMap[gvk] = resource
}
Expand Down
33 changes: 17 additions & 16 deletions pkg/restore/restore.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,19 @@ 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(),
// we want singular name (Serviceaccount), not plural (serviceaccounts)
// obj.GetKind() returns ServiceAccount, not Serviceaccount and was causing issues
// so we lowercase it here and in the KindMap that is used in discovery
Kind: strings.ToLower(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() {
Expand All @@ -1084,6 +1097,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)
Expand Down Expand Up @@ -1478,22 +1495,6 @@ func (ctx *restoreContext) restoreItem(obj *unstructured.Unstructured, groupReso
}
}

// Check if cluster has GVK required to restore resource, otherwise return err.
// Placed here because the object apiVersion might get modified by a RestorePlugin
// So we check for the GVK after the RestorePlugin has run.
_, _, err = ctx.discoveryHelper.KindFor(schema.GroupVersionKind{
Group: groupResource.Group,
Version: obj.GetAPIVersion(),
Kind: groupResource.Resource,
})
clusterHasKind := err == nil
if !clusterHasKind {
ctx.log.Errorf("Cannot restore %s because GVK doesn't exist in the cluster", groupResource)
// Adding to errs should cause restore to partially fail
errs.Add(namespace, fmt.Errorf("cannot restore %s because gvk doesn't exist in the cluster", groupResource))
return warnings, errs, itemExists
}

// Necessary because we may have remapped the namespace if the namespace is
// blank, don't create the key.
originalNamespace := obj.GetNamespace()
Expand Down

0 comments on commit 94f9e89

Please sign in to comment.