Skip to content

Commit acf1bc9

Browse files
authored
feat(controller): support for data at rest encryption (#102)
1 parent 99fd2d5 commit acf1bc9

File tree

8 files changed

+81
-18
lines changed

8 files changed

+81
-18
lines changed

.golangci.yml

-1
Original file line numberDiff line numberDiff line change
@@ -682,7 +682,6 @@ linters-settings:
682682
"PKI",
683683
"PSU",
684684
"PTR",
685-
"REST",
686685
"RSA",
687686
"RTP",
688687
"RX",

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ See updating [Changelog example here](https://keepachangelog.com/en/1.0.0/)
55

66
## [Unreleased]
77

8+
### Added
9+
10+
- controller: support for data at rest encryption (using encrypted snapshots as volume source is not supported yet)
11+
812
## [1.0.1]
913

1014
### Fixed
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
kind: StorageClass
2+
apiVersion: storage.k8s.io/v1
3+
metadata:
4+
name: upcloud-encrypted-block-storage
5+
namespace: kube-system
6+
parameters:
7+
tier: maxiops
8+
encryption: "data-at-rest"
9+
provisioner: storage.csi.upcloud.com
10+
---
11+
apiVersion: v1
12+
kind: PersistentVolumeClaim
13+
metadata:
14+
name: csi-pvc-encrypted
15+
spec:
16+
accessModes:
17+
- ReadWriteOnce
18+
resources:
19+
requests:
20+
storage: 10Gi
21+
storageClassName: upcloud-encrypted-block-storage

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ require (
2222

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

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

2727
require (
2828
github.com/emicklei/go-restful/v3 v3.9.0 // indirect

go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
22
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
33
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
44
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
5-
github.com/UpCloudLtd/upcloud-go-api/v6 v6.6.0 h1:Fc9a083OBzl8i4pDV2KXCAfxo4gCjJFHgRuPvRnroBY=
6-
github.com/UpCloudLtd/upcloud-go-api/v6 v6.6.0/go.mod h1:I8rWmBBl+OhiY3AGzKbrobiE5TsLCLNYkCQxE4eJcTg=
5+
github.com/UpCloudLtd/upcloud-go-api/v6 v6.12.0 h1:Qol8WuStmqWTXO8Hfel6FjCgLOZ98MGVCvg3ExcEs68=
6+
github.com/UpCloudLtd/upcloud-go-api/v6 v6.12.0/go.mod h1:I8rWmBBl+OhiY3AGzKbrobiE5TsLCLNYkCQxE4eJcTg=
77
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
88
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
99
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=

internal/controller/controller.go

+23-9
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,12 @@ func (c *Controller) CreateVolume(ctx context.Context, req *csi.CreateVolumeRequ
8686
}
8787
} else {
8888
volumeReq := &request.CreateStorageRequest{
89-
Zone: c.zone,
90-
Title: req.GetName(),
91-
Size: storageSizeGB,
92-
Tier: tier,
93-
Labels: c.storageLabels,
89+
Zone: c.zone,
90+
Title: req.GetName(),
91+
Size: storageSizeGB,
92+
Tier: tier,
93+
Labels: c.storageLabels,
94+
Encrypted: upcloud.FromBool(createVolumeRequestEncryptionAtRest(req)),
9495
}
9596
logger.WithServiceRequest(log, volumeReq).Info("creating volume")
9697
if vol, err = c.svc.CreateStorage(ctx, volumeReq); err != nil {
@@ -167,15 +168,20 @@ func (c *Controller) createVolumeFromSource(ctx context.Context, req *csi.Create
167168
}
168169
return nil, status.Errorf(codes.InvalidArgument, err.Error())
169170
}
171+
if src.Encrypted.Bool() != createVolumeRequestEncryptionAtRest(req) {
172+
// To prevent unexpected dst device properties, only allow cloning from device with same encryption policy.
173+
return nil, status.Errorf(codes.InvalidArgument, "source and destination volumes needs to have same encryption policy")
174+
}
170175
log.Info("checking that source storage is online")
171176
if err := c.svc.RequireStorageOnline(ctx, &src.Storage); err != nil {
172177
return nil, status.Error(codes.Internal, err.Error())
173178
}
174179
volumeReq := &request.CloneStorageRequest{
175-
UUID: src.Storage.UUID,
176-
Zone: c.zone,
177-
Tier: tier,
178-
Title: req.GetName(),
180+
UUID: src.Storage.UUID,
181+
Zone: c.zone,
182+
Tier: tier,
183+
Title: req.GetName(),
184+
Encrypted: src.Encrypted,
179185
}
180186
logger.WithServiceRequest(log, volumeReq).Info("cloning volume")
181187
vol, err := c.svc.CloneStorage(ctx, volumeReq, c.storageLabels...)
@@ -750,6 +756,14 @@ func createVolumeRequestTier(r *csi.CreateVolumeRequest) (string, error) {
750756
return "", status.Error(codes.InvalidArgument, fmt.Sprintf("storage tier '%s' not supported", tier))
751757
}
752758

759+
func createVolumeRequestEncryptionAtRest(r *csi.CreateVolumeRequest) bool {
760+
e, ok := r.Parameters["encryption"]
761+
if ok && e == "data-at-rest" {
762+
return true
763+
}
764+
return false
765+
}
766+
753767
func validateCreateVolumeRequest(r *csi.CreateVolumeRequest, zone string) error {
754768
if r.GetName() == "" {
755769
return status.Error(codes.InvalidArgument, "CreateVolume Name cannot be empty")

internal/controller/controller_internal_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"testing"
55

66
"github.com/UpCloudLtd/upcloud-go-api/v6/upcloud"
7+
"github.com/container-storage-interface/spec/lib/go/csi"
78
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
810
)
911

1012
func TestPaginateStorage(t *testing.T) {
@@ -88,3 +90,21 @@ func TestIsValidStorageUUID(t *testing.T) {
8890
assert.True(t, isValidUUID("1160ffc3-58ec-4670-bdc9-27fe385d281d"))
8991
assert.True(t, isValidUUID("0160ffc3-58ec-4670-bdc9-27fe385d281d"))
9092
}
93+
94+
func TestCreateVolumeRequestEncryptionAtRest(t *testing.T) {
95+
t.Parallel()
96+
97+
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{}))
98+
99+
p := map[string]string{}
100+
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))
101+
102+
p["encryption"] = "data-at-restx"
103+
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))
104+
105+
p["encryption"] = ""
106+
require.False(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))
107+
108+
p["encryption"] = "data-at-rest"
109+
require.True(t, createVolumeRequestEncryptionAtRest(&csi.CreateVolumeRequest{Parameters: p}))
110+
}

