// listCollection will list the items in the specified namespace // it returns the following: // the list of items in the collection (if found) // a boolean if the operation is supported // an error if the operation is supported but could not be completed. func listCollection( dynamicClient *dynamic.Client, opCache operationNotSupportedCache, gvr unversioned.GroupVersionResource, namespace string, ) (*runtime.UnstructuredList, bool, error) { glog.V(5).Infof("namespace controller - listCollection - namespace: %s, gvr: %v", namespace, gvr) key := operationKey{op: operationList, gvr: gvr} if !opCache.isSupported(key) { glog.V(5).Infof("namespace controller - listCollection ignored since not supported - namespace: %s, gvr: %v", namespace, gvr) return nil, false, nil } apiResource := unversioned.APIResource{Name: gvr.Resource, Namespaced: true} unstructuredList, err := dynamicClient.Resource(&apiResource, namespace).List(&v1.ListOptions{}) if err == nil { return unstructuredList, true, nil } // this is strange, but we need to special case for both MethodNotSupported and NotFound errors // TODO: https://github.com/kubernetes/kubernetes/issues/22413 // we have a resource returned in the discovery API that supports no top-level verbs: // /apis/extensions/v1beta1/namespaces/default/replicationcontrollers // when working with this resource type, we will get a literal not found error rather than expected method not supported // remember next time that this resource does not support delete collection... if errors.IsMethodNotSupported(err) || errors.IsNotFound(err) { glog.V(5).Infof("namespace controller - listCollection not supported - namespace: %s, gvr: %v", namespace, gvr) opCache[key] = true return nil, false, nil } return nil, true, err }
// deleteEachItem is a helper function that will list the collection of resources and delete each item 1 by 1. func deleteEachItem( dynamicClient *dynamic.Client, opCache operationNotSupportedCache, gvr unversioned.GroupVersionResource, namespace string, ) error { glog.V(5).Infof("namespace controller - deleteEachItem - namespace: %s, gvr: %v", namespace, gvr) unstructuredList, listSupported, err := listCollection(dynamicClient, opCache, gvr, namespace) if err != nil { return err } if !listSupported { return nil } apiResource := unversioned.APIResource{Name: gvr.Resource, Namespaced: true} for _, item := range unstructuredList.Items { if err = dynamicClient.Resource(&apiResource, namespace).Delete(item.GetName(), nil); err != nil && !errors.IsNotFound(err) && !errors.IsMethodNotSupported(err) { return err } } return nil }