diff --git a/util/util.go b/util/util.go index 3b624ab624c9..c593c427f0ca 100644 --- a/util/util.go +++ b/util/util.go @@ -32,6 +32,7 @@ import ( corev1 "k8s.io/api/core/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/meta" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -493,15 +494,30 @@ func ClusterToObjectsMapper(c client.Client, ro runtime.Object, scheme *runtime. return nil, err } + isNamespaced, err := isAPINamespaced(gvk, c.RESTMapper()) + if err != nil { + return nil, err + } + return func(o client.Object) []ctrl.Request { cluster, ok := o.(*clusterv1.Cluster) if !ok { return nil } + listOpts := []client.ListOption{ + client.MatchingLabels{ + clusterv1.ClusterLabelName: cluster.Name, + }, + } + + if isNamespaced { + listOpts = append(listOpts, client.InNamespace(cluster.Namespace)) + } + list := &unstructured.UnstructuredList{} list.SetGroupVersionKind(gvk) - if err := c.List(context.TODO(), list, client.MatchingLabels{clusterv1.ClusterLabelName: cluster.Name}); err != nil { + if err := c.List(context.TODO(), list, listOpts...); err != nil { return nil } @@ -515,6 +531,25 @@ func ClusterToObjectsMapper(c client.Client, ro runtime.Object, scheme *runtime. }, nil } +// isAPINamespaced detects if a GroupVersionKind is namespaced. +func isAPINamespaced(gk schema.GroupVersionKind, restmapper meta.RESTMapper) (bool, error) { + restmapping, err := restmapper.RESTMapping(schema.GroupKind{Group: gk.Group, Kind: gk.Kind}) + if err != nil { + return false, fmt.Errorf("failed to get restmapping: %w", err) + } + + scope := restmapping.Scope.Name() + + if scope == "" { + return false, errors.New("Scope cannot be identified. Empty scope returned") + } + + if scope != meta.RESTScopeNameRoot { + return true, nil + } + return false, nil +} + // ObjectReferenceToUnstructured converts an object reference to an unstructured object. func ObjectReferenceToUnstructured(in corev1.ObjectReference) *unstructured.Unstructured { out := &unstructured.Unstructured{}