From 1c61d6a7affe7fe8cbc2a2c90976d3e1bdc37ffb Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Fri, 31 Jan 2020 19:07:59 +0100 Subject: [PATCH 1/2] Removed dependency on node annotation in favor of CSINode resource --- pkg/controller/csi_handler.go | 15 ++---- pkg/controller/csi_handler_test.go | 84 +++++++++++------------------- pkg/controller/util.go | 24 +-------- pkg/controller/util_test.go | 67 +----------------------- 4 files changed, 39 insertions(+), 151 deletions(-) diff --git a/pkg/controller/csi_handler.go b/pkg/controller/csi_handler.go index 2fc88d5d84..08ba1c2615 100644 --- a/pkg/controller/csi_handler.go +++ b/pkg/controller/csi_handler.go @@ -692,19 +692,14 @@ func (h *csiHandler) getNodeID(driver string, nodeName string, va *storage.Volum klog.V(4).Infof("Found NodeID %s in CSINode %s", nodeID, nodeName) return nodeID, nil } - klog.V(4).Infof("CSINode %s does not contain driver %s", nodeName, driver) // CSINode exists, but does not have the requested driver. - // Fall through to Node annotation. - } else { - // Can't get CSINode, fall through to Node annotation. - klog.V(4).Infof("Can't get CSINode %s: %s", nodeName, err) + errMessage := fmt.Sprintf("CSINode %s does not contain driver %s", nodeName, driver) + klog.V(4).Info(errMessage) + return "", errors.New(errMessage) } - // Check Node annotation. - node, err := h.nodeLister.Get(nodeName) - if err == nil { - return GetNodeIDFromNode(driver, node) - } + // Can't get CSINode, check Volume Attachment. + klog.V(4).Infof("Can't get CSINode %s: %s", nodeName, err) // Check VolumeAttachment annotation as the last resort if caller wants so (i.e. has provided one). if va == nil { diff --git a/pkg/controller/csi_handler_test.go b/pkg/controller/csi_handler_test.go index 8f2d06ee70..3e2c44cec1 100644 --- a/pkg/controller/csi_handler_test.go +++ b/pkg/controller/csi_handler_test.go @@ -194,19 +194,10 @@ func node() *v1.Node { return &v1.Node{ ObjectMeta: metav1.ObjectMeta{ Name: testNodeName, - Annotations: map[string]string{ - "csi.volume.kubernetes.io/nodeid": fmt.Sprintf("{ %q: %q }", testAttacherName, testNodeID), - }, }, } } -func nodeWithoutAnnotations() *v1.Node { - n := node() - n.Annotations = nil - return n -} - func csiNode() *storage.CSINode { return &storage.CSINode{ ObjectMeta: metav1.ObjectMeta{ @@ -295,7 +286,7 @@ func TestCSIHandler(t *testing.T) { // { name: "VolumeAttachment added -> successful attachment", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -312,7 +303,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec -> successful attachment", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{node(), csiNode()}, addedVA: vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -328,7 +319,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "readOnly VolumeAttachment added -> successful attachment", - initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node()}, + initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -345,7 +336,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "readOnly VolumeAttachment with InlineVolumeSpec -> successful attachment", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{node(), csiNode()}, addedVA: vaInlineSpecReadOnly(vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */))), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -361,7 +352,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment updated -> successful attachment", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -378,7 +369,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec updated -> successful attachment", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{node(), csiNode()}, updatedVA: vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */)), expectedActions: []core.Action{ // Finalizer is saved first @@ -395,7 +386,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with attributes -> successful attachment", - initialObjects: []runtime.Object{pvWithAttributes(pvWithFinalizer(), map[string]string{"foo": "bar"}), node()}, + initialObjects: []runtime.Object{pvWithAttributes(pvWithFinalizer(), map[string]string{"foo": "bar"}), node(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -412,7 +403,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and attributes -> successful attachment", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{node(), csiNode()}, updatedVA: vaInlineSpecWithAttributes(vaWithInlineSpec(va(false, "", nil)) /*va*/, map[string]string{"foo": "bar"} /*attributes*/), expectedActions: []core.Action{ // Finalizer is saved first @@ -429,7 +420,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with secrets -> successful attachment", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), node(), secret()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), node(), secret(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -447,7 +438,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and secrets -> successful attachment", - initialObjects: []runtime.Object{node(), secret()}, + initialObjects: []runtime.Object{node(), secret(), csiNode()}, updatedVA: vaInlineSpecWithSecret(vaWithInlineSpec(va(false, "", nil)) /*va*/, "secret" /*secret*/), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -465,7 +456,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with empty secrets -> successful attachment", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), node(), emptySecret()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), node(), emptySecret(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -483,7 +474,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and empty secrets -> successful attachment", - initialObjects: []runtime.Object{node(), emptySecret()}, + initialObjects: []runtime.Object{node(), emptySecret(), csiNode()}, updatedVA: vaInlineSpecWithSecret(vaWithInlineSpec(va(false, "", nil)) /*va*/, "emptySecret" /*secret*/), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -513,7 +504,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment updated -> PV finalizer is added", - initialObjects: []runtime.Object{pv(), node()}, + initialObjects: []runtime.Object{pv(), node(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // PV Finalizer after VA @@ -534,7 +525,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "error saving PV finalizer -> controller retries", - initialObjects: []runtime.Object{pv(), node()}, + initialObjects: []runtime.Object{pv(), node(), csiNode()}, updatedVA: va(false, "", nil), reactors: []reaction{ { @@ -604,7 +595,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment added -> successful attachment incl. metadata", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -695,12 +686,12 @@ func TestCSIHandler(t *testing.T) { expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, types.MergePatchType, patch(va(false, fin, ann), vaWithAttachError(va(false, fin, ann), - "node \"node1\" not found"))), + "csinode.storage.k8s.io \"node1\" not found"))), }, }, { name: "failed write with VA finializers -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false, "", nil), reactors: []reaction{ { @@ -744,7 +735,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "failed write with attached=true -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false, "", nil), reactors: []reaction{ { @@ -788,7 +779,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI attach fails -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -815,7 +806,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI attach times out -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -832,28 +823,28 @@ func TestCSIHandler(t *testing.T) { }, }, { - name: "Node without annotations -> error", - initialObjects: []runtime.Object{pvWithFinalizer(), nodeWithoutAnnotations()}, + name: "Node without CSINode -> error", + initialObjects: []runtime.Object{pvWithFinalizer(), node()}, addedVA: va(false, fin, ann), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, types.MergePatchType, patch(va(false /*attached*/, fin, ann), - vaWithAttachError(va(false, fin, ann), "node \"node1\" has no NodeID annotation"))), + vaWithAttachError(va(false, fin, ann), "csinode.storage.k8s.io \"node1\" not found"))), }, }, { - name: "CSINode exists without the driver, Node without annotations -> error", - initialObjects: []runtime.Object{pvWithFinalizer(), nodeWithoutAnnotations(), csiNodeEmpty()}, + name: "CSINode exists without the driver -> error", + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNodeEmpty()}, addedVA: va(false, fin, ann), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, types.MergePatchType, patch(va(false /*attached*/, fin, ann), - vaWithAttachError(va(false, fin, ann), "node \"node1\" has no NodeID annotation"))), + vaWithAttachError(va(false, fin, ann), "CSINode node1 does not contain driver csi/test"))), }, }, { name: "CSINode exists with the driver, Node without annotations -> success", - initialObjects: []runtime.Object{pvWithFinalizer(), nodeWithoutAnnotations(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -870,7 +861,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with GCEPersistentDiskVolumeSource -> successful attachment", - initialObjects: []runtime.Object{gcePDPVWithFinalizer(), node()}, + initialObjects: []runtime.Object{gcePDPVWithFinalizer(), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -1095,7 +1086,7 @@ func TestCSIHandler(t *testing.T) { expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, types.MergePatchType, patch(deleted(va(true, fin, nil)), - deleted(vaWithDetachError(va(true, fin, nil), "node \"node1\" not found")))), + deleted(vaWithDetachError(va(true, fin, nil), "csinode.storage.k8s.io \"node1\" not found")))), }, }, { @@ -1112,19 +1103,6 @@ func TestCSIHandler(t *testing.T) { {"detach", testVolumeHandle, "annotatedNodeID", noAttrs, noSecrets, readWrite, success, detached, noMetadata, 0}, }, }, - { - name: "VolumeAttachment marked for deletion -> node is preferred over VA annotation for NodeID", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, - addedVA: deleted(va(true, fin, map[string]string{vaNodeIDAnnotation: "annotatedNodeID"})), - expectedActions: []core.Action{ - core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, - types.MergePatchType, patch(deleted(va(true, fin, map[string]string{vaNodeIDAnnotation: "annotatedNodeID"})), - deleted(va(false /*attached*/, "", map[string]string{vaNodeIDAnnotation: "annotatedNodeID"})))), - }, - expectedCSICalls: []csiCall{ - {"detach", testVolumeHandle, testNodeID, noAttrs, noSecrets, readWrite, success, detached, noMetadata, 0}, - }, - }, { name: "failed write with attached=false -> controller retries", initialObjects: []runtime.Object{pvWithFinalizer(), node()}, @@ -1354,7 +1332,7 @@ func TestCSIHandlerReadOnly(t *testing.T) { // { name: "read-write PV -> attached as read-write", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -1371,7 +1349,7 @@ func TestCSIHandlerReadOnly(t *testing.T) { }, { name: "read-only PV -> attached as read-write", - initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node()}, + initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first diff --git a/pkg/controller/util.go b/pkg/controller/util.go index e1e86f429d..f65420d93c 100644 --- a/pkg/controller/util.go +++ b/pkg/controller/util.go @@ -23,8 +23,8 @@ import ( "regexp" "github.com/container-storage-interface/spec/lib/go/csi" - "github.com/evanphx/json-patch" - "k8s.io/api/core/v1" + jsonpatch "github.com/evanphx/json-patch" + v1 "k8s.io/api/core/v1" storage "k8s.io/api/storage/v1beta1" "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" @@ -93,7 +93,6 @@ func markAsDetached(client kubernetes.Interface, va *storage.VolumeAttachment) ( const ( defaultFSType = "ext4" - nodeIDAnnotation = "csi.volume.kubernetes.io/nodeid" csiVolAttribsAnnotationKey = "csi.volume.kubernetes.io/volume-attributes" vaNodeIDAnnotation = "csi.alpha.kubernetes.io/node-id" ) @@ -114,25 +113,6 @@ func GetFinalizerName(driver string) string { return "external-attacher/" + SanitizeDriverName(driver) } -// GetNodeIDFromNode returns nodeID string from node annotations. -func GetNodeIDFromNode(driver string, node *v1.Node) (string, error) { - nodeIDJSON, ok := node.Annotations[nodeIDAnnotation] - if !ok { - return "", fmt.Errorf("node %q has no NodeID annotation", node.Name) - } - - var nodeIDs map[string]string - if err := json.Unmarshal([]byte(nodeIDJSON), &nodeIDs); err != nil { - return "", fmt.Errorf("cannot parse NodeID annotation on node %q: %s", node.Name, err) - } - nodeID, ok := nodeIDs[driver] - if !ok { - return "", fmt.Errorf("cannot find NodeID for driver %q for node %q", driver, node.Name) - } - - return nodeID, nil -} - // GetNodeIDFromCSINode returns nodeID from CSIDriverInfoSpec func GetNodeIDFromCSINode(driver string, csiNode *storage.CSINode) (string, bool) { for _, d := range csiNode.Spec.Drivers { diff --git a/pkg/controller/util_test.go b/pkg/controller/util_test.go index f2b6a9bb4d..321c836f80 100644 --- a/pkg/controller/util_test.go +++ b/pkg/controller/util_test.go @@ -20,78 +20,13 @@ import ( "testing" "github.com/container-storage-interface/spec/lib/go/csi" - "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "k8s.io/api/core/v1" ) const ( driverName = "foo/bar" ) -func TestGetNodeIDFromNode(t *testing.T) { - tests := []struct { - name string - annotations map[string]string - expectedID string - expectError bool - }{ - { - name: "single key", - annotations: map[string]string{"csi.volume.kubernetes.io/nodeid": "{\"foo/bar\": \"MyNodeID\"}"}, - expectedID: "MyNodeID", - expectError: false, - }, - { - name: "multiple keys", - annotations: map[string]string{ - "csi.volume.kubernetes.io/nodeid": "{\"foo/bar\": \"MyNodeID\", \"-foo/bar\": \"MyNodeID2\", \"foo/bar-\": \"MyNodeID3\"}", - }, - expectedID: "MyNodeID", - expectError: false, - }, - { - name: "no annotations", - annotations: nil, - expectedID: "", - expectError: true, - }, - { - name: "invalid JSON", - annotations: map[string]string{"csi.volume.kubernetes.io/nodeid": "\"foo/bar\": \"MyNodeID\""}, - expectedID: "", - expectError: true, - }, - { - name: "annotations for another driver", - annotations: map[string]string{ - "csi.volume.kubernetes.io/nodeid": "{\"-foo/bar\": \"MyNodeID2\", \"foo/bar-\": \"MyNodeID3\"}", - }, - expectedID: "", - expectError: true, - }, - } - - for _, test := range tests { - node := &v1.Node{ - ObjectMeta: metav1.ObjectMeta{ - Name: "abc", - Annotations: test.annotations, - }, - } - nodeID, err := GetNodeIDFromNode(driverName, node) - - if err == nil && test.expectError { - t.Errorf("test %s: expected error, got none", test.name) - } - if err != nil && !test.expectError { - t.Errorf("test %s: got error: %s", test.name, err) - } - if !test.expectError && nodeID != test.expectedID { - t.Errorf("test %s: unexpected NodeID: %s", test.name, nodeID) - } - } -} - func createBlockCapability(mode csi.VolumeCapability_AccessMode_Mode) *csi.VolumeCapability { return &csi.VolumeCapability{ AccessType: &csi.VolumeCapability_Block{ From 8847215132c6a989ecef1e00a9de0886c6223b78 Mon Sep 17 00:00:00 2001 From: Danil-Grigorev Date: Mon, 3 Feb 2020 13:21:12 +0100 Subject: [PATCH 2/2] Removed RBAC for Nodes, updated tests --- cmd/csi-attacher/main.go | 3 +- deploy/kubernetes/rbac.yaml | 5 +- pkg/controller/csi_handler.go | 7 +- pkg/controller/csi_handler_test.go | 116 ++++++++++++++++------------- 4 files changed, 70 insertions(+), 61 deletions(-) diff --git a/cmd/csi-attacher/main.go b/cmd/csi-attacher/main.go index 1a5c69c3e6..44c22e6f6b 100644 --- a/cmd/csi-attacher/main.go +++ b/cmd/csi-attacher/main.go @@ -154,12 +154,11 @@ func main() { } if supportsAttach { pvLister := factory.Core().V1().PersistentVolumes().Lister() - nodeLister := factory.Core().V1().Nodes().Lister() vaLister := factory.Storage().V1beta1().VolumeAttachments().Lister() csiNodeLister := factory.Storage().V1beta1().CSINodes().Lister() volAttacher := attacher.NewAttacher(csiConn) CSIVolumeLister := attacher.NewVolumeLister(csiConn) - handler = controller.NewCSIHandler(clientset, csiAttacher, volAttacher, CSIVolumeLister, pvLister, nodeLister, csiNodeLister, vaLister, timeout, supportsReadOnly, csitrans.New()) + handler = controller.NewCSIHandler(clientset, csiAttacher, volAttacher, CSIVolumeLister, pvLister, csiNodeLister, vaLister, timeout, supportsReadOnly, csitrans.New()) klog.V(2).Infof("CSI driver supports ControllerPublishUnpublish, using real CSI handler") } else { handler = controller.NewTrivialHandler(clientset) diff --git a/deploy/kubernetes/rbac.yaml b/deploy/kubernetes/rbac.yaml index f5d97a1173..93ce319629 100644 --- a/deploy/kubernetes/rbac.yaml +++ b/deploy/kubernetes/rbac.yaml @@ -16,7 +16,7 @@ metadata: namespace: default --- -# Attacher must be able to work with PVs, nodes and VolumeAttachments +# Attacher must be able to work with PVs, CSINodes and VolumeAttachments kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: @@ -25,9 +25,6 @@ rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "update", "patch"] - - apiGroups: [""] - resources: ["nodes"] - verbs: ["get", "list", "watch"] - apiGroups: ["storage.k8s.io"] resources: ["csinodes"] verbs: ["get", "list", "watch"] diff --git a/pkg/controller/csi_handler.go b/pkg/controller/csi_handler.go index 08ba1c2615..c6c3a259f2 100644 --- a/pkg/controller/csi_handler.go +++ b/pkg/controller/csi_handler.go @@ -62,7 +62,6 @@ type csiHandler struct { attacher attacher.Attacher CSIVolumeLister VolumeLister pvLister corelisters.PersistentVolumeLister - nodeLister corelisters.NodeLister csiNodeLister storagelisters.CSINodeLister vaLister storagelisters.VolumeAttachmentLister vaQueue, pvQueue workqueue.RateLimitingInterface @@ -82,7 +81,6 @@ func NewCSIHandler( attacher attacher.Attacher, CSIVolumeLister VolumeLister, pvLister corelisters.PersistentVolumeLister, - nodeLister corelisters.NodeLister, csiNodeLister storagelisters.CSINodeLister, vaLister storagelisters.VolumeAttachmentLister, timeout *time.Duration, @@ -95,7 +93,6 @@ func NewCSIHandler( attacher: attacher, CSIVolumeLister: CSIVolumeLister, pvLister: pvLister, - nodeLister: nodeLister, csiNodeLister: csiNodeLister, vaLister: vaLister, timeout: *timeout, @@ -682,7 +679,7 @@ func (h *csiHandler) getCredentialsFromPV(csiSource *v1.CSIPersistentVolumeSourc return credentials, nil } -// getNodeID finds node ID from Node API object. If caller wants, it can find +// getNodeID finds node ID from CSINode API object. If caller wants, it can find // node ID stored in VolumeAttachment annotation. func (h *csiHandler) getNodeID(driver string, nodeName string, va *storage.VolumeAttachment) (string, error) { // Try to find CSINode first. @@ -709,7 +706,7 @@ func (h *csiHandler) getNodeID(driver string, nodeName string, va *storage.Volum return nodeID, nil } - // return nodeLister.Get error + // return csiNodeLister.Get error return "", err } diff --git a/pkg/controller/csi_handler_test.go b/pkg/controller/csi_handler_test.go index 3e2c44cec1..d60f9262e8 100644 --- a/pkg/controller/csi_handler_test.go +++ b/pkg/controller/csi_handler_test.go @@ -57,7 +57,6 @@ func csiHandlerFactory(client kubernetes.Interface, informerFactory informers.Sh csi, lister, informerFactory.Core().V1().PersistentVolumes().Lister(), - informerFactory.Core().V1().Nodes().Lister(), informerFactory.Storage().V1beta1().CSINodes().Lister(), informerFactory.Storage().V1beta1().VolumeAttachments().Lister(), &timeout, @@ -73,7 +72,6 @@ func csiHandlerFactoryNoReadOnly(client kubernetes.Interface, informerFactory in csi, lister, informerFactory.Core().V1().PersistentVolumes().Lister(), - informerFactory.Core().V1().Nodes().Lister(), informerFactory.Storage().V1beta1().CSINodes().Lister(), informerFactory.Storage().V1beta1().VolumeAttachments().Lister(), &timeout, @@ -198,6 +196,14 @@ func node() *v1.Node { } } +func nodeWithAnnotations() *v1.Node { + node := node() + node.Annotations = map[string]string{ + "csi.volume.kubernetes.io/nodeid": fmt.Sprintf("{ %q: %q }", testAttacherName, testNodeID), + } + return node +} + func csiNode() *storage.CSINode { return &storage.CSINode{ ObjectMeta: metav1.ObjectMeta{ @@ -286,7 +292,7 @@ func TestCSIHandler(t *testing.T) { // { name: "VolumeAttachment added -> successful attachment", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -303,7 +309,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec -> successful attachment", - initialObjects: []runtime.Object{node(), csiNode()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -319,7 +325,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "readOnly VolumeAttachment added -> successful attachment", - initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node(), csiNode()}, + initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -336,7 +342,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "readOnly VolumeAttachment with InlineVolumeSpec -> successful attachment", - initialObjects: []runtime.Object{node(), csiNode()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: vaInlineSpecReadOnly(vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */))), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -352,7 +358,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment updated -> successful attachment", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -369,7 +375,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec updated -> successful attachment", - initialObjects: []runtime.Object{node(), csiNode()}, + initialObjects: []runtime.Object{csiNode()}, updatedVA: vaWithInlineSpec(va(false /*attached*/, "" /*finalizer*/, nil /* annotations */)), expectedActions: []core.Action{ // Finalizer is saved first @@ -386,7 +392,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with attributes -> successful attachment", - initialObjects: []runtime.Object{pvWithAttributes(pvWithFinalizer(), map[string]string{"foo": "bar"}), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithAttributes(pvWithFinalizer(), map[string]string{"foo": "bar"}), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -403,7 +409,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and attributes -> successful attachment", - initialObjects: []runtime.Object{node(), csiNode()}, + initialObjects: []runtime.Object{csiNode()}, updatedVA: vaInlineSpecWithAttributes(vaWithInlineSpec(va(false, "", nil)) /*va*/, map[string]string{"foo": "bar"} /*attributes*/), expectedActions: []core.Action{ // Finalizer is saved first @@ -420,7 +426,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with secrets -> successful attachment", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), node(), secret(), csiNode()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), secret(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -438,7 +444,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and secrets -> successful attachment", - initialObjects: []runtime.Object{node(), secret(), csiNode()}, + initialObjects: []runtime.Object{secret(), csiNode()}, updatedVA: vaInlineSpecWithSecret(vaWithInlineSpec(va(false, "", nil)) /*va*/, "secret" /*secret*/), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -456,7 +462,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with empty secrets -> successful attachment", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), node(), emptySecret(), csiNode()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), emptySecret(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -474,7 +480,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec and empty secrets -> successful attachment", - initialObjects: []runtime.Object{node(), emptySecret(), csiNode()}, + initialObjects: []runtime.Object{emptySecret(), csiNode()}, updatedVA: vaInlineSpecWithSecret(vaWithInlineSpec(va(false, "", nil)) /*va*/, "emptySecret" /*secret*/), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -492,7 +498,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with missing secrets -> error", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "unknownSecret"), node()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "unknownSecret"), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "unknownSecret"), @@ -504,7 +510,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment updated -> PV finalizer is added", - initialObjects: []runtime.Object{pv(), node(), csiNode()}, + initialObjects: []runtime.Object{pv(), csiNode()}, updatedVA: va(false, "", nil), expectedActions: []core.Action{ // PV Finalizer after VA @@ -525,7 +531,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "error saving PV finalizer -> controller retries", - initialObjects: []runtime.Object{pv(), node(), csiNode()}, + initialObjects: []runtime.Object{pv(), csiNode()}, updatedVA: va(false, "", nil), reactors: []reaction{ { @@ -577,14 +583,14 @@ func TestCSIHandler(t *testing.T) { }, { name: "already attached volume -> ignored", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, updatedVA: va(true, fin, ann), expectedActions: []core.Action{}, expectedCSICalls: []csiCall{}, }, { name: "PV with deletion timestamp -> ignored with error", - initialObjects: []runtime.Object{pvDeleted(pv()), node()}, + initialObjects: []runtime.Object{pvDeleted(pv()), csiNode()}, updatedVA: va(false, fin, ann), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -595,7 +601,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment added -> successful attachment incl. metadata", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -611,13 +617,13 @@ func TestCSIHandler(t *testing.T) { }, { name: "unknown driver -> ignored", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: vaWithInvalidDriver(va(false, fin, ann)), expectedActions: []core.Action{}, }, { name: "unknown PV -> error", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: va(false, fin, ann), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -627,7 +633,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "unknown PV -> error + error saving the error", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: va(false, fin, ann), reactors: []reaction{ { @@ -661,7 +667,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "neither PV nor InlineVolumeSpec reference-> error", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: vaWithNoPVReferenceNorInlineVolumeSpec(va(false, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -671,7 +677,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "both PV and InlineVolumeSpec reference-> error", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: vaAddInlineSpec(va(false, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -691,7 +697,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "failed write with VA finializers -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false, "", nil), reactors: []reaction{ { @@ -735,7 +741,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "failed write with attached=true -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false, "", nil), reactors: []reaction{ { @@ -779,7 +785,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI attach fails -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -806,7 +812,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI attach times out -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false, "", nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -832,9 +838,19 @@ func TestCSIHandler(t *testing.T) { vaWithAttachError(va(false, fin, ann), "csinode.storage.k8s.io \"node1\" not found"))), }, }, + { + name: "Node with annotations, CSINode is absent -> error", + initialObjects: []runtime.Object{pvWithFinalizer(), nodeWithAnnotations()}, + addedVA: va(false, fin, ann), + expectedActions: []core.Action{ + core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, + types.MergePatchType, patch(va(false /*attached*/, fin, ann), + vaWithAttachError(va(false, fin, ann), "csinode.storage.k8s.io \"node1\" not found"))), + }, + }, { name: "CSINode exists without the driver -> error", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNodeEmpty()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNodeEmpty()}, addedVA: va(false, fin, ann), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -844,7 +860,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSINode exists with the driver, Node without annotations -> success", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -861,7 +877,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with GCEPersistentDiskVolumeSource -> successful attachment", - initialObjects: []runtime.Object{gcePDPVWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{gcePDPVWithFinalizer(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil), expectedActions: []core.Action{ // Finalizer is saved first @@ -882,7 +898,7 @@ func TestCSIHandler(t *testing.T) { { name: "VolumeAttachment marked for deletion -> successful detach", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -895,7 +911,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with InlineVolumeSpec marked for deletion -> successful detach", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: deleted(vaWithInlineSpec(va(true, fin, ann))), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -908,7 +924,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "volume with secrets -> successful detach", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), node(), secret()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "secret"), secret()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -922,7 +938,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "volume attachment with InlineVolumeSpec and secrets -> successful detach", - initialObjects: []runtime.Object{node(), secret()}, + initialObjects: []runtime.Object{secret()}, addedVA: deleted(vaInlineSpecWithSecret(vaWithInlineSpec(va(true, fin, ann)), "secret")), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "secret"), @@ -936,7 +952,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "volume with empty secrets -> successful detach", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), node(), emptySecret()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "emptySecret"), emptySecret()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -950,7 +966,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "volume attachment with InlineVolumeSpec and empty secrets -> successful detach", - initialObjects: []runtime.Object{node(), emptySecret()}, + initialObjects: []runtime.Object{emptySecret()}, addedVA: deleted(vaInlineSpecWithSecret(vaWithInlineSpec(va(true, fin, ann)), "emptySecret")), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "emptySecret"), @@ -964,7 +980,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "volume with missing secrets -> error", - initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "unknownSecret"), node()}, + initialObjects: []runtime.Object{pvWithSecret(pvWithFinalizer(), "unknownSecret"), csiNode()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewGetAction(secretGroupResourceVersion, "default", "unknownSecret"), @@ -977,7 +993,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI detach fails with an error -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -994,7 +1010,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "CSI detach times out -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -1008,14 +1024,14 @@ func TestCSIHandler(t *testing.T) { }, { name: "already detached volume -> ignored", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, updatedVA: deleted(va(false, "", nil)), expectedActions: []core.Action{}, expectedCSICalls: []csiCall{}, }, { name: "detach unknown PV -> error", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: deleted(va(true, fin, ann)), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -1025,7 +1041,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "detach unknown PV -> error + error saving the error", - initialObjects: []runtime.Object{node()}, + initialObjects: []runtime.Object{csiNode()}, addedVA: deleted(va(true, fin, ann)), reactors: []reaction{ { @@ -1059,7 +1075,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "detach VA with neither PV nor InlineCSIVolumeSource reference-> error", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(vaWithNoPVReferenceNorInlineVolumeSpec(va(true, fin, ann))), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -1070,7 +1086,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "detach VA with both PV and InlineCSIVolumeSource reference-> error", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(vaAddInlineSpec(va(true, fin, ann))), expectedActions: []core.Action{ core.NewPatchAction(vaGroupResourceVersion, metav1.NamespaceNone, testPVName+"-"+testNodeName, @@ -1105,7 +1121,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "failed write with attached=false -> controller retries", - initialObjects: []runtime.Object{pvWithFinalizer(), node()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: deleted(va(false, fin, ann)), reactors: []reaction{ { @@ -1148,7 +1164,7 @@ func TestCSIHandler(t *testing.T) { }, { name: "VolumeAttachment with GCEPersistentDiskVolumeSource marked for deletion -> successful detach", - initialObjects: []runtime.Object{gcePDPVWithFinalizer(), node()}, + initialObjects: []runtime.Object{gcePDPVWithFinalizer(), csiNode()}, addedVA: deleted(va(true /*attached*/, fin /*finalizer*/, ann)), expectedActions: []core.Action{ // Finalizer is saved first @@ -1332,7 +1348,7 @@ func TestCSIHandlerReadOnly(t *testing.T) { // { name: "read-write PV -> attached as read-write", - initialObjects: []runtime.Object{pvWithFinalizer(), node(), csiNode()}, + initialObjects: []runtime.Object{pvWithFinalizer(), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first @@ -1349,7 +1365,7 @@ func TestCSIHandlerReadOnly(t *testing.T) { }, { name: "read-only PV -> attached as read-write", - initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), node(), csiNode()}, + initialObjects: []runtime.Object{pvReadOnly(pvWithFinalizer()), csiNode()}, addedVA: va(false /*attached*/, "" /*finalizer*/, nil /* annotations */), expectedActions: []core.Action{ // Finalizer is saved first