From b4f4b99d565018d41a489e523f28734f0e9cef12 Mon Sep 17 00:00:00 2001 From: "Christopher J. Ruwe" Date: Mon, 1 Jun 2020 14:21:24 +0200 Subject: [PATCH] make character case for keys in parameters map irrelevant, fixing #143 More specifically, - introduce helper function to get maps with all keys set to lowercase, - introduce lookup helper based on such maps and - change lookups for CreateVolumeRequest()s and CreateVolume()s so that parameter keys are processed as lowercase irrespective of actual spelling. Signed-off-by: Christopher J. Ruwe --- changelogs/unreleased/144-cruwe | 1 + pkg/common/helpers/helpers.go | 43 +++++++++++++++++++++++++++++++++ pkg/driver/controller.go | 39 ++++++++++++++++++++---------- 3 files changed, 70 insertions(+), 13 deletions(-) create mode 100644 changelogs/unreleased/144-cruwe create mode 100644 pkg/common/helpers/helpers.go diff --git a/changelogs/unreleased/144-cruwe b/changelogs/unreleased/144-cruwe new file mode 100644 index 000000000..5fad5d3d4 --- /dev/null +++ b/changelogs/unreleased/144-cruwe @@ -0,0 +1 @@ +Fixes an issue where volumes meant to be filesystem datasets got created as zvols and generally makes storageclass parameter spelling insensitive to case diff --git a/pkg/common/helpers/helpers.go b/pkg/common/helpers/helpers.go new file mode 100644 index 000000000..09332058a --- /dev/null +++ b/pkg/common/helpers/helpers.go @@ -0,0 +1,43 @@ +/* +Copyright 2020 The OpenEBS Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package helpers + +import ( + "strings" +) + +// Coerce the map's keys to lower case, which only works when unicode char is in +// ASCII subset. May overwrite key-value pairs on different permutations of key +// case as in Key and key. DON'T force values to the lower case unconditionally, +// because values for keys such as mountpoint or keylocation are case-sensitive. +// Note that although keys such as 'comPREssion' are accepted and processed, +// even if they are technically invalid, updates to rectify such typing will be +// prohibited as a forbidden update. +func GetCaseInsensitiveMap(dict *map[string]string) map[string]string { + insensitiveDict := map[string]string{} + + for k, v := range *dict { + insensitiveDict[strings.ToLower(k)] = v + } + return insensitiveDict +} + +// special case of GetCaseInsensitiveMap looking up one key-value pair only +func GetInsensitiveParameter(dict *map[string]string, key string) string { + insensitiveDict := GetCaseInsensitiveMap(dict) + return insensitiveDict[strings.ToLower(key)] +} diff --git a/pkg/driver/controller.go b/pkg/driver/controller.go index fda1be37f..0d4c976f2 100644 --- a/pkg/driver/controller.go +++ b/pkg/driver/controller.go @@ -27,6 +27,7 @@ import ( "github.com/openebs/zfs-localpv/pkg/builder/snapbuilder" "github.com/openebs/zfs-localpv/pkg/builder/volbuilder" errors "github.com/openebs/zfs-localpv/pkg/common/errors" + "github.com/openebs/zfs-localpv/pkg/common/helpers" csipayload "github.com/openebs/zfs-localpv/pkg/response" analytics "github.com/openebs/zfs-localpv/pkg/usage" zfs "github.com/openebs/zfs-localpv/pkg/zfs" @@ -75,17 +76,25 @@ func sendEventOrIgnore(pvName, capacity, stgType, method string) { func CreateZFSVolume(req *csi.CreateVolumeRequest) (string, error) { volName := req.GetName() size := req.GetCapacityRange().RequiredBytes - rs := req.GetParameters()["recordsize"] - bs := req.GetParameters()["volblocksize"] - compression := req.GetParameters()["compression"] - dedup := req.GetParameters()["dedup"] - encr := req.GetParameters()["encryption"] - kf := req.GetParameters()["keyformat"] - kl := req.GetParameters()["keylocation"] - pool := req.GetParameters()["poolname"] - tp := req.GetParameters()["thinprovision"] - schld := req.GetParameters()["scheduler"] - fstype := req.GetParameters()["fstype"] + + // parameter keys may be mistyped from the CRD specification when declaring + // the storageclass, which kubectl validation will not catch. Because ZFS + // parameter keys (not values!) are all lowercase, keys may safely be forced + // to the lower case. + originalParams := req.GetParameters() + parameters := helpers.GetCaseInsensitiveMap(&originalParams) + + rs := parameters["recordsize"] + bs := parameters["volblocksize"] + compression := parameters["compression"] + dedup := parameters["dedup"] + encr := parameters["encryption"] + kf := parameters["keyformat"] + kl := parameters["keylocation"] + pool := parameters["poolname"] + tp := parameters["thinprovision"] + schld := parameters["scheduler"] + fstype := parameters["fstype"] vtype := zfs.GetVolumeType(fstype) @@ -130,7 +139,9 @@ func CreateZFSVolume(req *csi.CreateVolumeRequest) (string, error) { func CreateZFSClone(req *csi.CreateVolumeRequest, snapshot string) (string, error) { volName := req.GetName() - pool := req.GetParameters()["poolname"] + parameters := req.GetParameters() + // lower case keys, cf CreateZFSVolume() + pool := helpers.GetInsensitiveParameter(¶meters, "poolname") size := req.GetCapacityRange().RequiredBytes volsize := strconv.FormatInt(int64(size), 10) @@ -188,7 +199,9 @@ func (cs *controller) CreateVolume( var selected string volName := req.GetName() - pool := req.GetParameters()["poolname"] + parameters := req.GetParameters() + // lower case keys, cf CreateZFSVolume() + pool := helpers.GetInsensitiveParameter(¶meters, "poolname") size := req.GetCapacityRange().RequiredBytes contentSource := req.GetVolumeContentSource()