Skip to content

Add CMEK support #211

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

Merged
merged 2 commits into from
Dec 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
195 changes: 28 additions & 167 deletions Gopkg.lock

Large diffs are not rendered by default.

7 changes: 4 additions & 3 deletions pkg/common/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,11 @@ package common

const (
// Keys for Storage Class Parameters
ParameterKeyType = "type"
ParameterKeyReplicationType = "replication-type"
ParameterKeyType = "type"
ParameterKeyReplicationType = "replication-type"
ParameterKeyDiskEncryptionKmsKey = "disk-encryption-kms-key"

// Keys for Topology. This key will be shared amonst drivers from GCP
// Keys for Topology. This key will be shared amongst drivers from GCP
TopologyKeyZone = "topology.gke.io/zone"

// VolumeAttributes for Partition
Expand Down
12 changes: 11 additions & 1 deletion pkg/gce-cloud-provider/compute/fake-gce.go
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ func (cloud *FakeCloudProvider) ValidateExistingDisk(ctx context.Context, resp *
return nil
}

func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId, diskEncryptionKmsKey string) error {
if disk, ok := cloud.disks[volKey.Name]; ok {
err := cloud.ValidateExistingDisk(ctx, disk, diskType,
int64(capacityRange.GetRequiredBytes()),
Expand All @@ -209,6 +209,11 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
SelfLink: fmt.Sprintf("projects/%s/zones/%s/disks/%s", cloud.project, volKey.Zone, volKey.Name),
SourceSnapshotId: snapshotId,
}
if diskEncryptionKmsKey != "" {
diskToCreateGA.DiskEncryptionKey = &compute.CustomerEncryptionKey{
KmsKeyName: diskEncryptionKmsKey,
}
}
diskToCreate = ZonalCloudDisk(diskToCreateGA)
case meta.Regional:
diskToCreateBeta := &computebeta.Disk{
Expand All @@ -219,6 +224,11 @@ func (cloud *FakeCloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key
SelfLink: fmt.Sprintf("projects/%s/regions/%s/disks/%s", cloud.project, volKey.Region, volKey.Name),
SourceSnapshotId: snapshotId,
}
if diskEncryptionKmsKey != "" {
diskToCreateBeta.DiskEncryptionKey = &computebeta.CustomerEncryptionKey{
KmsKeyName: diskEncryptionKmsKey,
}
}
diskToCreate = RegionalCloudDisk(diskToCreateBeta)
default:
return fmt.Errorf("could not create disk, key was neither zonal nor regional, instead got: %v", volKey.String())
Expand Down
24 changes: 18 additions & 6 deletions pkg/gce-cloud-provider/compute/gce-compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ type GCECompute interface {
GetDisk(ctx context.Context, volumeKey *meta.Key) (*CloudDisk, error)
RepairUnderspecifiedVolumeKey(ctx context.Context, volumeKey *meta.Key) (*meta.Key, error)
ValidateExistingDisk(ctx context.Context, disk *CloudDisk, diskType string, reqBytes, limBytes int64) error
InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error
InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId, diskEncryptionKmsKey string) error
DeleteDisk(ctx context.Context, volumeKey *meta.Key) error
AttachDisk(ctx context.Context, volKey *meta.Key, readWrite, diskType, instanceZone, instanceName string) error
DetachDisk(ctx context.Context, deviceName string, instanceZone, instanceName string) error
Expand Down Expand Up @@ -202,18 +202,18 @@ func (cloud *CloudProvider) ValidateExistingDisk(ctx context.Context, resp *Clou
return nil
}

func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
func (cloud *CloudProvider) InsertDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId, diskEncryptionKmsKey string) error {
switch volKey.Type() {
case meta.Zonal:
return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange, snapshotId)
return cloud.insertZonalDisk(ctx, volKey, diskType, capBytes, capacityRange, snapshotId, diskEncryptionKmsKey)
case meta.Regional:
return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones, snapshotId)
return cloud.insertRegionalDisk(ctx, volKey, diskType, capBytes, capacityRange, replicaZones, snapshotId, diskEncryptionKmsKey)
default:
return fmt.Errorf("could not insert disk, key was neither zonal nor regional, instead got: %v", volKey.String())
}
}

