From 60ebf420f400d2e8ad2e7c9125287d692012e288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Al=C3=AD=20Fel=C3=A1n?= Date: Fri, 4 Aug 2023 03:02:46 -0400 Subject: [PATCH] Dynamic luks support Enable setting the luks option in a volume config based on the parameters from the create volume request --- frontend/csi/controller_server.go | 1 + frontend/csi/utils.go | 22 ++++++++ frontend/csi/utils_test.go | 89 ++++++++++++++++++++++++++++++ storage_drivers/ontap/ontap_san.go | 6 +- 4 files changed, 116 insertions(+), 2 deletions(-) diff --git a/frontend/csi/controller_server.go b/frontend/csi/controller_server.go index 479290a8e..c99319e0a 100644 --- a/frontend/csi/controller_server.go +++ b/frontend/csi/controller_server.go @@ -257,6 +257,7 @@ func (p *Plugin) CreateVolume( if volConfig.CloneSourceVolume != "" { newVolume, err = p.orchestrator.CloneVolume(ctx, volConfig) } else if volConfig.ImportOriginalName != "" { + overrideRequestedValues(req, volConfig) newVolume, err = p.orchestrator.ImportVolume(ctx, volConfig) } else { newVolume, err = p.orchestrator.AddVolume(ctx, volConfig) diff --git a/frontend/csi/utils.go b/frontend/csi/utils.go index db57b4968..648ddd1f6 100644 --- a/frontend/csi/utils.go +++ b/frontend/csi/utils.go @@ -15,6 +15,7 @@ import ( "github.com/netapp/trident/config" controllerAPI "github.com/netapp/trident/frontend/csi/controller_api" . "github.com/netapp/trident/logging" + "github.com/netapp/trident/storage" "github.com/netapp/trident/utils" "github.com/netapp/trident/utils/crypto" "github.com/netapp/trident/utils/errors" @@ -330,3 +331,24 @@ func ensureLUKSVolumePassphrase( } return nil } + +// Iteratees through the selector parameters in the request, and applies +// LUKS selector to the volume +func overrideRequestedValues(req *csi.CreateVolumeRequest, volConfig *storage.VolumeConfig ) { + var luksLabel = "luks" + // Add each selector to a map for accessibility + selectors := map[string]string{} + for _, selector := range strings.Split(req.Parameters["selector"], "; ") { + key, val, ok := strings.Cut(selector, "=") + if !ok { + // Selector has wrong format, skipped + continue + } + selectors[key] = val + } + + // If LUKS selector is set pass it to the volume config + if selectors[luksLabel] != "" { + volConfig.LUKSEncryption = selectors[luksLabel] + } +} diff --git a/frontend/csi/utils_test.go b/frontend/csi/utils_test.go index 1da5e80bd..4f942f31f 100644 --- a/frontend/csi/utils_test.go +++ b/frontend/csi/utils_test.go @@ -5,13 +5,16 @@ import ( "fmt" "testing" + "github.com/container-storage-interface/spec/lib/go/csi" "github.com/golang/mock/gomock" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" "github.com/netapp/trident/config" mockControllerAPI "github.com/netapp/trident/mocks/mock_frontend/mock_csi/mock_controller_api" "github.com/netapp/trident/mocks/mock_utils" "github.com/netapp/trident/mocks/mock_utils/mock_luks" + "github.com/netapp/trident/storage" "github.com/netapp/trident/utils" "github.com/netapp/trident/utils/errors" ) @@ -465,3 +468,89 @@ func TestEnsureLUKSVolumePassphrase_NoCorrectPassphraseProvided(t *testing.T) { assert.Error(t, err) mockCtrl.Finish() } + +func TestOverrideRequestedValues(t *testing.T) { + tests := []struct{ + name string + req csi.CreateVolumeRequest + volConfig storage.VolumeConfig + result storage.VolumeConfig + }{ + { + name: "Empty", + }, + { + name: "LUKSTrue", + req: csi.CreateVolumeRequest{ + Parameters: map[string]string{ + "selector": "luks=true", + }, + }, + result: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + }, + { + name: "Multiple", + req: csi.CreateVolumeRequest{ + Parameters: map[string]string{ + "selector": "efg=yes; luks=true; abc=false", + }, + }, + result: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + }, + { + name: "LUKSFalse", + req: csi.CreateVolumeRequest{ + Parameters: map[string]string{ + "selector": "efg=yes; luks=false; abc=false", + }, + }, + volConfig: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + result: storage.VolumeConfig{ + LUKSEncryption: "false", + }, + }, + { + name: "Misconfigured", + req: csi.CreateVolumeRequest{ + Parameters: map[string]string{ + "selector": "efg:yes; luks:false; abc=false", + }, + }, + volConfig: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + result: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + }, + { + name: "Mixed", + req: csi.CreateVolumeRequest{ + Parameters: map[string]string{ + "selector": "efg:yes; luks=false; abc/false", + }, + }, + volConfig: storage.VolumeConfig{ + LUKSEncryption: "true", + }, + result: storage.VolumeConfig{ + LUKSEncryption: "false", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func (t *testing.T) { + overrideRequestedValues(&test.req, &test.volConfig) + if diff := cmp.Diff(test.volConfig, test.result); diff != "" { + t.Errorf("overrideRequestedValues(): volConfig differs (+got, -want): %s", diff) + } + }) + } +} diff --git a/storage_drivers/ontap/ontap_san.go b/storage_drivers/ontap/ontap_san.go index c2ce64c89..b38670488 100644 --- a/storage_drivers/ontap/ontap_san.go +++ b/storage_drivers/ontap/ontap_san.go @@ -598,8 +598,10 @@ func (d *SANStorageDriver) Import(ctx context.Context, volConfig *storage.Volume } } - // Set the volume to LUKS if backend has LUKS true as default - volConfig.LUKSEncryption = d.Config.LUKSEncryption + // If the volume has LUKS unset, apply the default from the backend + if volConfig.LUKSEncryption == "" { + volConfig.LUKSEncryption = d.Config.LUKSEncryption + } // Ensure the volume has only one LUN lunInfo, err := d.API.LunGetByName(ctx, "/vol/"+originalName+"/*")