Skip to content

Commit

Permalink
Merge pull request #133 from schinmai-akamai/master
Browse files Browse the repository at this point in the history
Allow passing tags to volumes using the storage class
  • Loading branch information
luthermonson authored Nov 22, 2023
2 parents 3da0b84 + db6afe9 commit 258a04f
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 24 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,25 @@ spec:
storage: 10Gi
storageClassName: linode-block-storage-retain-luks
```
### Adding Tags to created volumes
This feature gives users the ability to add tags to volumes created by a specific storageClass, to allow for better tracking of volumes.
Tags are added as a comma seperated string value for a parameter `linodebs.csi.linode.com/volumeTags`

#### Example StorageClass
```
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
name: linode-block-storage
namespace: kube-system
provisioner: linodebs.csi.linode.com
parameters:
linodebs.csi.linode.com/volumeTags: "test, foo, yolo"
```


## Disclaimers

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
{{- end }}
{{- if .Values.volumeTags }}
parameters:
linodebs.csi.linode.com/volumeTags: {{ join "," .Values.volumeTags }}
{{- end}}
allowVolumeExpansion: true
provisioner: linodebs.csi.linode.com
reclaimPolicy: Retain
4 changes: 4 additions & 0 deletions helm-chart/csi-driver/templates/linode-block-storage.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,9 @@ metadata:
annotations:
storageclass.kubernetes.io/is-default-class: "true"
{{- end }}
{{- if .Values.volumeTags }}
parameters:
linodebs.csi.linode.com/volumeTags: {{ join "," .Values.volumeTags }}
{{- end}}
allowVolumeExpansion: true
provisioner: linodebs.csi.linode.com
10 changes: 8 additions & 2 deletions helm-chart/csi-driver/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,13 @@ namespace: kube-system
# "linode-block-storage" or left as an empty string
defaultStorageClass: linode-block-storage-retain

# Images - Default
# set these value to a comma seperated string if you'd like to add tags to the created volumes
#volumeTags:
# - example
# - test

# Images - Default

csiProvisioner:
image: registry.k8s.io/sig-storage/csi-provisioner
tag: v3.0.0
Expand All @@ -45,4 +51,4 @@ kubectl:

csiNodeDriverRegistrar:
image: registry.k8s.io/sig-storage/csi-node-driver-registrar
tag: v1.3.0
tag: v1.3.0
34 changes: 28 additions & 6 deletions pkg/linode-bs/controllerserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,28 @@ import (
"google.golang.org/grpc/status"
)

const gigabyte = 1024 * 1024 * 1024
const minProviderVolumeBytes = 10 * gigabyte
const waitTimeout = 300
const devicePathKey = "devicePath"
type VolumeLifecycle string

const (
gigabyte = 1024 * 1024 * 1024
driverName = "linodebs.csi.linode.com"
devicePathKey = "devicePath"
waitTimeout = 300
minProviderVolumeBytes = 10 * gigabyte

// VolumeTags is a comma seperated string used to pass information to the linode APIs to tag the
// created volumes
VolumeTags = driverName + "/volumeTags"

// PublishInfoVolumeName is used to pass the volume name from
// `ControllerPublishVolume` to `NodeStageVolume or `NodePublishVolume`
PublishInfoVolumeName = driverName + "/volume-name"

VolumeLifecycleNodeStageVolume VolumeLifecycle = "NodeStageVolume"
VolumeLifecycleNodePublishVolume VolumeLifecycle = "NodePublishVolume"
VolumeLifecycleNodeUnstageVolume VolumeLifecycle = "NodeUnstageVolume"
VolumeLifecycleNodeUnpublishVolume VolumeLifecycle = "NodeUnpublishVolume"
)

