cli: don't backup CRs that cannot be found (#2133)

Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
Daniel Weiße 2023-07-27 10:28:56 +02:00 committed by GitHub
parent a3184af7a2
commit 28e29ffe61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 39 additions and 2 deletions

View File

@ -427,6 +427,7 @@ go_library(
"@com_github_pkg_errors//:errors", "@com_github_pkg_errors//:errors",
"@com_github_spf13_afero//:afero", "@com_github_spf13_afero//:afero",
"@io_k8s_apiextensions_apiserver//pkg/apis/apiextensions/v1:apiextensions", "@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/apis/meta/v1/unstructured",
"@io_k8s_apimachinery//pkg/runtime/schema", "@io_k8s_apimachinery//pkg/runtime/schema",
"@io_k8s_sigs_yaml//:yaml", "@io_k8s_sigs_yaml//:yaml",
@ -465,6 +466,7 @@ go_test(
"@com_github_stretchr_testify//assert", "@com_github_stretchr_testify//assert",
"@com_github_stretchr_testify//require", "@com_github_stretchr_testify//require",
"@io_k8s_apiextensions_apiserver//pkg/apis/apiextensions/v1:apiextensions", "@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/apis/meta/v1/unstructured",
"@io_k8s_apimachinery//pkg/runtime/schema", "@io_k8s_apimachinery//pkg/runtime/schema",
"@io_k8s_sigs_yaml//:yaml", "@io_k8s_sigs_yaml//:yaml",

View File

@ -13,6 +13,7 @@ import (
"github.com/edgelesssys/constellation/v2/internal/constants" "github.com/edgelesssys/constellation/v2/internal/constants"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
@ -56,12 +57,24 @@ func (c *Client) backupCRs(ctx context.Context, crds []apiextensionsv1.CustomRes
c.log.Debugf("Starting CR backup") c.log.Debugf("Starting CR backup")
for _, crd := range crds { for _, crd := range crds {
c.log.Debugf("Creating backup for resource type: %s", crd.Name) 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 { 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} gvr := schema.GroupVersionResource{Group: crd.Spec.Group, Version: version.Name, Resource: crd.Spec.Names.Plural}
crs, err := c.kubectl.GetCRs(ctx, gvr) crs, err := c.kubectl.GetCRs(ctx, gvr)
if err != nil { if err != nil {
if !k8serrors.IsNotFound(err) {
return fmt.Errorf("retrieving CR %s: %w", crd.Name, 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) backupFolder := c.backupFolder(upgradeID)
for _, cr := range crs { for _, cr := range crs {

View File

@ -17,6 +17,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" 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/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
@ -117,6 +118,23 @@ func TestBackupCRs(t *testing.T) {
getCRsError: errors.New("api error"), getCRsError: errors.New("api error"),
wantError: true, 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 { for name, tc := range testCases {
@ -140,6 +158,10 @@ func TestBackupCRs(t *testing.T) {
assert.NoError(err) 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")) 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) require.NoError(err)
assert.YAMLEq(tc.expectedFile, string(data)) assert.YAMLEq(tc.expectedFile, string(data))
}) })

View File

@ -99,7 +99,7 @@ func (k *Kubectl) GetCRs(ctx context.Context, gvr schema.GroupVersionResource) (
crdClient := k.dynamicClient.Resource(gvr) crdClient := k.dynamicClient.Resource(gvr)
unstructuredList, err := crdClient.List(ctx, metav1.ListOptions{}) unstructuredList, err := crdClient.List(ctx, metav1.ListOptions{})
if err != nil { 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 return unstructuredList.Items, nil