mirror of https://github.com/fluxcd/cli-utils.git
Skip pruning an object whose Group/Kind is not found
This commit is contained in:
parent
d50496a12b
commit
f0e71ba543
|
|
@ -166,14 +166,17 @@ func (po *PruneOptions) GetPruneObjs(inv inventory.InventoryInfo,
|
||||||
for _, pruneID := range pruneIds {
|
for _, pruneID := range pruneIds {
|
||||||
pruneObj, err := po.GetObject(pruneID)
|
pruneObj, err := po.GetObject(pruneID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If prune object is not in cluster, no need to prune it--skip.
|
if meta.IsNoMatchError(err) {
|
||||||
if apierrors.IsNotFound(err) {
|
klog.V(4).Infof("skip pruning obj %s/%s: the resource type is unrecognized by the cluster (kind: %s, group %s)",
|
||||||
klog.V(4).Infof("prune obj not in cluster--skip (%s/%s)",
|
pruneID.Namespace, pruneID.Name, pruneID.GroupKind.Kind, pruneID.GroupKind.Group)
|
||||||
|
continue
|
||||||
|
} else if apierrors.IsNotFound(err) {
|
||||||
|
// If prune object is not in cluster, no need to prune it--skip.
|
||||||
|
klog.V(4).Infof("skip pruning obj %s/%s: not found in the cluster",
|
||||||
pruneID.Namespace, pruneID.Name)
|
pruneID.Namespace, pruneID.Name)
|
||||||
continue
|
continue
|
||||||
} else {
|
|
||||||
return nil, err
|
|
||||||
}
|
}
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
pruneObjs = append(pruneObjs, pruneObj)
|
pruneObjs = append(pruneObjs, pruneObj)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,8 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
|
"k8s.io/apimachinery/pkg/api/meta/testrestmapper"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||||
|
|
@ -110,6 +112,14 @@ var pdbDeleteFailure = &unstructured.Unstructured{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var crontabCRManifest = `
|
||||||
|
apiVersion: "stable.example.com/v1"
|
||||||
|
kind: CronTab
|
||||||
|
metadata:
|
||||||
|
name: cron-tab-01
|
||||||
|
namespace: test-namespace
|
||||||
|
`
|
||||||
|
|
||||||
// Returns a inventory object with the inventory set from
|
// Returns a inventory object with the inventory set from
|
||||||
// the passed "children".
|
// the passed "children".
|
||||||
func createInventoryInfo(children ...*unstructured.Unstructured) inventory.InventoryInfo {
|
func createInventoryInfo(children ...*unstructured.Unstructured) inventory.InventoryInfo {
|
||||||
|
|
@ -549,6 +559,11 @@ func TestGetPruneObjs(t *testing.T) {
|
||||||
prevInventory: []*unstructured.Unstructured{pod, pdb, namespace},
|
prevInventory: []*unstructured.Unstructured{pod, pdb, namespace},
|
||||||
expectedObjs: []*unstructured.Unstructured{pod, namespace},
|
expectedObjs: []*unstructured.Unstructured{pod, namespace},
|
||||||
},
|
},
|
||||||
|
"skip pruning objects whose resource types are unrecognized by the cluster": {
|
||||||
|
localObjs: []*unstructured.Unstructured{pdb},
|
||||||
|
prevInventory: []*unstructured.Unstructured{testutil.Unstructured(t, crontabCRManifest), pdb, namespace},
|
||||||
|
expectedObjs: []*unstructured.Unstructured{namespace},
|
||||||
|
},
|
||||||
"local objs, inventory disjoint means inventory is pruned": {
|
"local objs, inventory disjoint means inventory is pruned": {
|
||||||
localObjs: []*unstructured.Unstructured{pdb},
|
localObjs: []*unstructured.Unstructured{pdb},
|
||||||
prevInventory: []*unstructured.Unstructured{pod, namespace},
|
prevInventory: []*unstructured.Unstructured{pod, namespace},
|
||||||
|
|
@ -588,6 +603,40 @@ func TestGetPruneObjs(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetObject_NoMatchError(t *testing.T) {
|
||||||
|
po := PruneOptions{
|
||||||
|
Client: fake.NewSimpleDynamicClient(scheme.Scheme, pod, namespace),
|
||||||
|
Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme,
|
||||||
|
scheme.Scheme.PrioritizedVersionsAllGroups()...),
|
||||||
|
}
|
||||||
|
_, err := po.GetObject(testutil.ToIdentifier(t, crontabCRManifest))
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected GetObject() to return a NoKindMatchError, got nil")
|
||||||
|
}
|
||||||
|
if !meta.IsNoMatchError(err) {
|
||||||
|
t.Fatalf("expected GetObject() to return a NoKindMatchError, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetObject_NotFoundError(t *testing.T) {
|
||||||
|
po := PruneOptions{
|
||||||
|
Client: fake.NewSimpleDynamicClient(scheme.Scheme, pod, namespace),
|
||||||
|
Mapper: testrestmapper.TestOnlyStaticRESTMapper(scheme.Scheme,
|
||||||
|
scheme.Scheme.PrioritizedVersionsAllGroups()...),
|
||||||
|
}
|
||||||
|
objMeta, err := object.UnstructuredToObjMeta(pdb)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("unexpected error %s returned", err)
|
||||||
|
}
|
||||||
|
_, err = po.GetObject(objMeta)
|
||||||
|
if err == nil {
|
||||||
|
t.Fatalf("expected GetObject() to return a NotFound error, got nil")
|
||||||
|
}
|
||||||
|
if !apierrors.IsNotFound(err) {
|
||||||
|
t.Fatalf("expected GetObject() to return a NotFound error, got %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type optionsCaptureNamespaceClient struct {
|
type optionsCaptureNamespaceClient struct {
|
||||||
dynamic.ResourceInterface
|
dynamic.ResourceInterface
|
||||||
options metav1.DeleteOptions
|
options metav1.DeleteOptions
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue