Skip to content

Commit 48235c2

Browse files
committed
Add metadata info in tag on PD
1 parent f476c98 commit 48235c2

File tree

7 files changed

+134
-14
lines changed

7 files changed

+134
-14
lines changed

deploy/kubernetes/base/controller/controller.yaml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ spec:
3232
- "--enable-leader-election"
3333
- "--leader-election-type=leases"
3434
- "--leader-election-namespace=$(PDCSI_NAMESPACE)"
35+
- "--extra-create-metadata"
3536
# - "--run-controller-service=false" # disable the controller service of the CSI driver
3637
# - "--run-node-service=false" # disable the node service of the CSI driver
3738
env:

deploy/kubernetes/images/dev/image.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ metadata:
44
name: imagetag-gcepd-driver-dev
55
imageTag:
66
name: gke.gcr.io/gcp-compute-persistent-disk-csi-driver
7-
newName: gcr.io/dyzz-csi-staging/csi/gce-pd-driver
7+
newName: gcr.io/saads-vms2/pd-csi
88
newTag: "latest"

pkg/common/parameters.go

+29-4
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@ const (
2727
ParameterKeyDiskEncryptionKmsKey = "disk-encryption-kms-key"
2828

2929
replicationTypeNone = "none"
30+
31+
// Keys for PV and PVC parameters as reported by external-provisioner
32+
ParameterKeyPVCName = "csi.storage.k8s.io/pvc/name"
33+
ParameterKeyPVCNamespace = "csi.storage.k8s.io/pvc/namespace"
34+
ParameterKeyPVName = "csi.storage.k8s.io/pv/name"
35+
36+
// Keys for tags to attach to the provisioned disk.
37+
tagKeyCreatedForClaimNamespace = "kubernetes.io/created-for/pvc/namespace"
38+
tagKeyCreatedForClaimName = "kubernetes.io/created-for/pvc/name"
39+
tagKeyCreatedForVolumeName = "kubernetes.io/created-for/pv/name"
40+
tagKeyCreatedBy = "storage.gke.io/created-by"
3041
)
3142

3243
// DiskParameters contains normalized and defaulted disk parameters
@@ -40,16 +51,21 @@ type DiskParameters struct {
4051
// Values: {string}
4152
// Default: ""
4253
DiskEncryptionKMSKey string
54+
// Values: {map[string]string}
55+
// Default: ""
56+
Tags map[string]string
4357
}
4458

4559
// ExtractAndDefaultParameters will take the relevant parameters from a map and
4660
// put them into a well defined struct making sure to default unspecified fields
47-
func ExtractAndDefaultParameters(parameters map[string]string) (DiskParameters, error) {
61+
func ExtractAndDefaultParameters(parameters map[string]string, driverName string) (DiskParameters, error) {
4862
p := DiskParameters{
49-
DiskType: "pd-standard", // Default
50-
ReplicationType: replicationTypeNone, // Default
51-
DiskEncryptionKMSKey: "", // Default
63+
DiskType: "pd-standard", // Default
64+
ReplicationType: replicationTypeNone, // Default
65+
DiskEncryptionKMSKey: "", // Default
66+
Tags: make(map[string]string), // Default
5267
}
68+
5369
for k, v := range parameters {
5470
if k == "csiProvisionerSecretName" || k == "csiProvisionerSecretNamespace" {
5571
// These are hardcoded secrets keys required to function but not needed by GCE PD
@@ -67,9 +83,18 @@ func ExtractAndDefaultParameters(parameters map[string]string) (DiskParameters,
6783
case ParameterKeyDiskEncryptionKmsKey:
6884
// Resource names (e.g. "keyRings", "cryptoKeys", etc.) are case sensitive, so do not change case
6985
p.DiskEncryptionKMSKey = v
86+
case ParameterKeyPVCName:
87+
p.Tags[tagKeyCreatedForClaimName] = v
88+
case ParameterKeyPVCNamespace:
89+
p.Tags[tagKeyCreatedForClaimNamespace] = v
90+
case ParameterKeyPVName:
91+
p.Tags[tagKeyCreatedForVolumeName] = v
7092
default:
7193
return p, fmt.Errorf("parameters contains invalid option %q", k)
7294
}
7395
}
96+
if len(p.Tags) > 0 {
97+
p.Tags[tagKeyCreatedBy] = driverName
98+
}
7499
return p, nil
75100
}

pkg/common/parameters_test.go

+15-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ func TestExtractAndDefaultParameters(t *testing.T) {
3535
DiskType: "pd-standard",
3636
ReplicationType: "none",
3737
DiskEncryptionKMSKey: "",
38+
Tags: make(map[string]string),
3839
},
3940
},
4041
{
@@ -44,6 +45,7 @@ func TestExtractAndDefaultParameters(t *testing.T) {
4445
DiskType: "pd-standard",
4546
ReplicationType: "none",
4647
DiskEncryptionKMSKey: "",
48+
Tags: make(map[string]string),
4749
},
4850
},
4951
{
@@ -58,6 +60,7 @@ func TestExtractAndDefaultParameters(t *testing.T) {
5860
DiskType: "pd-ssd",
5961
ReplicationType: "regional-pd",
6062
DiskEncryptionKMSKey: "foo/key",
63+
Tags: make(map[string]string),
6164
},
6265
},
6366
{
@@ -67,13 +70,24 @@ func TestExtractAndDefaultParameters(t *testing.T) {
6770
DiskType: "pd-standard",
6871
ReplicationType: "none",
6972
DiskEncryptionKMSKey: "foo/key",
73+
Tags: make(map[string]string),
74+
},
75+
},
76+
{
77+
name: "tags",
78+
parameters: map[string]string{ParameterKeyPVCName: "testPVCName", ParameterKeyPVCNamespace: "testPVCNamespace", ParameterKeyPVName: "testPVName"},
79+
expectParams: DiskParameters{
80+
DiskType: "pd-standard",
81+
ReplicationType: "none",
82+
DiskEncryptionKMSKey: "",
83+
Tags: map[string]string{tagKeyCreatedForClaimName: "testPVCName", tagKeyCreatedForClaimNamespace: "testPVCNamespace", tagKeyCreatedForVolumeName: "testPVName", tagKeyCreatedBy: "testDriver"},
7084
},
7185
},
7286
}
7387

