Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting String Interpolation for Modifying Tags On Existing Volumes Through VAC #2093

Merged
Merged
3 changes: 3 additions & 0 deletions charts/aws-ebs-csi-driver/templates/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ spec:
{{- if not (regexMatch "(-timeout)" (join " " .Values.sidecars.resizer.additionalArgs)) }}
- --timeout=60s
{{- end }}
{{- if .Values.controller.extraCreateMetadata }}
- --extra-modify-metadata
{{- end}}
- --csi-address=$(ADDRESS)
- --v={{ .Values.sidecars.resizer.logLevel }}
- --handle-volume-inuse-error=false
Expand Down
2 changes: 1 addition & 1 deletion charts/aws-ebs-csi-driver/values.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@
},
"extraCreateMetadata": {
"type": "boolean",
"description": "If set, add pv/pvc metadata to plugin create requests as parameters.",
"description": "If set, add pv/pvc metadata to plugin create and modify requests as parameters.",
"default": true
},
"k8sTagClusterId": {
Expand Down
4 changes: 2 additions & 2 deletions charts/aws-ebs-csi-driver/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ sidecars:
image:
pullPolicy: IfNotPresent
repository: public.ecr.aws/eks-distro/kubernetes-csi/external-resizer
tag: "v1.12.0-eks-1-31-11"
tag: "v1.13.1-eks-1-32-5"
# Tune leader lease election for csi-resizer.
# Leader election is on by default.
leaderElection:
Expand Down Expand Up @@ -220,7 +220,7 @@ controller:
env: []
# Use envFrom to reference ConfigMaps and Secrets across all containers in the deployment
envFrom: []
# If set, add pv/pvc metadata to plugin create requests as parameters.
# If set, add pv/pvc metadata to plugin create and modify requests as parameters.
extraCreateMetadata: true
# Extra volume tags to attach to each dynamically provisioned volume.
# ---
Expand Down
3 changes: 2 additions & 1 deletion deploy/kubernetes/base/controller.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,11 @@ spec:
seccompProfile:
type: RuntimeDefault
- name: csi-resizer
image: public.ecr.aws/eks-distro/kubernetes-csi/external-resizer:v1.12.0-eks-1-31-11
image: public.ecr.aws/eks-distro/kubernetes-csi/external-resizer:v1.13.1-eks-1-32-5
imagePullPolicy: IfNotPresent
args:
- --timeout=60s
- --extra-modify-metadata
- --csi-address=$(ADDRESS)
- --v=2
- --handle-volume-inuse-error=false
Expand Down
2 changes: 1 addition & 1 deletion deploy/kubernetes/overlays/stable/gcr/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ images:
newTag: v8.2.0
- name: public.ecr.aws/eks-distro/kubernetes-csi/external-resizer
newName: registry.k8s.io/sig-storage/csi-resizer
newTag: v1.12.0
newTag: v1.13.1
- name: public.ecr.aws/eks-distro/kubernetes-csi/node-driver-registrar
newName: registry.k8s.io/sig-storage/csi-node-driver-registrar
newTag: v2.13.0
30 changes: 27 additions & 3 deletions docs/tagging.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ To help manage volumes in the aws account, CSI driver will automatically add tag

# StorageClass Tagging

The AWS EBS CSI Driver supports tagging through `StorageClass.parameters` (in v1.6.0 and later).
The AWS EBS CSI Driver supports tagging through `StorageClass.parameters`.

If a key has the prefix `tagSpecification`, the CSI driver will treat the value as a key-value pair to be applied to the dynamically provisioned volume as tags.

Expand Down Expand Up @@ -97,8 +97,26 @@ billingID=ABCDEF
```

# Adding, Modifying, and Deleting Tags Of Existing Volumes
The AWS EBS CSI Driver supports the modifying of tags of existing volumes through `VolumeAttributesClass.parameters` the examples below show the syntax for addition, modification, and deletion of tags within the `VolumeAttributesClass.parameters`. For a walkthrough on how to apply these modifications to a volume follow the [walkthrough for Volume Modification via VolumeAttributeClass](../examples/kubernetes/modify-volume)

The AWS EBS CSI Driver supports the modifying of tags of existing volumes through `VolumeAttributesClass.parameters` the examples below show the syntax for addition, modification, and deletion of tags within the `VolumeAttributesClass.parameters`. The driver also supports runtime string interpolation on tag values for a volume upon modification, which allows the specification of placeholder values for the PVC namespace, PVC name, and PV name, which will then be dynamically computed at runtime.

**Note: Interpolated tags require the `--extra-modify-metadata` flag to be enabled on the `external-resizer` sidecar. To modify Amazon EBS resource tags through VACs, ensure that you attach the following IAM Policy to the role used by your Amazon EBS CSI driver:**
```
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:CreateTags"
],
"Resource": [
"arn:aws:ec2:*:*:volume/*",
"arn:aws:ec2:*:*:snapshot/*"
]
}
]
}
```
**Syntax for Adding or Modifying a Tag**

If a key has the prefix `tagSpecification`, the CSI driver will treat the value as a key-value pair to be added to the existing volume. If there is already an existing tag with the specified key, the CSI driver will overwrite the value of that tag with the new value specified.
Expand All @@ -111,6 +129,12 @@ driverName: ebs.csi.aws.com
parameters:
tagSpecification_1: "location=Seattle"
tagSpecification_2: "cost-center=" // If the value is left blank, tag is created with an empty value
# Interpolated tag
tagSpecification_3: "PVC-Name={{ .PVCName }}"
tagSpecification_4: "PVC-Namespace={{ .PVCNamespace }}"
tagSpecification_5: "PV-Name={{ .PVName }}"
# Interpolated tag w/ function
tagSpecification_6: 'key6={{ .PVCNamespace | contains "prod" }}'
```
**Syntax for Deleting a Tag**