func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId string) error {
func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, replicaZones []string, snapshotId, diskEncryptionKmsKey string) error {
diskToCreateBeta := &computebeta.Disk{
Name: volKey.Name,
SizeGb: common.BytesToGb(capBytes),
Expand All @@ -226,6 +226,11 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
if len(replicaZones) != 0 {
diskToCreateBeta.ReplicaZones = replicaZones
}
if diskEncryptionKmsKey != "" {
diskToCreateBeta.DiskEncryptionKey = &computebeta.CustomerEncryptionKey{
KmsKeyName: diskEncryptionKmsKey,
}
}

insertOp, err := cloud.betaService.RegionDisks.Insert(cloud.project, volKey.Region, diskToCreateBeta).Context(ctx).Do()
if err != nil {
Expand Down Expand Up @@ -267,17 +272,24 @@ func (cloud *CloudProvider) insertRegionalDisk(ctx context.Context, volKey *meta
return nil
}

func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, snapshotId string) error {
func (cloud *CloudProvider) insertZonalDisk(ctx context.Context, volKey *meta.Key, diskType string, capBytes int64, capacityRange *csi.CapacityRange, snapshotId, diskEncryptionKmsKey string) error {
diskToCreate := &compute.Disk{
Name: volKey.Name,
SizeGb: common.BytesToGb(capBytes),
Description: "Disk created by GCE-PD CSI Driver",
Type: cloud.GetDiskTypeURI(volKey, diskType),
}

if snapshotId != "" {
diskToCreate.SourceSnapshot = snapshotId
}

if diskEncryptionKmsKey != "" {
diskToCreate.DiskEncryptionKey = &compute.CustomerEncryptionKey{
KmsKeyName: diskEncryptionKmsKey,
}
}

op, err := cloud.service.Disks.Insert(cloud.project, volKey.Zone, diskToCreate).Context(ctx).Do()

if err != nil {
Expand Down
16 changes: 10 additions & 6 deletions pkg/gce-pd-csi-driver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
diskType := "pd-standard"
// Start process for creating a new disk
replicationType := replicationTypeNone
diskEncryptionKmsKey := ""
for k, v := range req.GetParameters() {
if k == "csiProvisionerSecretName" || k == "csiProvisionerSecretNamespace" {
// These are hardcoded secrets keys required to function but not needed by GCE PD
Expand All @@ -105,6 +106,9 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
diskType = v
case common.ParameterKeyReplicationType:
replicationType = strings.ToLower(v)
case common.ParameterKeyDiskEncryptionKmsKey:
// Resource names (e.g. "keyRings", "cryptoKeys", etc.) are case sensitive, so do not change case
diskEncryptionKmsKey = v
default:
return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("CreateVolume invalid option %q", k))
}
Expand Down Expand Up @@ -172,15 +176,15 @@ func (gceCS *GCEControllerServer) CreateVolume(ctx context.Context, req *csi.Cre
if len(zones) != 1 {
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a single zone for creating zonal disk, instead got: %v", zones))
}
disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
disk, err = createSingleZoneDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId, diskEncryptionKmsKey)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create single zonal disk %#v: %v", name, err))
}
case replicationTypeRegionalPD:
if len(zones) != 2 {
return nil, status.Errorf(codes.Internal, fmt.Sprintf("CreateVolume failed to get a 2 zones for creating regional disk, instead got: %v", zones))
}
disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId)
disk, err = createRegionalDisk(ctx, gceCS.CloudProvider, name, zones, diskType, capacityRange, capBytes, snapshotId, diskEncryptionKmsKey)
if err != nil {
return nil, status.Error(codes.Internal, fmt.Sprintf("CreateVolume failed to create regional disk %#v: %v", name, err))
}
Expand Down Expand Up @@ -888,7 +892,7 @@ func cleanSelfLink(selfLink string) string {
return strings.TrimPrefix(temp, gce.GCEComputeBetaAPIEndpoint)
}

func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId, diskEncryptionKmsKey string) (*gce.CloudDisk, error) {
region, err := common.GetRegionFromZones(zones)
if err != nil {
return nil, fmt.Errorf("failed to get region from zones: %v", err)
Expand All @@ -900,7 +904,7 @@ func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name
fullyQualifiedReplicaZones, cloudProvider.GetReplicaZoneURI(replicaZone))
}

err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones, snapshotId)
err = cloudProvider.InsertDisk(ctx, meta.RegionalKey(name, region), diskType, capBytes, capacityRange, fullyQualifiedReplicaZones, snapshotId, diskEncryptionKmsKey)
if err != nil {
return nil, fmt.Errorf("failed to insert regional disk: %v", err)
}
Expand All @@ -914,12 +918,12 @@ func createRegionalDisk(ctx context.Context, cloudProvider gce.GCECompute, name
return disk, nil
}

func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId string) (*gce.CloudDisk, error) {
func createSingleZoneDisk(ctx context.Context, cloudProvider gce.GCECompute, name string, zones []string, diskType string, capacityRange *csi.CapacityRange, capBytes int64, snapshotId, diskEncryptionKmsKey string) (*gce.CloudDisk, error) {
if len(zones) != 1 {
return nil, fmt.Errorf("got wrong number of zones for zonal create volume: %v", len(zones))
}
diskZone := zones[0]
err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil, snapshotId)
err := cloudProvider.InsertDisk(ctx, meta.ZonalKey(name, diskZone), diskType, capBytes, capacityRange, nil, snapshotId, diskEncryptionKmsKey)
if err != nil {
return nil, fmt.Errorf("failed to insert zonal disk: %v", err)
}
Expand Down
17 changes: 17 additions & 0 deletions pkg/gce-pd-csi-driver/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,23 @@ func TestCreateVolumeArguments(t *testing.T) {
},
expErrCode: codes.Unimplemented, // once block support is implemented, this error should be InvalidArgument
},
{
name: "success with disk encryption kms key",
req: &csi.CreateVolumeRequest{
Name: name,
CapacityRange: stdCapRange,
VolumeCapabilities: stdVolCap,
Parameters: map[string]string{
common.ParameterKeyDiskEncryptionKmsKey: "projects/KMS_PROJECT_ID/locations/REGION/keyRings/KEY_RING/cryptoKeys/KEY",
},
},
expVol: &csi.Volume{
CapacityBytes: common.GbToBytes(20),
VolumeId: testVolumeId,
VolumeContext: nil,
AccessibleTopology: stdTopology,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the Key something that would be ok/useful to add as part of the VolumeContext?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not necessary. Once a volume is provisioned, GCE knows that the key is required and it does not explicitly need to be passed in for attach or mount.

},
},
}

// Run test cases
Expand Down
1 change: 1 addition & 0 deletions vendor/google.golang.org/api/CONTRIBUTORS

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading