From 28e29ffe61f9a55e1898261a82096af42c812f62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Wei=C3=9Fe?= <66256922+daniel-weisse@users.noreply.github.com> Date: Thu, 27 Jul 2023 10:28:56 +0200 Subject: [PATCH] cli: don't backup CRs that cannot be found (#2133) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Weiße --- cli/internal/helm/BUILD.bazel | 2 ++ cli/internal/helm/backup.go | 15 ++++++++++++++- cli/internal/helm/backup_test.go | 22 ++++++++++++++++++++++ internal/kubernetes/kubectl/kubectl.go | 2 +- 4 files changed, 39 insertions(+), 2 deletions(-) diff --git a/cli/internal/helm/BUILD.bazel b/cli/internal/helm/BUILD.bazel index 05b8d3279..25aa7e756 100644 --- a/cli/internal/helm/BUILD.bazel +++ b/cli/internal/helm/BUILD.bazel @@ -427,6 +427,7 @@ go_library( "@com_github_pkg_errors//:errors", "@com_github_spf13_afero//:afero", "@io_k8s_apiextensions_apiserver//pkg/apis/apiextensions/v1:apiextensions", + "@io_k8s_apimachinery//pkg/api/errors", "@io_k8s_apimachinery//pkg/apis/meta/v1/unstructured", "@io_k8s_apimachinery//pkg/runtime/schema", "@io_k8s_sigs_yaml//:yaml", @@ -465,6 +466,7 @@ go_test( "@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//require", "@io_k8s_apiextensions_apiserver//pkg/apis/apiextensions/v1:apiextensions", + "@io_k8s_apimachinery//pkg/api/errors", "@io_k8s_apimachinery//pkg/apis/meta/v1/unstructured", "@io_k8s_apimachinery//pkg/runtime/schema", "@io_k8s_sigs_yaml//:yaml", diff --git a/cli/internal/helm/backup.go b/cli/internal/helm/backup.go index 35deea614..162c71a9e 100644 --- a/cli/internal/helm/backup.go +++ b/cli/internal/helm/backup.go @@ -13,6 +13,7 @@ import ( "github.com/edgelesssys/constellation/v2/internal/constants" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" ) @@ -56,11 +57,23 @@ func (c *Client) backupCRs(ctx context.Context, crds []apiextensionsv1.CustomRes c.log.Debugf("Starting CR backup") for _, crd := range crds { c.log.Debugf("Creating backup for resource type: %s", crd.Name) + + // Iterate over all versions of the CRD + // TODO: Consider iterating over crd.Status.StoredVersions instead + // Currently, we have to ignore not-found errors, because a CRD might define + // a version that is not installed in the cluster. + // With the StoredVersions field, we could only iterate over the installed versions. for _, version := range crd.Spec.Versions { + c.log.Debugf("Creating backup of CRs for %q at version %q", crd.Name, version.Name) + gvr := schema.GroupVersionResource{Group: crd.Spec.Group, Version: version.Name, Resource: crd.Spec.Names.Plural} crs, err := c.kubectl.GetCRs(ctx, gvr) if err != nil { - return fmt.Errorf("retrieving CR %s: %w", crd.Name, err) + if !k8serrors.IsNotFound(err) { + return fmt.Errorf("retrieving CR %s: %w", crd.Name, err) + } + c.log.Debugf("No CRs found for %q at version %q, skipping...", crd.Name, version.Name) + continue } backupFolder := c.backupFolder(upgradeID) diff --git a/cli/internal/helm/backup_test.go b/cli/internal/helm/backup_test.go index ea87015e7..1533c7b31 100644 --- a/cli/internal/helm/backup_test.go +++ b/cli/internal/helm/backup_test.go @@ -17,6 +17,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" @@ -117,6 +118,23 @@ func TestBackupCRs(t *testing.T) { getCRsError: errors.New("api error"), wantError: true, }, + "custom resource not found": { + upgradeID: "1234", + crd: apiextensionsv1.CustomResourceDefinition{ + Spec: apiextensionsv1.CustomResourceDefinitionSpec{ + Names: apiextensionsv1.CustomResourceDefinitionNames{ + Plural: "foobars", + }, + Group: "some.group", + Versions: []apiextensionsv1.CustomResourceDefinitionVersion{ + { + Name: "versionZero", + }, + }, + }, + }, + getCRsError: k8serrors.NewNotFound(schema.GroupResource{Group: "some.group"}, "foobars"), + }, } for name, tc := range testCases { @@ -140,6 +158,10 @@ func TestBackupCRs(t *testing.T) { assert.NoError(err) data, err := afero.ReadFile(memFs, filepath.Join(client.backupFolder(tc.upgradeID), tc.crd.Spec.Group, tc.crd.Spec.Versions[0].Name, tc.resource.GetNamespace(), tc.resource.GetKind(), tc.resource.GetName()+".yaml")) + if tc.expectedFile == "" { + assert.Error(err) + return + } require.NoError(err) assert.YAMLEq(tc.expectedFile, string(data)) }) diff --git a/internal/kubernetes/kubectl/kubectl.go b/internal/kubernetes/kubectl/kubectl.go index b90edb26e..bfafd9492 100644 --- a/internal/kubernetes/kubectl/kubectl.go +++ b/internal/kubernetes/kubectl/kubectl.go @@ -99,7 +99,7 @@ func (k *Kubectl) GetCRs(ctx context.Context, gvr schema.GroupVersionResource) ( crdClient := k.dynamicClient.Resource(gvr) unstructuredList, err := crdClient.List(ctx, metav1.ListOptions{}) if err != nil { - return nil, fmt.Errorf("listing CRDs for gvr %+v: %w", crdClient, err) + return nil, fmt.Errorf("listing CRs for GroupVersionResource %+v: %w", gvr, err) } return unstructuredList.Items, nil