diff --git a/e2e/backup/backup_test.go b/e2e/backup/backup_test.go index ae0169d6..f48fdf3f 100644 --- a/e2e/backup/backup_test.go +++ b/e2e/backup/backup_test.go @@ -7,13 +7,14 @@ import ( "sync" "time" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" + . "github.com/kralicky/kmatch" "github.com/minio/minio-go/v7" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/rancher/backup-restore-operator/e2e/test" backupv1 "github.com/rancher/backup-restore-operator/pkg/apis/resources.cattle.io/v1" - backuputil "github.com/rancher/backup-restore-operator/pkg/util" "github.com/rancher/wrangler/v3/pkg/condition" "github.com/samber/lo" "github.com/testcontainers/testcontainers-go" @@ -301,7 +302,7 @@ var _ = Describe("Backup e2e local driver", Ordered, Label("integration"), func( Namespace: ts.ChartNamespace, }, Data: map[string][]byte{ - backuputil.EncryptionProviderConfigKey: payload, + encryptionconfig.EncryptionProviderConfigKey: payload, }, } o.Add(secret) diff --git a/e2e/backup/setup_test.go b/e2e/backup/setup_test.go index bde6207f..e4c80bdf 100644 --- a/e2e/backup/setup_test.go +++ b/e2e/backup/setup_test.go @@ -4,6 +4,8 @@ import ( "context" "fmt" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" + . "github.com/kralicky/kmatch" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" @@ -12,7 +14,6 @@ import ( "github.com/rancher/backup-restore-operator/e2e/test" backupv1 "github.com/rancher/backup-restore-operator/pkg/apis/resources.cattle.io/v1" "github.com/rancher/backup-restore-operator/pkg/operator" - backuputil "github.com/rancher/backup-restore-operator/pkg/util" "github.com/testcontainers/testcontainers-go" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -49,7 +50,7 @@ func SetupEncryption(o *ObjectTracker) { Namespace: ts.ChartNamespace, }, Data: map[string][]byte{ - backuputil.EncryptionProviderConfigKey: payload, + encryptionconfig.EncryptionProviderConfigKey: payload, }, } o.Add(encsecret) diff --git a/pkg/controllers/backup/controller.go b/pkg/controllers/backup/controller.go index c48c3fcd..87c1930b 100644 --- a/pkg/controllers/backup/controller.go +++ b/pkg/controllers/backup/controller.go @@ -14,6 +14,7 @@ import ( backupControllers "github.com/rancher/backup-restore-operator/pkg/generated/controllers/resources.cattle.io/v1" "github.com/rancher/backup-restore-operator/pkg/resourcesets" "github.com/rancher/backup-restore-operator/pkg/util" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" "github.com/rancher/wrangler/v3/pkg/condition" v1core "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/rancher/wrangler/v3/pkg/genericcondition" @@ -22,8 +23,7 @@ import ( "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" k8sv1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/storage/value" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" "k8s.io/client-go/util/retry" @@ -215,10 +215,15 @@ func (h *handler) OnBackupChange(_ string, backup *v1.Backup) (*v1.Backup, error func (h *handler) performBackup(backup *v1.Backup, tmpBackupPath, backupFileName string) error { var err error - transformerMap := make(map[schema.GroupResource]value.Transformer) + transformerMap := k8sEncryptionconfig.StaticTransformers{} if backup.Spec.EncryptionConfigSecretName != "" { logrus.Infof("Processing encryption config %v for backup CR %v", backup.Spec.EncryptionConfigSecretName, backup.Name) - transformerMap, err = util.GetEncryptionTransformersFromSecret(backup.Spec.EncryptionConfigSecretName, h.secrets) + encryptionConfigSecret, err := encryptionconfig.GetEncryptionConfigSecret(h.secrets, backup.Spec.EncryptionConfigSecretName) + if err != nil { + return err + } + + transformerMap, err = encryptionconfig.GetEncryptionTransformersFromSecret(h.ctx, encryptionConfigSecret) if err != nil { return err } diff --git a/pkg/controllers/restore/controller.go b/pkg/controllers/restore/controller.go index 9bad18d2..a3e3c60c 100644 --- a/pkg/controllers/restore/controller.go +++ b/pkg/controllers/restore/controller.go @@ -12,6 +12,7 @@ import ( v1 "github.com/rancher/backup-restore-operator/pkg/apis/resources.cattle.io/v1" restoreControllers "github.com/rancher/backup-restore-operator/pkg/generated/controllers/resources.cattle.io/v1" "github.com/rancher/backup-restore-operator/pkg/util" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" lasso "github.com/rancher/lasso/pkg/client" "github.com/rancher/wrangler/v3/pkg/condition" v1core "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" @@ -28,7 +29,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/apiserver/pkg/storage/value" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" coordinationclientv1 "k8s.io/client-go/kubernetes/typed/coordination/v1" @@ -156,11 +157,17 @@ func (h *handler) OnRestoreChange(_ string, restore *v1.Restore) (*v1.Restore, e backupResourceSet: v1.ResourceSet{}, } - transformerMap := make(map[schema.GroupResource]value.Transformer) + transformerMap := k8sEncryptionconfig.StaticTransformers{} var err error if restore.Spec.EncryptionConfigSecretName != "" { logrus.Infof("Processing encryption config %v for restore CR %v", restore.Spec.EncryptionConfigSecretName, restore.Name) - transformerMap, err = util.GetEncryptionTransformersFromSecret(restore.Spec.EncryptionConfigSecretName, h.secrets) + encryptionConfigSecret, err := encryptionconfig.GetEncryptionConfigSecret(h.secrets, restore.Spec.EncryptionConfigSecretName) + if err != nil { + logrus.Errorf("Error fetching encryption config secret: %v", err) + return h.setReconcilingCondition(restore, err) + } + + transformerMap, err = encryptionconfig.GetEncryptionTransformersFromSecret(h.ctx, encryptionConfigSecret) if err != nil { logrus.Errorf("Error processing encryption config: %v", err) return h.setReconcilingCondition(restore, err) diff --git a/pkg/controllers/restore/download.go b/pkg/controllers/restore/download.go index c003a3a7..77d0748d 100644 --- a/pkg/controllers/restore/download.go +++ b/pkg/controllers/restore/download.go @@ -10,12 +10,12 @@ import ( "strings" v1 "github.com/rancher/backup-restore-operator/pkg/apis/resources.cattle.io/v1" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" + "github.com/rancher/backup-restore-operator/pkg/objectstore" - "github.com/rancher/backup-restore-operator/pkg/util" "github.com/sirupsen/logrus" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/server/options/encryptionconfig" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/apiserver/pkg/storage/value" ) @@ -41,7 +41,7 @@ func (h *handler) downloadFromS3(restore *v1.Restore, objStore *v1.S3ObjectStore } // very initial parts: https://medium.com/@skdomino/taring-untaring-files-in-go-6b07cf56bc07 -func (h *handler) LoadFromTarGzip(tarGzFilePath string, transformerMap map[schema.GroupResource]value.Transformer, +func (h *handler) LoadFromTarGzip(tarGzFilePath string, transformerMap k8sEncryptionconfig.StaticTransformers, cr *ObjectsFromBackupCR) error { r, err := os.Open(tarGzFilePath) if err != nil { @@ -87,7 +87,7 @@ func (h *handler) LoadFromTarGzip(tarGzFilePath string, transformerMap map[schem } func (h *handler) loadDataFromFile(tarContent *tar.Header, readData []byte, - transformerMap map[schema.GroupResource]value.Transformer, cr *ObjectsFromBackupCR) error { + transformerMap k8sEncryptionconfig.StaticTransformers, cr *ObjectsFromBackupCR) error { var name, namespace, additionalAuthenticatedData string cr.resourcesFromBackup[tarContent.Name] = true @@ -106,9 +106,8 @@ func (h *handler) loadDataFromFile(tarContent *tar.Header, readData []byte, gvrStr := splitPath[0] gvr := getGVR(gvrStr) - var staticTransformers encryptionconfig.StaticTransformers = transformerMap - decryptionTransformer := staticTransformers.TransformerForResource(gvr.GroupResource()) - if decryptionTransformer != nil && !util.IsDefaultEncryptionTransformer(decryptionTransformer) { + decryptionTransformer := transformerMap.TransformerForResource(gvr.GroupResource()) + if decryptionTransformer != nil && !encryptionconfig.IsDefaultEncryptionTransformer(decryptionTransformer) { var encryptedBytes []byte if err := json.Unmarshal(readData, &encryptedBytes); err != nil { logrus.Errorf("Error unmarshaling encrypted data for resource [%v]: %v", gvr.GroupResource(), err) diff --git a/pkg/controllers/restore/prune.go b/pkg/controllers/restore/prune.go index 3ae086c4..30bca678 100644 --- a/pkg/controllers/restore/prune.go +++ b/pkg/controllers/restore/prune.go @@ -14,7 +14,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" k8sv1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/storage/value" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/client-go/dynamic" ) @@ -24,7 +24,7 @@ type pruneResourceInfo struct { gvr schema.GroupVersionResource } -func (h *handler) prune(resourceSelectors []v1.ResourceSelector, transformerMap map[schema.GroupResource]value.Transformer, +func (h *handler) prune(resourceSelectors []v1.ResourceSelector, transformerMap k8sEncryptionconfig.StaticTransformers, cr ObjectsFromBackupCR, deleteTimeout int) error { var resourcesToDelete []pruneResourceInfo rh := resourcesets.ResourceHandler{ diff --git a/pkg/resourcesets/collector.go b/pkg/resourcesets/collector.go index 5643a6de..fc0ac143 100644 --- a/pkg/resourcesets/collector.go +++ b/pkg/resourcesets/collector.go @@ -10,13 +10,14 @@ import ( "strings" v1 "github.com/rancher/backup-restore-operator/pkg/apis/resources.cattle.io/v1" - "github.com/rancher/backup-restore-operator/pkg/util" + "github.com/rancher/backup-restore-operator/pkg/util/encryptionconfig" + "github.com/sirupsen/logrus" apierrors "k8s.io/apimachinery/pkg/api/errors" k8sv1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/server/options/encryptionconfig" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" "k8s.io/apiserver/pkg/storage/value" "k8s.io/client-go/discovery" "k8s.io/client-go/dynamic" @@ -33,7 +34,7 @@ type GVResource struct { type ResourceHandler struct { DiscoveryClient discovery.DiscoveryInterface DynamicClient dynamic.Interface - TransformerMap map[schema.GroupResource]value.Transformer + TransformerMap k8sEncryptionconfig.StaticTransformers GVResourceToObjects map[GVResource][]unstructured.Unstructured Ctx context.Context } @@ -389,8 +390,7 @@ func (h *ResourceHandler) WriteBackupObjects(backupPath string) error { } gr := schema.ParseGroupResource(gvResource.Name + "." + gv.Group) - var staticTransformers encryptionconfig.StaticTransformers = h.TransformerMap - encryptionTransformer := staticTransformers.TransformerForResource(gr) + encryptionTransformer := h.TransformerMap.TransformerForResource(gr) additionalAuthenticatedData := objName if gvResource.Namespaced { additionalAuthenticatedData = fmt.Sprintf("%s#%s", metadata["namespace"].(string), additionalAuthenticatedData) @@ -436,7 +436,7 @@ func writeToBackup(ctx context.Context, resource map[string]interface{}, backupP if err != nil { return fmt.Errorf("error converting resource to JSON: %v", err) } - if transformer != nil && !util.IsDefaultEncryptionTransformer(transformer) { + if transformer != nil && !encryptionconfig.IsDefaultEncryptionTransformer(transformer) { encrypted, err := transformer.TransformToStorage(ctx, resourceBytes, value.DefaultContext(additionalAuthenticatedData)) if err != nil { return fmt.Errorf("error converting resource to JSON: %v", err) diff --git a/pkg/util/encryptionconfig/config.go b/pkg/util/encryptionconfig/config.go new file mode 100644 index 00000000..26e5961d --- /dev/null +++ b/pkg/util/encryptionconfig/config.go @@ -0,0 +1,78 @@ +package encryptionconfig + +import ( + "context" + "fmt" + "os" + + "github.com/rancher/backup-restore-operator/pkg/util" + v1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + + "github.com/sirupsen/logrus" + v1core "k8s.io/api/core/v1" + v2 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8sEncryptionconfig "k8s.io/apiserver/pkg/server/options/encryptionconfig" + storagevalue "k8s.io/apiserver/pkg/storage/value" + "k8s.io/apiserver/pkg/storage/value/encrypt/identity" +) + +type contextKey string + +var tempConfigPathKey = contextKey("tmpConfigPath") + +const EncryptionProviderConfigKey = "encryption-provider-config.yaml" + +func GetEncryptionConfigSecret(secrets v1.SecretController, encryptionConfigSecretName string) (*v1core.Secret, error) { + // EncryptionConfig secret ns is hardcoded to ns of controller in chart's ns + // kubectl create secret generic test-encryptionconfig --from-file=./encryption-provider-config.yaml + logrus.Infof("Get encryption config from namespace %v", util.GetChartNamespace()) + encryptionConfigSecret, err := secrets.Get(util.GetChartNamespace(), encryptionConfigSecretName, v2.GetOptions{}) + if err != nil { + return nil, err + } + + return encryptionConfigSecret, nil +} + +func GetEncryptionTransformersFromSecret(ctx context.Context, encryptionConfigSecret *v1core.Secret) (k8sEncryptionconfig.StaticTransformers, error) { + fileHandle, err := PrepareEncryptionConfigSecretTempConfig(encryptionConfigSecret) + // we defer file removal till here to ensure it's around for all of PrepareEncryptionTransformersFromConfig + defer os.Remove(EncryptionProviderConfigKey) + if err != nil { + return nil, err + } + ctx = context.WithValue(ctx, tempConfigPathKey, fileHandle.Name()) + return PrepareEncryptionTransformersFromConfig(ctx, EncryptionProviderConfigKey) +} + +func PrepareEncryptionConfigSecretTempConfig(encryptionConfigSecret *v1core.Secret) (*os.File, error) { + encryptionConfigBytes, ok := encryptionConfigSecret.Data[EncryptionProviderConfigKey] + if !ok { + return nil, fmt.Errorf("no encryptionConfig provided") + } + err := os.WriteFile(EncryptionProviderConfigKey, encryptionConfigBytes, os.ModePerm) + if err != nil { + return nil, err + } + + // Open the file for reading (or other operations) and return the handle + file, err := os.Open(EncryptionProviderConfigKey) + if err != nil { + return nil, err + } + + return file, nil +} + +func PrepareEncryptionTransformersFromConfig(ctx context.Context, encryptionProviderPath string) (k8sEncryptionconfig.StaticTransformers, error) { + apiServerID := "" + encryptionConfig, err := k8sEncryptionconfig.LoadEncryptionConfig(ctx, encryptionProviderPath, false, apiServerID) + if err != nil { + return nil, err + } + return encryptionConfig.Transformers, nil +} + +func IsDefaultEncryptionTransformer(transformer storagevalue.Transformer) bool { + return transformer == identity.NewEncryptCheckTransformer() +} diff --git a/pkg/util/encryptionconfig/config_test.go b/pkg/util/encryptionconfig/config_test.go new file mode 100644 index 00000000..dd996898 --- /dev/null +++ b/pkg/util/encryptionconfig/config_test.go @@ -0,0 +1,151 @@ +package encryptionconfig + +import ( + "context" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apiserver/pkg/storage/value/encrypt/identity" +) + +var serviceAccountGVR = schema.GroupVersionResource{ + Group: "", + Version: "v1", + Resource: "serviceaccounts", +} + +var deploymentGVR = schema.GroupVersionResource{ + Group: "apps", + Version: "v1", + Resource: "deployments", +} + +func TestGetEncryptionTransformersFromSecret_Basic(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-wildcard.yaml") + configBytes, _ := os.ReadFile(encryptionConfigFilepath) + + testSecret := v1.Secret{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"}, + ObjectMeta: metav1.ObjectMeta{Name: "test-secret"}, + Data: map[string][]byte{ + EncryptionProviderConfigKey: configBytes, + }, + } + transformers, err := GetEncryptionTransformersFromSecret( + context.Background(), + &testSecret, + ) + + assert.Nil(t, err) + assert.NotNil(t, transformers) +} + +func TestPrepareEncryptionConfigSecretTempConfig_ValidSecretKeySillyData(t *testing.T) { + sillyTestData := "Hello Rancher! Moo." + testSecret := v1.Secret{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"}, + ObjectMeta: metav1.ObjectMeta{Name: "test-secret"}, + Data: map[string][]byte{ + EncryptionProviderConfigKey: []byte(sillyTestData), + }, + } + fileHandle, err := PrepareEncryptionConfigSecretTempConfig(&testSecret) + defer os.Remove(EncryptionProviderConfigKey) + // Assert that no error is returned + assert.Nil(t, err) + + // Read the file written by PrepareEncryptionConfigSecretTempConfig + actualBytes := make([]byte, 1024) + n, err := fileHandle.Read(actualBytes) + if err != nil { + t.Fatal(err) + } + + // Assert that the contents of the file match the expected encryption config value + assert.Equal(t, sillyTestData, string(actualBytes[:n])) +} + +func TestPrepareEncryptionConfigSecretTempConfig_EmptySecret(t *testing.T) { + testSecret := v1.Secret{} + _, err := PrepareEncryptionConfigSecretTempConfig(&testSecret) + assert.NotNil(t, err) + assert.Error(t, err) + assert.ErrorContains(t, err, "no encryptionConfig provided") +} + +func TestPrepareEncryptionConfigSecretTempConfig_IncorrectSecretKey(t *testing.T) { + testSecret := v1.Secret{ + TypeMeta: metav1.TypeMeta{APIVersion: "v1", Kind: "Secret"}, + ObjectMeta: metav1.ObjectMeta{Name: "test-secret"}, + Data: map[string][]byte{ + "key": []byte("value"), + }, + } + _, err := PrepareEncryptionConfigSecretTempConfig(&testSecret) + assert.NotNil(t, err) + assert.Error(t, err) + assert.ErrorContains(t, err, "no encryptionConfig provided") + +} + +func TestPrepareEncryptionTransformersFromConfig_Wildcard(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-wildcard.yaml") + transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) + assert.Nil(t, err) + + assert.NotNil(t, transformers.TransformerForResource(serviceAccountGVR.GroupResource())) + assert.NotNil(t, transformers.TransformerForResource(deploymentGVR.GroupResource())) + assert.NotEqual(t, transformers.TransformerForResource(deploymentGVR.GroupResource()), identity.NewEncryptCheckTransformer()) +} + +func TestPrepareEncryptionTransformersFromConfig_ErrorsWithInvalidConfig(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-invalid.yaml") + nilTransformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) + assert.Nil(t, nilTransformers) + assert.NotNil(t, err) + + assert.Error(t, err) + assert.ErrorContains(t, err, "error while parsing file: error decoding encryption provider configuration file") +} + +func TestIsDefaultEncryptionTransformer_Wildcard(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-wildcard.yaml") + transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) + assert.Nil(t, err) + + serviceAccountTransformer := transformers.TransformerForResource(serviceAccountGVR.GroupResource()) + deploymentTransformer := transformers.TransformerForResource(deploymentGVR.GroupResource()) + + assert.False(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) + assert.False(t, IsDefaultEncryptionTransformer(deploymentTransformer)) +} + +func TestIsDefaultEncryptionTransformer_PartialWildcard(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-partial-wildcard.yaml") + ctx := context.WithValue(context.Background(), tempConfigPathKey, encryptionConfigFilepath) + transformers, err := PrepareEncryptionTransformersFromConfig(ctx, encryptionConfigFilepath) + assert.Nil(t, err) + + serviceAccountTransformer := transformers.TransformerForResource(serviceAccountGVR.GroupResource()) + deploymentTransformer := transformers.TransformerForResource(deploymentGVR.GroupResource()) + + assert.True(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) + assert.False(t, IsDefaultEncryptionTransformer(deploymentTransformer)) +} + +func TestIsDefaultEncryptionTransformer_SpecificResource(t *testing.T) { + encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-specific-resource.yaml") + transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) + assert.Nil(t, err) + + serviceAccountTransformer := transformers.TransformerForResource(serviceAccountGVR.GroupResource()) + deploymentTransformer := transformers.TransformerForResource(deploymentGVR.GroupResource()) + + assert.False(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) + assert.True(t, IsDefaultEncryptionTransformer(deploymentTransformer)) +} diff --git a/pkg/util/testdata/encryption-provider-config-invalid.yaml b/pkg/util/encryptionconfig/testdata/encryption-provider-config-invalid.yaml similarity index 100% rename from pkg/util/testdata/encryption-provider-config-invalid.yaml rename to pkg/util/encryptionconfig/testdata/encryption-provider-config-invalid.yaml diff --git a/pkg/util/testdata/encryption-provider-config-partial-wildcard.yaml b/pkg/util/encryptionconfig/testdata/encryption-provider-config-partial-wildcard.yaml similarity index 100% rename from pkg/util/testdata/encryption-provider-config-partial-wildcard.yaml rename to pkg/util/encryptionconfig/testdata/encryption-provider-config-partial-wildcard.yaml diff --git a/pkg/util/testdata/encryption-provider-config-specific-resource.yaml b/pkg/util/encryptionconfig/testdata/encryption-provider-config-specific-resource.yaml similarity index 100% rename from pkg/util/testdata/encryption-provider-config-specific-resource.yaml rename to pkg/util/encryptionconfig/testdata/encryption-provider-config-specific-resource.yaml diff --git a/pkg/util/testdata/encryption-provider-config-wildcard.yaml b/pkg/util/encryptionconfig/testdata/encryption-provider-config-wildcard.yaml similarity index 100% rename from pkg/util/testdata/encryption-provider-config-wildcard.yaml rename to pkg/util/encryptionconfig/testdata/encryption-provider-config-wildcard.yaml diff --git a/pkg/util/util.go b/pkg/util/util.go index db9d67bf..e449f4c5 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -3,23 +3,13 @@ package util import ( "context" "fmt" - "os" "reflect" - - v1core "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" - "github.com/sirupsen/logrus" - k8sv1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/server/options/encryptionconfig" - "k8s.io/apiserver/pkg/storage/value" - "k8s.io/apiserver/pkg/storage/value/encrypt/identity" ) const ( - WorkerThreads = 25 - S3Backup = "S3" - PVBackup = "PV" - EncryptionProviderConfigKey = "encryption-provider-config.yaml" + WorkerThreads = 25 + S3Backup = "S3" + PVBackup = "PV" ) var ( @@ -69,36 +59,6 @@ func SetChartNamespace(ns string) { }) } -func GetEncryptionTransformersFromSecret(encryptionConfigSecretName string, secrets v1core.SecretController) (map[schema.GroupResource]value.Transformer, error) { - // EncryptionConfig secret ns is hardcoded to ns of controller in chart's ns - // kubectl create secret generic test-encryptionconfig --from-file=./encryption-provider-config.yaml - logrus.Infof("Get encryption config from namespace %v", GetChartNamespace()) - encryptionConfigSecret, err := secrets.Get(GetChartNamespace(), encryptionConfigSecretName, k8sv1.GetOptions{}) - if err != nil { - return nil, err - } - encryptionConfigBytes, ok := encryptionConfigSecret.Data[EncryptionProviderConfigKey] - if !ok { - return nil, fmt.Errorf("no encryptionConfig provided") - } - err = os.WriteFile(EncryptionProviderConfigKey, encryptionConfigBytes, os.ModePerm) - defer os.Remove(EncryptionProviderConfigKey) - - if err != nil { - return nil, err - } - return PrepareEncryptionTransformersFromConfig(context.Background(), EncryptionProviderConfigKey) -} - -func PrepareEncryptionTransformersFromConfig(ctx context.Context, encryptionProviderPath string) (map[schema.GroupResource]value.Transformer, error) { - apiServerID := "" - encryptionConfig, err := encryptionconfig.LoadEncryptionConfig(ctx, encryptionProviderPath, false, apiServerID) - if err != nil { - return nil, err - } - return encryptionConfig.Transformers, nil -} - func GetObjectQueue(l interface{}, capacity int) chan interface{} { s := reflect.ValueOf(l) c := make(chan interface{}, capacity) @@ -109,10 +69,6 @@ func GetObjectQueue(l interface{}, capacity int) chan interface{} { return c } -func IsDefaultEncryptionTransformer(transformer value.Transformer) bool { - return transformer == identity.NewEncryptCheckTransformer() -} - func ErrList(e []error) error { if len(e) > 0 { return fmt.Errorf("%v", e) diff --git a/pkg/util/util_test.go b/pkg/util/util_test.go index 47411d44..a740be48 100644 --- a/pkg/util/util_test.go +++ b/pkg/util/util_test.go @@ -1,99 +1,12 @@ package util import ( - "context" "fmt" - "path/filepath" "testing" "github.com/stretchr/testify/assert" - "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/apiserver/pkg/server/options/encryptionconfig" - "k8s.io/apiserver/pkg/storage/value/encrypt/identity" ) -var serviceAccountGVR = schema.GroupVersionResource{ - Group: "", - Version: "v1", - Resource: "serviceaccounts", -} - -var deploymentGVR = schema.GroupVersionResource{ - Group: "apps", - Version: "v1", - Resource: "deployments", -} - -func TestPrepareEncryptionTransformersFromConfig_Wildcard(t *testing.T) { - encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-wildcard.yaml") - transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) - if err != nil { - return - } - - var staticTransformers encryptionconfig.StaticTransformers = transformers - - assert.NotNil(t, staticTransformers.TransformerForResource(serviceAccountGVR.GroupResource())) - assert.NotNil(t, staticTransformers.TransformerForResource(deploymentGVR.GroupResource())) - assert.NotEqual(t, staticTransformers.TransformerForResource(deploymentGVR.GroupResource()), identity.NewEncryptCheckTransformer()) -} - -func TestPrepareEncryptionTransformersFromConfig_ErrorsWithInvalidConfig(t *testing.T) { - encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-invalid.yaml") - _, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) - if err == nil { - return - } - - assert.Error(t, err) - assert.ErrorContains(t, err, "error while parsing file: error decoding encryption provider configuration file") -} - -func TestIsDefaultEncryptionTransformer_Wildcard(t *testing.T) { - encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-wildcard.yaml") - transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) - if err != nil { - return - } - - var staticTransformers encryptionconfig.StaticTransformers = transformers - serviceAccountTransformer := staticTransformers.TransformerForResource(serviceAccountGVR.GroupResource()) - deploymentTransformer := staticTransformers.TransformerForResource(deploymentGVR.GroupResource()) - - assert.False(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) - assert.False(t, IsDefaultEncryptionTransformer(deploymentTransformer)) -} - -func TestIsDefaultEncryptionTransformer_PartialWildcard(t *testing.T) { - encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-partial-wildcard.yaml") - transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) - if err != nil { - return - } - - var staticTransformers encryptionconfig.StaticTransformers = transformers - serviceAccountTransformer := staticTransformers.TransformerForResource(serviceAccountGVR.GroupResource()) - deploymentTransformer := staticTransformers.TransformerForResource(deploymentGVR.GroupResource()) - - assert.True(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) - assert.False(t, IsDefaultEncryptionTransformer(deploymentTransformer)) -} - -func TestIsDefaultEncryptionTransformer_SpecificResource(t *testing.T) { - encryptionConfigFilepath := filepath.Join("testdata", "encryption-provider-config-specific-resource.yaml") - transformers, err := PrepareEncryptionTransformersFromConfig(context.Background(), encryptionConfigFilepath) - if err != nil { - return - } - - var staticTransformers encryptionconfig.StaticTransformers = transformers - serviceAccountTransformer := staticTransformers.TransformerForResource(serviceAccountGVR.GroupResource()) - deploymentTransformer := staticTransformers.TransformerForResource(deploymentGVR.GroupResource()) - - assert.False(t, IsDefaultEncryptionTransformer(serviceAccountTransformer)) - assert.True(t, IsDefaultEncryptionTransformer(deploymentTransformer)) -} - func TestErrList_VerifyErrorConcatenation(t *testing.T) { errList := []error{ fmt.Errorf("error1"),