Skip to content

Commit

Permalink
Add support for addition of ResoureManagerTags to GCP Compute Disk, I…
Browse files Browse the repository at this point in the history
…mage, Snapshot resources
  • Loading branch information
arkadeepsen committed Apr 23, 2024
1 parent e26e399 commit 00ed53a
Show file tree
Hide file tree
Showing 73 changed files with 33,156 additions and 29 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ See Github [Issues](https://github.com/kubernetes-sigs/gcp-compute-persistent-di
| labels | `key1=value1,key2=value2` | | Labels allow you to assign custom [GCE Disk labels](https://cloud.google.com/compute/docs/labeling-resources). |
| 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. |
| 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](https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/hyperdisk#create)) for details, including valid ranges for throughput. |
| 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, Image and Snapshot. 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). |

### Topology

Expand Down
12 changes: 11 additions & 1 deletion cmd/gce-pd-csi-driver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ var (

useInstanceAPIOnWaitForAttachDiskTypesFlag = flag.String("use-instance-api-to-poll-attachment-disk-types", "", "Comma separated list of disk types that should use instances.get API when polling for disk attach during ControllerPublish")

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 or Project name 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")

version string
)

Expand Down Expand Up @@ -153,6 +155,14 @@ func handle() {
klog.Fatalf("Bad extra volume labels: %v", err.Error())
}

if len(*extraTagsStr) > 0 && !*runControllerService {
klog.Fatalf("Extra tags provided but not running controller")
}
extraTags, err := common.ConvertTagsStringToMap(*extraTagsStr)
if err != nil {
klog.Fatalf("Bad extra tags: %v", err.Error())
}

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

Expand Down Expand Up @@ -211,7 +221,7 @@ func handle() {
}
}

