Skip to content

Commit e93b90c

Browse files
committed
Support to add ResoureManagerTags to GCP Compute Disk, Image, Snapshot resources
1 parent 2c674dd commit e93b90c

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+32651
-29
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ See Github [Issues](https://github.com/kubernetes-sigs/gcp-compute-persistent-di
6060
| labels | `key1=value1,key2=value2` | | Labels allow you to assign custom [GCE Disk labels](https://cloud.google.com/compute/docs/labeling-resources). |
6161
| provisioned-iops-on-create | string (int64 format). Values typically between 10,000 and 120,000 | | Indicates how many IOPS to provision for the disk. See the [Extreme persistent disk documentation](https://cloud.google.com/compute/docs/disks/extreme-persistent-disk) for details, including valid ranges for IOPS. |
6262
| provisioned-throughput-on-create | string (int64 format). Values typically between 1 and 7,124 mb per second | | Indicates how much throughput to provision for the disk. See the [hyperdisk documentation](TBD) for details, including valid ranges for throughput. |
63+
| resource-tags | `<parent_id1>/<tag_key1>/<tag_value1>,<parent_id2>/<tag_key2>/<tag_value2>` | | Resource tags allow you to attach user-defined tags to each Compute Disk. See [Tags overview](https://cloud.google.com/resource-manager/docs/tags/tags-overview), [Creating and managing tags](https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing). |
6364

6465
### Topology
6566

cmd/gce-pd-csi-driver/main.go

+11-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ var (
6767
maxConcurrentFormatAndMount = flag.Int("max-concurrent-format-and-mount", 1, "If set then format and mount operations are serialized on each node. This is stronger than max-concurrent-format as it includes fsck and other mount operations")
6868
formatAndMountTimeout = flag.Duration("format-and-mount-timeout", 1*time.Minute, "The maximum duration of a format and mount operation before another such operation will be started. Used only if --serialize-format-and-mount")
6969

70+
extraTagsStr = flag.String("extra-tags", "", "Extra tags to attach to each Compute Disk, Image, Snapshot created. It is a comma separated list of parent id, key and value like '<parent_id1>/<tag_key1>/<tag_value1>,...,<parent_idN>/<tag_keyN>/<tag_valueN>'. parent_id is the Organization or the Project ID where the tag key and the tag value resources exist. A maximum of 50 tags bindings is allowed for a resource. See https://cloud.google.com/resource-manager/docs/tags/tags-overview, https://cloud.google.com/resource-manager/docs/tags/tags-creating-and-managing for details")
71+
7072
version string
7173
)
7274

@@ -136,6 +138,14 @@ func handle() {
136138
klog.Fatalf("Bad extra volume labels: %v", err.Error())
137139
}
138140

141+
if len(*extraTagsStr) > 0 && !*runControllerService {
142+
klog.Fatalf("Extra tags provided but not running controller")
143+
}
144+
extraTags, err := common.ConvertTagsStringToMap(*extraTagsStr)
145+
if err != nil {
146+
klog.Fatalf("Bad extra tags: %v", err.Error())
147+
}
148+
139149
ctx, cancel := context.WithCancel(context.Background())
140150
defer cancel()
141151

@@ -178,7 +188,7 @@ func handle() {
178188
}
179189
}
180190

181-
err = gceDriver.SetupGCEDriver(driverName, version, extraVolumeLabels, identityServer, controllerServer, nodeServer)
191+
err = gceDriver.SetupGCEDriver(driverName, version, extraVolumeLabels, extraTags, identityServer, controllerServer, nodeServer)
182192
if err != nil {
183193
klog.Fatalf("Failed to initialize GCE CSI Driver: %v", err.Error())
184194
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: storage.k8s.io/v1
2+
kind: StorageClass
3+
metadata:
4+
name: csi-gce-pd-with-resource-tags
5+
provisioner: pd.csi.storage.gke.io
6+
parameters:
7+
resource-tags: <parent_id1>/<tag_key1>/<tag_value1>,<parent_id2>/<tag_key2>/<tag_value2>
8+
volumeBindingMode: WaitForFirstConsumer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
apiVersion: snapshot.storage.k8s.io/v1beta1
2+
kind: VolumeSnapshotClass
3+
metadata:
4+
name: csi-gce-pd-snapshot-class-with-resource-tags
5+
parameters:
6+
resource-tags: <parent_id1>/<tag_key1>/<tag_value1>,<parent_id2>/<tag_key2>/<tag_value2>
7+
driver: pd.csi.storage.gke.io
8+
deletionPolicy: Delete

go.mod

+5-2
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@ go 1.20
55
require (
66
cloud.google.com/go/compute/metadata v0.2.3
77
cloud.google.com/go/kms v1.15.5
8+
cloud.google.com/go/resourcemanager v1.9.2
89
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.24.0
910
github.com/container-storage-interface/spec v1.6.0
1011
github.com/google/go-cmp v0.6.0
1112
github.com/google/uuid v1.4.0
13+
github.com/googleapis/gax-go/v2 v2.12.0
1214
github.com/kubernetes-csi/csi-proxy/client v1.1.3
1315
github.com/kubernetes-csi/csi-test/v4 v4.4.0
1416
github.com/onsi/ginkgo/v2 v2.13.2
@@ -20,6 +22,7 @@ require (
2022
go.opentelemetry.io/otel/sdk v1.21.0
2123
golang.org/x/oauth2 v0.15.0
2224
golang.org/x/sys v0.15.0
25+
golang.org/x/time v0.5.0
2326
google.golang.org/api v0.151.0
2427
google.golang.org/genproto v0.0.0-20231016165738-49dd2c1f3d0b
2528
google.golang.org/grpc v1.59.0
@@ -37,8 +40,10 @@ require (
3740
)
3841

3942
require (
43+
cloud.google.com/go v0.110.8 // indirect
4044
cloud.google.com/go/compute v1.23.3 // indirect
4145
cloud.google.com/go/iam v1.1.5 // indirect
46+
cloud.google.com/go/longrunning v0.5.2 // indirect
4247
github.com/Microsoft/go-winio v0.6.1 // indirect
4348
github.com/PuerkitoBio/purell v1.1.1 // indirect
4449
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
@@ -64,7 +69,6 @@ require (
6469
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
6570
github.com/google/s2a-go v0.1.7 // indirect
6671
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
67-
github.com/googleapis/gax-go/v2 v2.12.0 // indirect
6872
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
6973
github.com/hashicorp/errwrap v1.0.0 // indirect
7074
github.com/hashicorp/go-multierror v1.1.0 // indirect
@@ -97,7 +101,6 @@ require (
97101
golang.org/x/sync v0.5.0 // indirect
98102
golang.org/x/term v0.15.0 // indirect
99103
golang.org/x/text v0.14.0 // indirect
100-
golang.org/x/time v0.5.0 // indirect
101104
golang.org/x/tools v0.16.0 // indirect
102105
google.golang.org/appengine v1.6.8 // indirect
103106
google.golang.org/genproto/googleapis/api v0.0.0-20231016165738-49dd2c1f3d0b // indirect

go.sum

+5
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFO
4848
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
4949
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
5050
cloud.google.com/go v0.110.8 h1:tyNdfIxjzaWctIiLYOTalaLKZ17SI44SKFW26QbOhME=
51+
cloud.google.com/go v0.110.8/go.mod h1:Iz8AkXJf1qmxC3Oxoep8R1T36w8B92yU29PcBhHO5fk=
5152
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
5253
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
5354
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
@@ -361,6 +362,8 @@ cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeN
361362
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
362363
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
363364
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
365+
cloud.google.com/go/longrunning v0.5.2 h1:u+oFqfEwwU7F9dIELigxbe0XVnBAo9wqMuQLA50CZ5k=
366+
cloud.google.com/go/longrunning v0.5.2/go.mod h1:nqo6DQbNV2pXhGDbDMoN2bWz68MjZUzqv2YttZiveCs=
364367
cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=
365368
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
366369
cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
@@ -471,6 +474,8 @@ cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7L
471474
cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots=
472475
cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo=
473476
cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI=
477+
cloud.google.com/go/resourcemanager v1.9.2 h1:lC3PjJMHLPlZKqLfan6FkEb3X1F8oCRc1ylY7vRHvDQ=
478+
cloud.google.com/go/resourcemanager v1.9.2/go.mod h1:OujkBg1UZg5lX2yIyMo5Vz9O5hf7XQOSV7WxqxxMtQE=
474479
cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU=
475480
cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=
476481
cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=

pkg/common/parameters.go

+36-2
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ const (
3232
ParameterAvailabilityClass = "availability-class"
3333
ParameterKeyEnableConfidentialCompute = "enable-confidential-storage"
3434
ParameterKeyStoragePools = "storage-pools"
35+
ParameterKeyResourceTags = "resource-tags"
3536

3637
// Parameters for VolumeSnapshotClass
3738
ParameterKeyStorageLocations = "storage-locations"
@@ -98,6 +99,9 @@ type DiskParameters struct {
9899
// Values: {[]string}
99100
// Default: ""
100101
StoragePools []string
102+
// Values: {map[string]string}
103+
// Default: ""
104+
ResourceTags map[string]string
101105
}
102106

103107
// SnapshotParameters contains normalized and defaulted parameters for snapshots
@@ -107,25 +111,31 @@ type SnapshotParameters struct {
107111
ImageFamily string
108112
Tags map[string]string
109113
Labels map[string]string
114+
ResourceTags map[string]string
110115
}
111116

112117
// ExtractAndDefaultParameters will take the relevant parameters from a map and
113118
// put them into a well defined struct making sure to default unspecified fields.
114119
// extraVolumeLabels are added as labels; if there are also labels specified in
115120
// parameters, any matching extraVolumeLabels will be overridden.
116-
func ExtractAndDefaultParameters(parameters map[string]string, driverName string, extraVolumeLabels map[string]string) (DiskParameters, error) {
121+
func ExtractAndDefaultParameters(parameters map[string]string, driverName string, extraVolumeLabels map[string]string, extraTags map[string]string) (DiskParameters, error) {
117122
p := DiskParameters{
118123
DiskType: "pd-standard", // Default
119124
ReplicationType: replicationTypeNone, // Default
120125
DiskEncryptionKMSKey: "", // Default
121126
Tags: make(map[string]string), // Default
122127
Labels: make(map[string]string), // Default
128+
ResourceTags: make(map[string]string), // Default
123129
}
124130

125131
for k, v := range extraVolumeLabels {
126132
p.Labels[k] = v
127133
}
128134

135+
for k, v := range extraTags {
136+
p.ResourceTags[k] = v
137+
}
138+
129139
for k, v := range parameters {
130140
if k == "csiProvisionerSecretName" || k == "csiProvisionerSecretNamespace" {
131141
// These are hardcoded secrets keys required to function but not needed by GCE PD
@@ -198,6 +208,15 @@ func ExtractAndDefaultParameters(parameters map[string]string, driverName string
198208
return p, fmt.Errorf("parameters contain invalid value for %s parameter: %w", ParameterKeyStoragePools, err)
199209
}
200210
p.StoragePools = storagePools
211+
case ParameterKeyResourceTags:
212+
paramResourceTags, err := ConvertTagsStringToMap(v)
213+
if err != nil {
214+
return p, fmt.Errorf("parameters contain invalid tags parameter: %w", err)
215+
}
216+
// Override any existing resource tags with those from this parameter.
217+
for tagParentIDKey, tagValue := range paramResourceTags {
218+
p.ResourceTags[tagParentIDKey] = tagValue
219+
}
201220
default:
202221
return p, fmt.Errorf("parameters contains invalid option %q", k)
203222
}
@@ -208,13 +227,19 @@ func ExtractAndDefaultParameters(parameters map[string]string, driverName string
208227
return p, nil
209228
}
210229

211-
func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverName string) (SnapshotParameters, error) {
230+
func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverName string, extraTags map[string]string) (SnapshotParameters, error) {
212231
p := SnapshotParameters{
213232
StorageLocations: []string{},
214233
SnapshotType: DiskSnapshotType,
215234
Tags: make(map[string]string), // Default
216235
Labels: make(map[string]string), // Default
236+
ResourceTags: make(map[string]string), // Default
217237
}
238+
239+
for k, v := range extraTags {
240+
p.ResourceTags[k] = v
241+
}
242+
218243
for k, v := range parameters {
219244
switch strings.ToLower(k) {
220245
case ParameterKeyStorageLocations:
@@ -246,6 +271,15 @@ func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverNam
246271
for labelKey, labelValue := range paramLabels {
247272
p.Labels[labelKey] = labelValue
248273
}
274+
case ParameterKeyResourceTags:
275+
paramResourceTags, err := ConvertTagsStringToMap(v)
276+
if err != nil {
277+
return p, fmt.Errorf("parameters contain invalid tags parameter: %w", err)
278+
}
279+
// Override any existing resource tags with those from this parameter.
280+
for tagParentIDKey, tagValue := range paramResourceTags {
281+
p.ResourceTags[tagParentIDKey] = tagValue
282+
}
249283
default:
250284
return p, fmt.Errorf("parameters contains invalid option %q", k)
251285
}

0 commit comments

Comments
 (0)