7488
for _, tc := range tests {
7589
t.Run(tc.name, func(t *testing.T) {
76-
p, err := ExtractAndDefaultParameters(tc.parameters)
90+
p, err := ExtractAndDefaultParameters(tc.parameters, "testDriver")
7791
if gotErr := err != nil; gotErr != tc.expectErr {
7892
t.Fatalf("ExtractAndDefaultParameters(%+v) = %v; expectedErr: %v", tc.parameters, err, tc.expectErr)
7993
}

pkg/gce-cloud-provider/compute/gce-compute.go

+50-6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ limitations under the License.
1515
package gcecloudprovider
1616

1717
import (
18+
"encoding/json"
1819
"fmt"
1920
"strings"
2021
"time"
@@ -268,21 +269,42 @@ func ValidateDiskParameters(disk *CloudDisk, params common.DiskParameters) error
268269

269270
func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, params common.DiskParameters, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotID string) error {
270271
klog.V(5).Infof("Inserting disk %v", volKey)
272+
273+
description, err := encodeDiskTags(params.Tags)
274+
if err != nil {
275+
return err
276+
}
277+
271278
switch volKey.Type() {
272279
case meta.Zonal:
273-
return cloud.insertZonalDisk(ctx, volKey, params, capBytes, capacityRange, snapshotID)
280+
if description == "" {
281+
description = "Disk created by GCE-PD CSI Driver"
282+
}
283+
return cloud.insertZonalDisk(ctx, volKey, params, capBytes, capacityRange, snapshotID, description)
274284
case meta.Regional:
275-
return cloud.insertRegionalDisk(ctx, volKey, params, capBytes, capacityRange, replicaZones, snapshotID)
285+
if description == "" {
286+
description = "Regional disk created by GCE-PD CSI Driver"
287+
}
288+
return cloud.insertRegionalDisk(ctx, volKey, params, capBytes, capacityRange, replicaZones, snapshotID, description)
276289
default:
277290
return fmt.Errorf("could not insert disk, key was neither zonal nor regional, instead got: %v", volKey.String())
278291
}
279292
}
280293

281-
func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, params common.DiskParameters, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotID string) error {
294+
func (cloud *CloudProvider) insertRegionalDisk(
295+
ctx context.Context,
296+
volKey *meta.Key,
297+
params common.DiskParameters,
298+
capBytes int64,
299+
capacityRange *csi.CapacityRange,
300+
replicaZones []string,
301+
snapshotID string,
302+
description string) error {
303+
282304
diskToCreate := &computev1.Disk{
283305
Name: volKey.Name,
284306
SizeGb: common.BytesToGb(capBytes),
285-
Description: "Regional disk created by GCE-PD CSI Driver",
307+
Description: description,
286308
Type: cloud.GetDiskTypeURI(volKey, params.DiskType),
287309
}
288310
if snapshotID != "" {
@@ -337,11 +359,18 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
337359
return nil
338360
}
339361

340-
func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, params common.DiskParameters, capBytes int64, capacityRange *csi.CapacityRange, snapshotID string) error {
362+
func (cloud *CloudProvider) insertZonalDisk(
363+
ctx context.Context,
364+
volKey *meta.Key,
365+
params common.DiskParameters,
366+
capBytes int64,
367+
capacityRange *csi.CapacityRange,
368+
snapshotID string,
369+
description string) error {
341370
diskToCreate := &computev1.Disk{
342371
Name: volKey.Name,
343372
SizeGb: common.BytesToGb(capBytes),
344-
Description: "Disk created by GCE-PD CSI Driver",
373+
Description: description,
345374
Type: cloud.GetDiskTypeURI(volKey, params.DiskType),
346375
}
347376

@@ -788,3 +817,18 @@ func removeCryptoKeyVersion(kmsKey string) string {
788817
}
789818
return kmsKey
790819
}
820+
821+
// encodeDiskTags encodes requested volume tags into JSON string, as GCE does
822+
// not support tags on GCE PDs and we use Description field as fallback.
823+
func encodeDiskTags(tags map[string]string) (string, error) {
824+
if len(tags) == 0 {
825+
// No tags -> empty JSON
826+
return "", nil
827+
}
828+
829+
enc, err := json.Marshal(tags)
830+
if err != nil {
831+
return "", fmt.Errorf("failed to encodeDiskTags %v: %v", tags, err)
832+
}
833+
return string(enc), nil
834+
}

pkg/gce-pd-csi-driver/controller.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
110110

111111
// Apply Parameters (case-insensitive). We leave validation of
112112
// the values to the cloud provider.
113-
params, err := common.ExtractAndDefaultParameters(req.GetParameters())
113+
params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name)
114114
if err != nil {
115115
return nil, status.Errorf(codes.InvalidArgument, "failed to extract parameters: %v", err)
116116
}
@@ -471,7 +471,7 @@ func (gceCS *GCEControllerServer) ValidateVolumeCapabilities(ctx context.Context
471471
}
472472

473473
// Validate the disk parameters match the disk we GET
474-
params, err := common.ExtractAndDefaultParameters(req.GetParameters())
474+
params, err := common.ExtractAndDefaultParameters(req.GetParameters(), gceCS.Driver.name)
475475
if err != nil {
476476
return nil, status.Errorf(codes.InvalidArgument, "failed to extract parameters: %v", err)
477477
}

test/e2e/tests/single_zone_e2e_test.go

+36
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,42 @@ var _ = Describe("GCE PD CSI Driver", func() {
676676
Expect(err).To(BeNil(), "Failed to go through volume lifecycle")
677677
})
678678

679+
It("Should successfully create disk with PVC/PV tags", func() {
680+
Expect(testContexts).ToNot(BeEmpty())
681+
testContext := getRandomTestContext()
682+
683+
controllerInstance := testContext.Instance
684+
controllerClient := testContext.Client
685+
686+
p, z, _ := controllerInstance.GetIdentity()
687+
688+
// Create Disk
689+
volName := testNamePrefix + string(uuid.NewUUID())
690+
volID, err := controllerClient.CreateVolume(volName, map[string]string{
691+
common.ParameterKeyPVCName: "test-pvc",
692+
common.ParameterKeyPVCNamespace: "test-pvc-namespace",
693+
common.ParameterKeyPVName: "test-pv-name",
694+
}, defaultSizeGb, nil /* topReq */)
695+
Expect(err).To(BeNil(), "CreateVolume failed with error: %v", err)
696+
697+
// Validate Disk Created
698+
cloudDisk, err := computeService.Disks.Get(p, z, volName).Do()
699+
Expect(err).To(BeNil(), "Could not get disk from cloud directly")
700+
Expect(cloudDisk.Type).To(ContainSubstring(standardDiskType))
701+
Expect(cloudDisk.Status).To(Equal(readyState))
702+
Expect(cloudDisk.SizeGb).To(Equal(defaultSizeGb))
703+
Expect(cloudDisk.Name).To(Equal(volName))
704+
Expect(cloudDisk.Description).To(Equal("{\"kubernetes.io/created-for/pv/name\":\"test-pv-name\",\"kubernetes.io/created-for/pvc/name\":\"test-pvc\",\"kubernetes.io/created-for/pvc/namespace\":\"test-pvc-namespace\",\"storage.gke.io/created-by\":\"pd.csi.storage.gke.io\"}"))
705+
defer func() {
706+
// Delete Disk
707+
controllerClient.DeleteVolume(volID)
708+
Expect(err).To(BeNil(), "DeleteVolume failed")
709+
710+
// Validate Disk Deleted
711+
_, err = computeService.Disks.Get(p, z, volName).Do()
712+
Expect(gce.IsGCEError(err, "notFound")).To(BeTrue(), "Expected disk to not be found")
713+
}()
714+
})
679715
})
680716

681717
func equalWithinEpsilon(a, b, epsiolon int64) bool {

0 commit comments

Comments
 (0)