Expand Down
22 changes: 16 additions & 6 deletions pkg/driver/controller_modify_volume.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
"github.com/awslabs/volume-modifier-for-k8s/pkg/rpc"
"github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/cloud"
"github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/coalescer"
"github.com/kubernetes-sigs/aws-ebs-csi-driver/pkg/util/template"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"k8s.io/klog/v2"
Expand Down Expand Up @@ -170,6 +171,8 @@ func parseModifyVolumeParameters(params map[string]string) (*modifyVolumeRequest
TagsToDelete: make([]string, 0),
},
}
var rawTagsToAdd []string
tProps := new(template.PVProps)
for key, value := range params {
switch key {
case ModificationKeyIOPS:
Expand All @@ -193,23 +196,30 @@ func parseModifyVolumeParameters(params map[string]string) (*modifyVolumeRequest
options.modifyDiskOptions.VolumeType = value
case ModificationKeyVolumeType:
options.modifyDiskOptions.VolumeType = value
case PVCNameKey:
tProps.PVCName = value
case PVCNamespaceKey:
tProps.PVCNamespace = value
case PVNameKey:
tProps.PVName = value
default:
switch {
case strings.HasPrefix(key, ModificationAddTag):
st := strings.SplitN(value, "=", 2)
if len(st) < 2 {
return nil, status.Errorf(codes.InvalidArgument, "Invalid tag specification: %v", st)
}
options.modifyTagsOptions.TagsToAdd[st[0]] = st[1]
rawTagsToAdd = append(rawTagsToAdd, value)
case strings.HasPrefix(key, ModificationDeleteTag):
options.modifyTagsOptions.TagsToDelete = append(options.modifyTagsOptions.TagsToDelete, value)
default:
return nil, status.Errorf(codes.InvalidArgument, "Invalid mutable parameter key: %s", key)
}
}
}
if err := validateExtraTags(options.modifyTagsOptions.TagsToAdd, false); err != nil {
addTags, err := template.Evaluate(rawTagsToAdd, tProps, false)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Error interpolating the tag value: %v", err)
}
if err := validateExtraTags(addTags, false); err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Invalid tag value: %v", err)
}
options.modifyTagsOptions.TagsToAdd = addTags
return &options, nil
}
11 changes: 10 additions & 1 deletion pkg/driver/controller_modify_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,14 @@ func TestParseModifyVolumeParameters(t *testing.T) {
ModificationKeyVolumeType: validType,
ModificationKeyIOPS: validIops,
ModificationKeyThroughput: validThroughput,
ModificationAddTag: validTagSpecificationInput,
ModificationAddTag + "_1": validTagSpecificationInput,
ModificationAddTag + "_2": "key2={{ .PVCName }}",
ModificationAddTag + "_3": "key3={{ .PVCNamespace }}",
ModificationAddTag + "_4": "key4={{ .PVName }}",
ModificationDeleteTag: validTagDeletion,
PVCNameKey: "ebs-claim",
PVCNamespaceKey: "test-namespace",
PVNameKey: "testPV-Name",
},
expectedOptions: &modifyVolumeRequest{
modifyDiskOptions: cloud.ModifyDiskOptions{
Expand All @@ -166,6 +172,9 @@ func TestParseModifyVolumeParameters(t *testing.T) {
modifyTagsOptions: cloud.ModifyTagsOptions{
TagsToAdd: map[string]string{
"key1": "tag1",
"key2": "ebs-claim",
"key3": "test-namespace",
"key4": "testPV-Name",
},
TagsToDelete: []string{
"key2",
Expand Down