Skip to content

[WIP] Remove linode api token requirement from node-server #414

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

Closed
wants to merge 6 commits into from
Closed
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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ FROM alpine:3.20.3
LABEL maintainers="Linode"
LABEL description="Linode CSI Driver"

RUN apk add --no-cache e2fsprogs e2fsprogs-extra findmnt blkid cryptsetup
RUN apk add --no-cache e2fsprogs e2fsprogs-extra findmnt blkid cryptsetup lsblk
RUN apk add --no-cache xfsprogs=6.2.0-r2 xfsprogs-extra=6.2.0-r2 --repository=http://dl-cdn.alpinelinux.org/alpine/v3.18/main

COPY --from=builder /bin/linode-blockstorage-csi-driver /linode
Expand Down
1 change: 1 addition & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ WORKDIR /linode

RUN apk add \
blkid \
lsblk \
cryptsetup \
cryptsetup-libs \
cryptsetup-dev \
Expand Down
11 changes: 0 additions & 11 deletions deploy/kubernetes/base/ds-csi-linode-node.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,6 @@ spec:
env:
- name: CSI_ENDPOINT
value: unix:///csi/csi.sock
- name: LINODE_URL
value: https://api.linode.com/v4
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: LINODE_TOKEN
valueFrom:
secretKeyRef:
name: linode
key: token
imagePullPolicy: "Always"
securityContext:
# This container must run as privileged due to the requirement for bidirectional mount propagation
Expand Down
11 changes: 0 additions & 11 deletions helm-chart/csi-driver/templates/daemonset.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,6 @@ spec:
env:
- name: CSI_ENDPOINT
value: unix:///csi/csi.sock
- name: LINODE_URL
value: https://api.linode.com
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: LINODE_TOKEN
valueFrom:
secretKeyRef:
name: {{ if .Values.secretRef }}{{ .Values.secretRef.name | default "linode" }}{{ else }}"linode"{{ end }}
key: {{ if .Values.secretRef }}{{ .Values.secretRef.apiTokenRef | default "token" }}{{ else }}"token"{{ end }}
- name: ENABLE_METRICS
value: {{ .Values.enableMetrics | quote}}
- name: METRICS_PORT
Expand Down
27 changes: 23 additions & 4 deletions internal/driver/nodeserver.go
Copy link
Contributor

Choose a reason for hiding this comment

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

What are your thoughts on using this library instead of exec command?

https://github.com/jaypipes/ghw?tab=readme-ov-file#block-storage

Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
*/

import (
"encoding/json"
"errors"
"fmt"
"os/exec"
"strconv"
"sync"
"time"
Expand Down Expand Up @@ -50,6 +52,14 @@
csi.UnimplementedNodeServer
}

type BlockDevice struct {
Name string `json:"name"`
}

type LsblkOutput struct {
BlockDevices []BlockDevice `json:"blockdevices"`
}

var _ csi.NodeServer = &NodeServer{}

func NewNodeServer(ctx context.Context, linodeDriver *LinodeDriver, mounter *mountmanager.SafeFormatAndMount, deviceUtils devicemanager.DeviceUtils, client linodeclient.LinodeClient, metadata Metadata, encrypt Encryption, resize mountmanager.ResizeFSer) (*NodeServer, error) {
Expand Down Expand Up @@ -469,8 +479,12 @@
}, nil
}

func execRunner(name string, arg ...string) ([]byte, error) {
return exec.Command(name, arg...).CombinedOutput()
}

Comment on lines +482 to +485
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use the interfaces defined for exec calls here: https://github.com/linode/linode-blockstorage-csi-driver/blob/d43f82da3e16f6294f1b1cf32eaa3d621c53d044/pkg/mount-manager/safe_mounter.go

This would be helpful during mocking for unit testing

Could you also move the structs and execRunner() to either helper file OR somewhere in the pkg directory?

func (ns *NodeServer) NodeGetInfo(ctx context.Context, req *csi.NodeGetInfoRequest) (*csi.NodeGetInfoResponse, error) {
log, ctx := logger.GetLogger(ctx)

Check failure on line 487 in internal/driver/nodeserver.go

View workflow job for this annotation

GitHub Actions / ci

ineffectual assignment to ctx (ineffassign)

Check failure on line 487 in internal/driver/nodeserver.go

View workflow job for this annotation

GitHub Actions / ci

ineffectual assignment to ctx (ineffassign)
log, done := logger.WithMethod(log, "NodeGetInfo")
defer done()

Expand All @@ -484,13 +498,18 @@
// This is what the spec wants us to report: the actual number of volumes
// that can be attached, and not the theoretical maximum number of
// devices that can be attached.
log.V(4).Info("Listing instance disks", "nodeID", ns.metadata.ID)
disks, err := ns.client.ListInstanceDisks(ctx, ns.metadata.ID, nil)
log.V(4).Info("Listing attached block devices", "nodeID", ns.metadata.ID)

lsblkOutput, err := execRunner("lsblk", "-J", "--nodeps", "-e7")
if err != nil {
return &csi.NodeGetInfoResponse{}, errInternal("list instance disks: %v", err)
return &csi.NodeGetInfoResponse{}, errInternal("lsblk: %v", err)
}
var lsblkData LsblkOutput
if err := json.Unmarshal(lsblkOutput, &lsblkData); err != nil {
return &csi.NodeGetInfoResponse{}, errInternal("error unmarshaling lsblk json output: %s", err)
}
maxVolumes := maxVolumeAttachments(ns.metadata.Memory) - len(disks)

maxVolumes := maxVolumeAttachments(ns.metadata.Memory) - len(lsblkData.BlockDevices)
log.V(2).Info("functionStatusfully completed")
return &csi.NodeGetInfoResponse{
NodeId: strconv.Itoa(ns.metadata.ID),
Expand Down
10 changes: 0 additions & 10 deletions internal/driver/nodeserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -755,13 +755,6 @@ func TestNodeGetInfo(t *testing.T) {
},
},
},
expectLinodeClientCalls: func(m *mocks.MockLinodeClient) {
m.EXPECT().ListInstanceDisks(gomock.Any(), gomock.Any(), gomock.Any()).Return([]linodego.InstanceDisk{
{
ID: 1,
},
}, nil)
},
expectedError: nil,
},
}
Expand All @@ -771,9 +764,6 @@ func TestNodeGetInfo(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockClient := mocks.NewMockLinodeClient(ctrl)
if tt.expectLinodeClientCalls != nil {
tt.expectLinodeClientCalls(mockClient)
}
ns := &NodeServer{
driver: &LinodeDriver{},
client: mockClient,
Expand Down
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,12 @@ func handle(ctx context.Context) error {
log.V(4).Info("Driver vendor version", "version", vendorVersion)

cfg := loadConfig()

// Warn if LINODE_TOKEN is not set.
// Validation of LINODE_TOKEN being set is moved to the helm chart.
// ToDo: Decouple the node-server from the controller code.
if cfg.linodeToken == "" {
return errors.New("linode token required")
log.V(4).Info("LINODE_TOKEN is not set, this is OK for node-server")
}

linodeDriver := driver.GetLinodeDriver(ctx)
Expand Down
Loading