2022-12-19 02:08:46 -05:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
package kubecmd
|
2022-12-19 02:08:46 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"path/filepath"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/edgelesssys/constellation/v2/internal/file"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/spf13/afero"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
2023-07-27 04:28:56 -04:00
|
|
|
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
2022-12-19 02:08:46 -05:00
|
|
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime/schema"
|
|
|
|
"sigs.k8s.io/yaml"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestBackupCRDs(t *testing.T) {
|
|
|
|
testCases := map[string]struct {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID string
|
2022-12-19 02:08:46 -05:00
|
|
|
crd string
|
|
|
|
expectedFile string
|
|
|
|
getCRDsError error
|
|
|
|
wantError bool
|
|
|
|
}{
|
|
|
|
"success": {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID: "1234",
|
2022-12-19 02:08:46 -05:00
|
|
|
crd: "apiVersion: \nkind: \nmetadata:\n name: foobar\n creationTimestamp: null\nspec:\n group: \"\"\n names:\n kind: \"somename\"\n plural: \"somenames\"\n scope: \"\"\n versions: null\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: null\n storedVersions: null\n",
|
|
|
|
expectedFile: "apiVersion: apiextensions.k8s.io/v1\nkind: CustomResourceDefinition\nmetadata:\n name: foobar\n creationTimestamp: null\nspec:\n group: \"\"\n names:\n kind: \"somename\"\n plural: \"somenames\"\n scope: \"\"\n versions: null\nstatus:\n acceptedNames:\n kind: \"\"\n plural: \"\"\n conditions: null\n storedVersions: null\n",
|
|
|
|
},
|
|
|
|
"api request fails": {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID: "1234",
|
2022-12-19 02:08:46 -05:00
|
|
|
getCRDsError: errors.New("api error"),
|
|
|
|
wantError: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
require := require.New(t)
|
|
|
|
memFs := afero.NewMemMapFs()
|
|
|
|
|
|
|
|
crd := apiextensionsv1.CustomResourceDefinition{}
|
|
|
|
err := yaml.Unmarshal([]byte(tc.crd), &crd)
|
|
|
|
require.NoError(err)
|
2023-08-24 10:40:47 -04:00
|
|
|
client := KubeCmd{
|
|
|
|
kubectl: &stubKubectl{crds: []apiextensionsv1.CustomResourceDefinition{crd}, getCRDsError: tc.getCRDsError},
|
|
|
|
fileHandler: file.NewHandler(memFs),
|
|
|
|
log: stubLog{},
|
2022-12-19 02:08:46 -05:00
|
|
|
}
|
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
_, err = client.BackupCRDs(context.Background(), tc.upgradeID)
|
2022-12-19 02:08:46 -05:00
|
|
|
if tc.wantError {
|
|
|
|
assert.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert.NoError(err)
|
|
|
|
|
2023-06-21 03:22:32 -04:00
|
|
|
data, err := afero.ReadFile(memFs, filepath.Join(client.crdBackupFolder(tc.upgradeID), crd.Name+".yaml"))
|
2022-12-19 02:08:46 -05:00
|
|
|
require.NoError(err)
|
|
|
|
assert.YAMLEq(tc.expectedFile, string(data))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestBackupCRs(t *testing.T) {
|
|
|
|
testCases := map[string]struct {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID string
|
2022-12-19 02:08:46 -05:00
|
|
|
crd apiextensionsv1.CustomResourceDefinition
|
|
|
|
resource unstructured.Unstructured
|
|
|
|
expectedFile string
|
|
|
|
getCRsError error
|
|
|
|
wantError bool
|
|
|
|
}{
|
|
|
|
"success": {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID: "1234",
|
2022-12-19 02:08:46 -05:00
|
|
|
crd: apiextensionsv1.CustomResourceDefinition{
|
|
|
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
|
|
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
|
|
|
Plural: "foobars",
|
|
|
|
},
|
|
|
|
Group: "some.group",
|
|
|
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
|
|
|
{
|
|
|
|
Name: "versionZero",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
resource: unstructured.Unstructured{Object: map[string]any{"metadata": map[string]any{"name": "foobar"}}},
|
|
|
|
expectedFile: "metadata:\n name: foobar\n",
|
|
|
|
},
|
|
|
|
"api request fails": {
|
2023-06-21 03:22:32 -04:00
|
|
|
upgradeID: "1234",
|
2022-12-19 02:08:46 -05:00
|
|
|
crd: apiextensionsv1.CustomResourceDefinition{
|
|
|
|
Spec: apiextensionsv1.CustomResourceDefinitionSpec{
|
|
|
|
Names: apiextensionsv1.CustomResourceDefinitionNames{
|
|
|
|
Plural: "foobars",
|
|
|
|
},
|
|
|
|
Group: "some.group",
|
|
|
|
Versions: []apiextensionsv1.CustomResourceDefinitionVersion{
|
|
|
|
{
|
|
|
|
Name: "versionZero",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
getCRsError: errors.New("api error"),
|
|
|
|
wantError: true,
|
|
|
|
},
|
2023-07-27 04:28:56 -04:00
|
|
|
"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"),
|
|
|
|
},
|
2022-12-19 02:08:46 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for name, tc := range testCases {
|
|
|
|
t.Run(name, func(t *testing.T) {
|
|
|
|
assert := assert.New(t)
|
|
|
|
require := require.New(t)
|
|
|
|
memFs := afero.NewMemMapFs()
|
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
client := KubeCmd{
|
|
|
|
kubectl: &stubKubectl{crs: []unstructured.Unstructured{tc.resource}, getCRsError: tc.getCRsError},
|
|
|
|
fileHandler: file.NewHandler(memFs),
|
|
|
|
log: stubLog{},
|
2022-12-19 02:08:46 -05:00
|
|
|
}
|
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
err := client.BackupCRs(context.Background(), []apiextensionsv1.CustomResourceDefinition{tc.crd}, tc.upgradeID)
|
2022-12-19 02:08:46 -05:00
|
|
|
if tc.wantError {
|
|
|
|
assert.Error(err)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
assert.NoError(err)
|
|
|
|
|
2023-06-21 03:22:32 -04:00
|
|
|
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"))
|
2023-07-27 04:28:56 -04:00
|
|
|
if tc.expectedFile == "" {
|
|
|
|
assert.Error(err)
|
|
|
|
return
|
|
|
|
}
|
2022-12-19 02:08:46 -05:00
|
|
|
require.NoError(err)
|
|
|
|
assert.YAMLEq(tc.expectedFile, string(data))
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type stubLog struct{}
|
|
|
|
|
2023-03-20 06:03:36 -04:00
|
|
|
func (s stubLog) Debugf(_ string, _ ...any) {}
|
|
|
|
func (s stubLog) Sync() {}
|
2022-12-19 02:08:46 -05:00
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
func (c stubKubectl) ListCRDs(_ context.Context) ([]apiextensionsv1.CustomResourceDefinition, error) {
|
2022-12-19 02:08:46 -05:00
|
|
|
if c.getCRDsError != nil {
|
|
|
|
return nil, c.getCRDsError
|
|
|
|
}
|
|
|
|
return c.crds, nil
|
|
|
|
}
|
|
|
|
|
2023-08-24 10:40:47 -04:00
|
|
|
func (c stubKubectl) ListCRs(_ context.Context, _ schema.GroupVersionResource) ([]unstructured.Unstructured, error) {
|
2022-12-19 02:08:46 -05:00
|
|
|
if c.getCRsError != nil {
|
|
|
|
return nil, c.getCRsError
|
|
|
|
}
|
|
|
|
return c.crs, nil
|
|
|
|
}
|