type LinodeControllerServer struct {
Driver *LinodeDriver
Expand Down Expand Up @@ -102,6 +120,8 @@ func (linodeCS *LinodeControllerServer) CreateVolume(ctx context.Context, req *c
volumeContext[LuksKeySizeAttribute] = req.Parameters[LuksKeySizeAttribute]
}

tags := req.Parameters[VolumeTags]

if len(volumes) != 0 {
if len(volumes) > 1 {
return nil, status.Error(codes.AlreadyExists, fmt.Sprintf("duplicate volume %q exists", volumeName))
Expand Down Expand Up @@ -131,7 +151,7 @@ func (linodeCS *LinodeControllerServer) CreateVolume(ctx context.Context, req *c
vol, err = linodeCS.cloneLinodeVolume(ctx, volumeName, volumeSizeGB, sourceVolumeInfo.VolumeID)
} else {
// Create the volume from scratch
vol, err = linodeCS.createLinodeVolume(ctx, volumeName, volumeSizeGB)
vol, err = linodeCS.createLinodeVolume(ctx, volumeName, volumeSizeGB, tags)
}

// Error handling for the above function calls
Expand Down Expand Up @@ -546,11 +566,13 @@ func (linodeCS *LinodeControllerServer) attemptGetContentSourceVolume(

// createLinodeVolume creates a Linode volume and returns the result
func (linodeCS *LinodeControllerServer) createLinodeVolume(
ctx context.Context, label string, sizeGB int) (*linodego.Volume, error) {
ctx context.Context, label string, sizeGB int, tags string) (*linodego.Volume, error) {

volumeReq := linodego.VolumeCreateOptions{
Region: linodeCS.MetadataService.GetZone(),
Label: label,
Size: sizeGB,
Tags: strings.Split(tags, ","),
}

glog.V(4).Infoln("creating volume", map[string]interface{}{"volume_req": volumeReq})
Expand Down
1 change: 1 addition & 0 deletions pkg/linode-bs/driver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,7 @@ func (f *fakeAPI) ServeHTTP(w http.ResponseWriter, r *http.Request) {
Size: v.Size,
FilesystemPath: path,
Status: linodego.VolumeActive,
Tags: v.Tags,
Created: &now,
Updated: &now,
}
Expand Down
15 changes: 1 addition & 14 deletions pkg/linode-bs/luks.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import (
"github.com/golang/glog"
)

type VolumeLifecycle string

type LuksContext struct {
EncryptionEnabled bool
EncryptionKey string
Expand All @@ -44,12 +42,6 @@ type LuksContext struct {
}

const (
driverName = "linodebs.csi.linode.com"

// PublishInfoVolumeName is used to pass the volume name from
// `ControllerPublishVolume` to `NodeStageVolume or `NodePublishVolume`
PublishInfoVolumeName = driverName + "/volume-name"

// LuksEncryptedAttribute is used to pass the information if the volume should be
// encrypted with luks to `NodeStageVolume`
LuksEncryptedAttribute = driverName + "/luks-encrypted"
Expand All @@ -64,11 +56,6 @@ const (

// LuksKeyAttribute is the key of the luks key used in the map of secrets passed from the CO
LuksKeyAttribute = "luksKey"

VolumeLifecycleNodeStageVolume VolumeLifecycle = "NodeStageVolume"
VolumeLifecycleNodePublishVolume VolumeLifecycle = "NodePublishVolume"
VolumeLifecycleNodeUnstageVolume VolumeLifecycle = "NodeUnstageVolume"
VolumeLifecycleNodeUnpublishVolume VolumeLifecycle = "NodeUnpublishVolume"
)

func (ctx *LuksContext) validate() error {
Expand Down Expand Up @@ -257,7 +244,7 @@ func luksClose(volume string) error {
func luksOpen(volume string, keyFile string, ctx LuksContext) error {
// check if the luks volume is already open
if _, err := os.Stat("/dev/mapper/" + ctx.VolumeName); !os.IsNotExist(err) {
glog.V(4).Info("luks volume is already open %s", volume)
glog.V(4).Infof("luks volume is already open %s", volume)
return nil
}

Expand Down
4 changes: 2 additions & 2 deletions pkg/linode-bs/nodeserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ func (ns *LinodeNodeServer) NodeUnpublishVolume(ctx context.Context, req *csi.No
return nil, status.Error(codes.Internal, fmt.Sprintf("Unmount failed: %v\nUnmounting arguments: %s\n", err, targetPath))
}

glog.V(4).Infof("NodeUnpublishVolume called with args: %v, targetPath ", req, targetPath)
glog.V(4).Infof("NodeUnpublishVolume called with args: %v, targetPath %s", req, targetPath)

if err := closeMountSources(targetPath); err != nil {
return nil, err
Expand Down Expand Up @@ -370,7 +370,7 @@ func closeMountSources(path string) error {
return status.Error(codes.Internal, fmt.Sprintf("closeMountSources failed determine if mount is a luks mapping %s: %v", path, err))
}
if isLuksMapping {
glog.V(4).Infof("luksClose ", mappingName)
glog.V(4).Infof("luksClose %s", mappingName)
if err := luksClose(mappingName); err != nil {
return status.Error(codes.Internal, fmt.Sprintf("closeMountSources failed to close luks mount %s: %v", path, err))
}
Expand Down

0 comments on commit 258a04f

Please sign in to comment.