Skip to content

Commit

Permalink
feat(controller): support for data at rest encryption (#102)
Browse files Browse the repository at this point in the history
  • Loading branch information
peknur authored Feb 1, 2024
1 parent 99fd2d5 commit acf1bc9
Show file tree
Hide file tree
Showing 8 changed files with 81 additions and 18 deletions.
1 change: 0 additions & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,6 @@ linters-settings:
"PKI",
"PSU",
"PTR",
"REST",
"RSA",
"RTP",
"RX",
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)

## [Unreleased]

### Added

- controller: support for data at rest encryption (using encrypted snapshots as volume source is not supported yet)

## [1.0.1]

### Fixed
Expand Down
21 changes: 21 additions & 0 deletions example/test-pvc-encryption-at-rest.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: upcloud-encrypted-block-storage
namespace: kube-system
parameters:
tier: maxiops
encryption: "data-at-rest"
provisioner: storage.csi.upcloud.com
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-pvc-encrypted
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: upcloud-encrypted-block-storage
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ require (

require github.com/kubernetes-csi/csi-test/v5 v5.0.0

require github.com/UpCloudLtd/upcloud-go-api/v6 v6.6.0
require github.com/UpCloudLtd/upcloud-go-api/v6 v6.12.0

require (
github.com/emicklei/go-restful/v3 v3.9.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/UpCloudLtd/upcloud-go-api/v6 v6.6.0 h1:Fc9a083OBzl8i4pDV2KXCAfxo4gCjJFHgRuPvRnroBY=
github.com/UpCloudLtd/upcloud-go-api/v6 v6.6.0/go.mod h1:I8rWmBBl+OhiY3AGzKbrobiE5TsLCLNYkCQxE4eJcTg=
github.com/UpCloudLtd/upcloud-go-api/v6 v6.12.0 h1:Qol8WuStmqWTXO8Hfel6FjCgLOZ98MGVCvg3ExcEs68=
github.com/UpCloudLtd/upcloud-go-api/v6 v6.12.0/go.mod h1:I8rWmBBl+OhiY3AGzKbrobiE5TsLCLNYkCQxE4eJcTg=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
Expand Down
32 changes: 23 additions & 9 deletions internal/controller/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ func (c *Controller) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequ
}
} else {
volumeReq := &request.CreateStorageRequest{
Zone: c.zone,
Title: req.GetName(),
Size: storageSizeGB,
Tier: tier,
Labels: c.storageLabels,
Zone: c.zone,
Title: req.GetName(),
Size: storageSizeGB,
Tier: tier,
Labels: c.storageLabels,
Encrypted: upcloud.FromBool(createVolumeRequestEncryptionAtRest(req)),
}
logger.WithServiceRequest(log, volumeReq).Info("creating volume")
if vol, err = c.svc.CreateStorage(ctx, volumeReq); err != nil {
Expand Down Expand Up @@ -167,15 +168,20 @@ func (c *Controller) createVolumeFromSource(ctx context.Context, req *csi.Create
}
return nil, status.Errorf(codes.InvalidArgument, err.Error())
}
if src.Encrypted.Bool() != createVolumeRequestEncryptionAtRest(req) {
// To prevent unexpected dst device properties, only allow cloning from device with same encryption policy.
return nil, status.Errorf(codes.InvalidArgument, "source and destination volumes needs to have same encryption policy")
}
log.Info("checking that source storage is online")
if err := c.svc.RequireStorageOnline(ctx, &src.Storage); err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
volumeReq := &request.CloneStorageRequest{
UUID: src.Storage.UUID,
Zone: c.zone,
Tier: tier,
Title: req.GetName(),
UUID: src.Storage.UUID,
Zone: c.zone,
Tier: tier,
Title: req.GetName(),
Encrypted: src.Encrypted,
}
logger.WithServiceRequest(log, volumeReq).Info("cloning volume")
vol, err := c.svc.CloneStorage(ctx, volumeReq, c.storageLabels...)
Expand Down Expand Up @@ -750,6 +756,14 @@ func createVolumeRequestTier(r *csi.CreateVolumeRequest) (string, error) {
return "", status.Error(codes.InvalidArgument, fmt.Sprintf("storage tier '%s' not supported", tier))
}

func createVolumeRequestEncryptionAtRest(r *csi.CreateVolumeRequest) bool {
e, ok := r.Parameters["encryption"]
if ok && e == "data-at-rest" {
return true
}
return false
}

func validateCreateVolumeRequest(r *csi.CreateVolumeRequest, zone string) error {
if r.GetName() == "" {
return status.Error(codes.InvalidArgument, "CreateVolume Name cannot be empty")
Expand Down
20 changes: 20 additions & 0 deletions internal/controller/controller_internal_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"testing"

"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
"github.com/container-storage-interface/spec/lib/go/csi"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestPaginateStorage(t *testing.T) {
Expand Down Expand Up @@ -88,3 +90,21 @@ func TestIsValidStorageUUID(t *testing.T) {
assert.True(t, isValidUUID("1160ffc3-58ec-4670-bdc9-27fe385d281d"))
assert.True(t, isValidUUID("0160ffc3-58ec-4670-bdc9-27fe385d281d"))
}

func TestCreateVolumeRequestEncryptionAtRest(t *testing.T) {
t.Parallel()

require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{}))

p := map[string]string{}
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))

p["encryption"] = "data-at-restx"
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))

p["encryption"] = ""
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))

p["encryption"] = "data-at-rest"
require.True(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))
}
15 changes: 10 additions & 5 deletions internal/service/mock/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ func newMockStorage(size int, label ...upcloud.Label) *upcloud.Storage {
id, _ := uuid.NewUUID()

return &upcloud.Storage{
Size: size,
UUID: id.String(),
Labels: label,
Size: size,
UUID: id.String(),
Labels: label,
Encrypted: 0,
}
}

Expand Down Expand Up @@ -62,8 +63,10 @@ func (m *UpCloudServiceMock) GetStorageByName(ctx context.Context, storageName s

func (m *UpCloudServiceMock) CreateStorage(ctx context.Context, csr *request.CreateStorageRequest) (*upcloud.StorageDetails, error) {
id, _ := uuid.NewUUID()
storage := newMockStorage(m.StorageSize)
storage.Encrypted = csr.Encrypted
s := &upcloud.StorageDetails{
Storage: *newMockStorage(m.StorageSize),
Storage: *storage,
ServerUUIDs: upcloud.ServerUUIDSlice{id.String()}, // TODO change UUID prefix
}

Expand All @@ -72,8 +75,10 @@ func (m *UpCloudServiceMock) CreateStorage(ctx context.Context, csr *request.Cre

func (m *UpCloudServiceMock) CloneStorage(ctx context.Context, csr *request.CloneStorageRequest, label ...upcloud.Label) (*upcloud.StorageDetails, error) {
id, _ := uuid.NewUUID()
storage := newMockStorage(m.CloneStorageSize, label...)
storage.Encrypted = csr.Encrypted
s := &upcloud.StorageDetails{
Storage: *newMockStorage(m.CloneStorageSize, label...),
Storage: *storage,
ServerUUIDs: upcloud.ServerUUIDSlice{id.String()}, // TODO change UUID prefix
}

Expand Down

0 comments on commit acf1bc9

Please sign in to comment.