diff --git a/docs/README.md b/docs/README.md index 1350ccb2e..69e5f9ffb 100644 --- a/docs/README.md +++ b/docs/README.md @@ -361,11 +361,11 @@ Enabling the vol-metrics-opt-in parameter activates the gathering of inode and d ### Container Arguments for deployment(controller) -| Parameters | Values | Default | Optional | Description | -|-----------------------------|--------|---------|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| delete-access-point-root-dir| | false | true | Opt in to delete access point root directory by DeleteVolume. By default, DeleteVolume will delete the access point behind Persistent Volume and deleting access point will not delete the access point root directory or its contents. | -| adaptive-retry-mode | | true | true | Opt out to use standard sdk retry mode for EFS API calls. By default, Driver will use adaptive mode for the sdk retry configuration which heavily rate limits EFS API requests to reduce throttling if throttling is observed. | -| tags | | | true | Space separated key:value pairs which will be added as tags for Amazon EFS resources. For example, '--tags=name:efs-tag-test date:Jan24' | +| Parameters | Values | Default | Optional | Description | +|-----------------------------|--------|---------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| delete-access-point-root-dir| | false | true | Opt in to delete access point root directory by DeleteVolume. By default, DeleteVolume will delete the access point behind Persistent Volume and deleting access point will not delete the access point root directory or its contents. | +| adaptive-retry-mode | | true | true | Opt out to use standard sdk retry mode for EFS API calls. By default, Driver will use adaptive mode for the sdk retry configuration which heavily rate limits EFS API requests to reduce throttling if throttling is observed. | +| tags | | | true | Space separated key:value pairs which will be added as tags for Amazon EFS resources. For example, '--tags=name:efs-tag-test date:Jan24'. To include a ':' in the tag name or value, use \ as an escape character, for example '--tags="tag\:name:tag\:value" | ### Upgrading the Amazon EFS CSI Driver diff --git a/pkg/driver/controller_test.go b/pkg/driver/controller_test.go index 4413234f6..6b03138ca 100644 --- a/pkg/driver/controller_test.go +++ b/pkg/driver/controller_test.go @@ -796,7 +796,11 @@ func TestCreateVolume(t *testing.T) { cloud: mockCloud, gidAllocator: NewGidAllocator(), lockManager: NewLockManagerMap(), - tags: parseTagsFromStr("cluster:efs"), + tags: parseTagsFromStr("cluster:efs tag2\\:name2:tag2\\:val2"), + } + + if driver.tags["cluster"] != "efs" || driver.tags["tag2:name2"] != "tag2:val2" { + t.Fatalf("Incorrect tags") } req := &csi.CreateVolumeRequest{ diff --git a/pkg/driver/driver.go b/pkg/driver/driver.go index f8d78dac6..79f166492 100644 --- a/pkg/driver/driver.go +++ b/pkg/driver/driver.go @@ -23,11 +23,10 @@ import ( "time" "github.com/container-storage-interface/spec/lib/go/csi" - "google.golang.org/grpc" - "k8s.io/klog/v2" - "github.com/kubernetes-sigs/aws-efs-csi-driver/pkg/cloud" "github.com/kubernetes-sigs/aws-efs-csi-driver/pkg/util" + "google.golang.org/grpc" + "k8s.io/klog/v2" ) const ( @@ -155,9 +154,31 @@ func parseTagsFromStr(tagStr string) map[string]string { return m } tagsSplit := strings.Split(tagStr, " ") - for _, pair := range tagsSplit { - p := strings.Split(pair, ":") - m[p[0]] = p[1] + for _, currTag := range tagsSplit { + var nameBuilder strings.Builder + var valBuilder strings.Builder + var currBuilder *strings.Builder = &nameBuilder + + for i := 0; i < len(currTag); i++ { + if currTag[i] == ':' { + if currBuilder == &valBuilder { + break + } else { + currBuilder = &valBuilder + continue + } + } + + // Handle escape character + if currTag[i] == byte('\\') && currTag[i+1] == byte(':') { + currBuilder.WriteRune(':') + i++ // Skip an extra character + continue + } + + currBuilder.WriteByte(currTag[i]) + } + m[nameBuilder.String()] = valBuilder.String() } return m }