in pkg/controllers/clusterresourceplacement/resource_selector.go [167:236]
func (r *Reconciler) fetchClusterScopedResources(selector fleetv1beta1.ClusterResourceSelector, placeName string) ([]runtime.Object, error) {
klog.V(2).InfoS("start to fetch the cluster scoped resources by the selector", "selector", selector)
gk := schema.GroupKind{
Group: selector.Group,
Kind: selector.Kind,
}
restMapping, err := r.RestMapper.RESTMapping(gk, selector.Version)
if err != nil {
return nil, controller.NewUserError(fmt.Errorf("invalid placement %s, failed to get GVR of the selector: %w", placeName, err))
}
gvr := restMapping.Resource
gvk := schema.GroupVersionKind{
Group: selector.Group,
Version: selector.Version,
Kind: selector.Kind,
}
if !r.InformerManager.IsClusterScopedResources(gvk) {
return nil, controller.NewUserError(fmt.Errorf("invalid placement %s: %+v is not a cluster scoped resource", placeName, restMapping.Resource))
}
if !r.InformerManager.IsInformerSynced(gvr) {
return nil, controller.NewExpectedBehaviorError(fmt.Errorf("informer cache for %+v is not synced yet", restMapping.Resource))
}
lister := r.InformerManager.Lister(gvr)
// TODO: validator should enforce the mutual exclusiveness between the `name` and `labelSelector` fields
if len(selector.Name) != 0 {
obj, err := lister.Get(selector.Name)
if err != nil {
klog.ErrorS(err, "cannot get the resource", "gvr", gvr, "name", selector.Name)
return nil, controller.NewAPIServerError(true, client.IgnoreNotFound(err))
}
uObj := obj.DeepCopyObject().(*unstructured.Unstructured)
if uObj.GetDeletionTimestamp() != nil {
// skip a to be deleted namespace
klog.V(2).InfoS("skip the deleting cluster scoped resources by the selector",
"selector", selector, "placeName", placeName, "resource name", uObj.GetName())
return []runtime.Object{}, nil
}
return []runtime.Object{obj}, nil
}
var labelSelector labels.Selector
if selector.LabelSelector == nil {
labelSelector = labels.Everything()
} else {
// TODO: validator should enforce the validity of the labelSelector
labelSelector, err = metav1.LabelSelectorAsSelector(selector.LabelSelector)
if err != nil {
return nil, controller.NewUnexpectedBehaviorError(fmt.Errorf("cannot convert the label selector to a selector: %w", err))
}
}
var selectedObjs []runtime.Object
objects, err := lister.List(labelSelector)
if err != nil {
return nil, controller.NewAPIServerError(true, fmt.Errorf("cannot list all the objects: %w", err))
}
// go ahead and claim all objects by adding a finalizer and insert the placement in its annotation
for i := 0; i < len(objects); i++ {
uObj := objects[i].DeepCopyObject().(*unstructured.Unstructured)
if uObj.GetDeletionTimestamp() != nil {
// skip a to be deleted namespace
klog.V(2).InfoS("skip the deleting cluster scoped resources by the selector",
"selector", selector, "placeName", placeName, "resource name", uObj.GetName())
continue
}
selectedObjs = append(selectedObjs, objects[i])
}
return selectedObjs, nil
}