mirror of
https://github.com/edgelesssys/constellation.git
synced 2025-02-23 08:20:15 -05:00
cli: don't backup CRs that cannot be found (#2133)
Signed-off-by: Daniel Weiße <dw@edgeless.systems>
This commit is contained in:
parent
a3184af7a2
commit
28e29ffe61
@ -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",
|
||||||
|
@ -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 {
|
||||||
|
@ -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))
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user