err = gceDriver.SetupGCEDriver(driverName, version, extraVolumeLabels, identityServer, controllerServer, nodeServer)
err = gceDriver.SetupGCEDriver(driverName, version, extraVolumeLabels, extraTags, identityServer, controllerServer, nodeServer)
if err != nil {
klog.Fatalf("Failed to initialize GCE CSI Driver: %v", err.Error())
}
Expand Down
8 changes: 8 additions & 0 deletions examples/kubernetes/demo-sc-with-resource-tags.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-gce-pd-with-resource-tags
provisioner: pd.csi.storage.gke.io
parameters:
resource-tags: parent1/key1/value1,parent2/key2/value2
volumeBindingMode: WaitForFirstConsumer
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
name: csi-gce-pd-snapshot-class-with-resource-tags
parameters:
resource-tags: parent1/key1/value1,parent2/key2/value2
driver: pd.csi.storage.gke.io
deletionPolicy: Delete
7 changes: 5 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ go 1.20
require (
cloud.google.com/go/compute/metadata v0.2.3
cloud.google.com/go/kms v1.15.8
cloud.google.com/go/resourcemanager v1.9.6
github.com/GoogleCloudPlatform/k8s-cloud-provider v1.24.0
github.com/container-storage-interface/spec v1.6.0
github.com/google/go-cmp v0.6.0
github.com/google/uuid v1.6.0
github.com/googleapis/gax-go/v2 v2.12.3
github.com/kubernetes-csi/csi-proxy/client v1.1.3
github.com/kubernetes-csi/csi-test/v4 v4.4.0
github.com/onsi/ginkgo/v2 v2.17.1
Expand All @@ -20,6 +22,7 @@ require (
go.opentelemetry.io/otel/sdk v1.22.0
golang.org/x/oauth2 v0.19.0
golang.org/x/sys v0.19.0
golang.org/x/time v0.5.0
google.golang.org/api v0.172.0
google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de
google.golang.org/grpc v1.63.2
Expand All @@ -37,8 +40,10 @@ require (
)

require (
cloud.google.com/go v0.112.1 // indirect
cloud.google.com/go/compute v1.25.1 // indirect
cloud.google.com/go/iam v1.1.7 // indirect
cloud.google.com/go/longrunning v0.5.5 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/PuerkitoBio/purell v1.1.1 // indirect
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
Expand All @@ -65,7 +70,6 @@ require (
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 // indirect
github.com/google/s2a-go v0.1.7 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.3.2 // indirect
github.com/googleapis/gax-go/v2 v2.12.3 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
Expand Down Expand Up @@ -99,7 +103,6 @@ require (
golang.org/x/sync v0.7.0 // indirect
golang.org/x/term v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.20.0 // indirect
google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 // indirect
Expand Down
5 changes: 5 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ cloud.google.com/go v0.105.0/go.mod h1:PrLgOJNe5nfE9UMxKxgXj4mD3voiP+YQ6gdt6KMFO
cloud.google.com/go v0.107.0/go.mod h1:wpc2eNrD7hXUTy8EKS10jkxpZBjASrORK7goS+3YX2I=
cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM=
cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4=
cloud.google.com/go/accessapproval v1.4.0/go.mod h1:zybIuC3KpDOvotz59lFe5qxRZx6C75OtwbisN56xYB4=
cloud.google.com/go/accessapproval v1.5.0/go.mod h1:HFy3tuiGvMdcd/u+Cu5b9NkO1pEICJ46IR82PoUdplw=
cloud.google.com/go/accessapproval v1.6.0/go.mod h1:R0EiYnwV5fsRFiKZkPHr6mwyk2wxUJ30nL4j2pcFY2E=
Expand Down Expand Up @@ -361,6 +362,8 @@ cloud.google.com/go/logging v1.7.0/go.mod h1:3xjP2CjkM3ZkO73aj4ASA5wRPGGCRrPIAeN
cloud.google.com/go/longrunning v0.1.1/go.mod h1:UUFxuDWkv22EuY93jjmDMFT5GPQKeFVJBIF6QlTqdsE=
cloud.google.com/go/longrunning v0.3.0/go.mod h1:qth9Y41RRSUE69rDcOn6DdK3HfQfsUI0YSmW3iIlLJc=
cloud.google.com/go/longrunning v0.4.1/go.mod h1:4iWDqhBZ70CvZ6BfETbvam3T8FMvLK+eFj0E6AaRQTo=
cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg=
cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s=
cloud.google.com/go/managedidentities v1.3.0/go.mod h1:UzlW3cBOiPrzucO5qWkNkh0w33KFtBJU281hacNvsdE=
cloud.google.com/go/managedidentities v1.4.0/go.mod h1:NWSBYbEMgqmbZsLIyKvxrYbtqOsxY1ZrGM+9RgDqInM=
cloud.google.com/go/managedidentities v1.5.0/go.mod h1:+dWcZ0JlUmpuxpIDfyP5pP5y0bLdRwOS4Lp7gMni/LA=
Expand Down Expand Up @@ -471,6 +474,8 @@ cloud.google.com/go/resourcemanager v1.4.0/go.mod h1:MwxuzkumyTX7/a3n37gmsT3py7L
cloud.google.com/go/resourcemanager v1.5.0/go.mod h1:eQoXNAiAvCf5PXxWxXjhKQoTMaUSNrEfg+6qdf/wots=
cloud.google.com/go/resourcemanager v1.6.0/go.mod h1:YcpXGRs8fDzcUl1Xw8uOVmI8JEadvhRIkoXXUNVYcVo=
cloud.google.com/go/resourcemanager v1.7.0/go.mod h1:HlD3m6+bwhzj9XCouqmeiGuni95NTrExfhoSrkC/3EI=
cloud.google.com/go/resourcemanager v1.9.6 h1:VPfJFbWxrTYQzEXCDbJNpcvSB8eZhTSM0YHH146fIB8=
cloud.google.com/go/resourcemanager v1.9.6/go.mod h1:d+XUOGbxg6Aka3lmC4fDiserslux3d15uX08C6a0MBg=
cloud.google.com/go/resourcesettings v1.3.0/go.mod h1:lzew8VfESA5DQ8gdlHwMrqZs1S9V87v3oCnKCWoOuQU=
cloud.google.com/go/resourcesettings v1.4.0/go.mod h1:ldiH9IJpcrlC3VSuCGvjR5of/ezRrOxFtpJoJo5SmXg=
cloud.google.com/go/resourcesettings v1.5.0/go.mod h1:+xJF7QSG6undsQDfsCJyqWXyBwUoJLhetkRMDRnIoXA=
Expand Down
40 changes: 38 additions & 2 deletions pkg/common/parameters.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
ParameterAvailabilityClass = "availability-class"
ParameterKeyEnableConfidentialCompute = "enable-confidential-storage"
ParameterKeyStoragePools = "storage-pools"
ParameterKeyResourceTags = "resource-tags"

// Parameters for VolumeSnapshotClass
ParameterKeyStorageLocations = "storage-locations"
Expand Down Expand Up @@ -98,6 +99,9 @@ type DiskParameters struct {
// Values: {[]string}
// Default: ""
StoragePools []StoragePool
// Values: {map[string]string}
// Default: ""
ResourceTags map[string]string
}

// SnapshotParameters contains normalized and defaulted parameters for snapshots
Expand All @@ -107,6 +111,7 @@ type SnapshotParameters struct {
ImageFamily string
Tags map[string]string
Labels map[string]string
ResourceTags map[string]string
}

type StoragePool struct {
Expand All @@ -120,19 +125,24 @@ type StoragePool struct {
// put them into a well defined struct making sure to default unspecified fields.
// extraVolumeLabels are added as labels; if there are also labels specified in
// parameters, any matching extraVolumeLabels will be overridden.
func ExtractAndDefaultParameters(parameters map[string]string, driverName string, extraVolumeLabels map[string]string, enableStoragePools bool) (DiskParameters, error) {
func ExtractAndDefaultParameters(parameters map[string]string, driverName string, extraVolumeLabels map[string]string, enableStoragePools bool, extraTags map[string]string) (DiskParameters, error) {
p := DiskParameters{
DiskType: "pd-standard", // Default
ReplicationType: replicationTypeNone, // Default
DiskEncryptionKMSKey: "", // Default
Tags: make(map[string]string), // Default
Labels: make(map[string]string), // Default
ResourceTags: make(map[string]string), // Default
}

for k, v := range extraVolumeLabels {
p.Labels[k] = v
}

for k, v := range extraTags {
p.ResourceTags[k] = v
}

for k, v := range parameters {
if k == "csiProvisionerSecretName" || k == "csiProvisionerSecretNamespace" {
// These are hardcoded secrets keys required to function but not needed by GCE PD
Expand Down Expand Up @@ -208,6 +218,10 @@ func ExtractAndDefaultParameters(parameters map[string]string, driverName string
return p, fmt.Errorf("parameters contain invalid value for %s parameter: %w", ParameterKeyStoragePools, err)
}
p.StoragePools = storagePools
case ParameterKeyResourceTags:
if err := extractResourceTagsParameter(v, p.ResourceTags); err != nil {
return p, err
}
default:
return p, fmt.Errorf("parameters contains invalid option %q", k)
}
Expand All @@ -218,13 +232,19 @@ func ExtractAndDefaultParameters(parameters map[string]string, driverName string
return p, nil
}

func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverName string) (SnapshotParameters, error) {
func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverName string, extraTags map[string]string) (SnapshotParameters, error) {
p := SnapshotParameters{
StorageLocations: []string{},
SnapshotType: DiskSnapshotType,
Tags: make(map[string]string), // Default
Labels: make(map[string]string), // Default
ResourceTags: make(map[string]string), // Default
}

for k, v := range extraTags {
p.ResourceTags[k] = v
}

for k, v := range parameters {
switch strings.ToLower(k) {
case ParameterKeyStorageLocations:
Expand Down Expand Up @@ -256,6 +276,10 @@ func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverNam
for labelKey, labelValue := range paramLabels {
p.Labels[labelKey] = labelValue
}
case ParameterKeyResourceTags:
if err := extractResourceTagsParameter(v, p.ResourceTags); err != nil {
return p, err
}
default:
return p, fmt.Errorf("parameters contains invalid option %q", k)
}
Expand All @@ -265,3 +289,15 @@ func ExtractAndDefaultSnapshotParameters(parameters map[string]string, driverNam
}
return p, nil
}

func extractResourceTagsParameter(tagsString string, resourceTags map[string]string) error {
paramResourceTags, err := ConvertTagsStringToMap(tagsString)
if err != nil {
return fmt.Errorf("parameters contain invalid %s parameter: %w", ParameterKeyResourceTags, err)
}
// Override any existing resource tags with those from this parameter.
for tagParentIDKey, tagValue := range paramResourceTags {
resourceTags[tagParentIDKey] = tagValue
}
return nil
}
Loading

0 comments on commit 00ed53a

Please sign in to comment.