internal/service/mock/service.go

+10-5
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,10 @@ func newMockStorage(size int, label ...upcloud.Label) *upcloud.Storage {
2323
id, _ := uuid.NewUUID()
2424

2525
return &upcloud.Storage{
26-
Size: size,
27-
UUID: id.String(),
28-
Labels: label,
26+
Size: size,
27+
UUID: id.String(),
28+
Labels: label,
29+
Encrypted: 0,
2930
}
3031
}
3132

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

6364
func (m *UpCloudServiceMock) CreateStorage(ctx context.Context, csr *request.CreateStorageRequest) (*upcloud.StorageDetails, error) {
6465
id, _ := uuid.NewUUID()
66+
storage := newMockStorage(m.StorageSize)
67+
storage.Encrypted = csr.Encrypted
6568
s := &upcloud.StorageDetails{
66-
Storage: *newMockStorage(m.StorageSize),
69+
Storage: *storage,
6770
ServerUUIDs: upcloud.ServerUUIDSlice{id.String()}, // TODO change UUID prefix
6871
}
6972

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

7376
func (m *UpCloudServiceMock) CloneStorage(ctx context.Context, csr *request.CloneStorageRequest, label ...upcloud.Label) (*upcloud.StorageDetails, error) {
7477
id, _ := uuid.NewUUID()
78+
storage := newMockStorage(m.CloneStorageSize, label...)
79+
storage.Encrypted = csr.Encrypted
7580
s := &upcloud.StorageDetails{
76-
Storage: *newMockStorage(m.CloneStorageSize, label...),
81+
Storage: *storage,
7782
ServerUUIDs: upcloud.ServerUUIDSlice{id.String()}, // TODO change UUID prefix
7883
}
7984

0 commit comments

Comments
 (0)