Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
05759a90
Commit
05759a90
authored
Nov 13, 2018
by
Deep Debroy
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Handle validation of drivers in Spec and Status
Signed-off-by:
Deep Debroy
<
ddebroy@docker.com
>
parent
af73d7bd
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
265 additions
and
63 deletions
+265
-63
nodeinfomanager.go
pkg/volume/csi/nodeinfomanager/nodeinfomanager.go
+33
-17
nodeinfomanager_test.go
pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go
+232
-46
No files found.
pkg/volume/csi/nodeinfomanager/nodeinfomanager.go
View file @
05759a90
...
@@ -387,10 +387,6 @@ func (nim *nodeInfoManager) CreateCSINodeInfo() (*csiv1alpha1.CSINodeInfo, error
...
@@ -387,10 +387,6 @@ func (nim *nodeInfoManager) CreateCSINodeInfo() (*csiv1alpha1.CSINodeInfo, error
},
},
}
}
err
=
validateCSINodeInfo
(
nodeInfo
)
if
err
!=
nil
{
return
err
}
return
csiKubeClient
.
CsiV1alpha1
()
.
CSINodeInfos
()
.
Create
(
nodeInfo
)
return
csiKubeClient
.
CsiV1alpha1
()
.
CSINodeInfos
()
.
Create
(
nodeInfo
)
}
}
...
@@ -503,7 +499,10 @@ func (nim *nodeInfoManager) uninstallDriverFromCSINodeInfo(csiDriverName string)
...
@@ -503,7 +499,10 @@ func (nim *nodeInfoManager) uninstallDriverFromCSINodeInfo(csiDriverName string)
return
nil
return
nil
}
}
// TODO (verult) make sure CSINodeInfo has validation logic to prevent duplicate driver names
err
=
validateCSINodeInfo
(
nodeInfo
)
if
err
!=
nil
{
return
err
}
_
,
updateErr
:=
nodeInfoClient
.
Update
(
nodeInfo
)
_
,
updateErr
:=
nodeInfoClient
.
Update
(
nodeInfo
)
return
updateErr
// do not wrap error
return
updateErr
// do not wrap error
...
@@ -568,29 +567,46 @@ func removeMaxAttachLimit(driverName string) nodeUpdateFunc {
...
@@ -568,29 +567,46 @@ func removeMaxAttachLimit(driverName string) nodeUpdateFunc {
}
}
// validateCSINodeInfo ensures members of CSINodeInfo object satisfies map and set semantics.
// validateCSINodeInfo ensures members of CSINodeInfo object satisfies map and set semantics.
// Before calling CSINodeInfoInterface.Create() or CSINodeInfoInterface.Update()
// Before calling CSINodeInfoInterface.Update(), validateCSINodeInfo() should be invoked to
// validateCSINodeInfo() should be invoked to make sure the CSINodeInfo is compliant
// make sure the CSINodeInfo is compliant
// TODO: move this logic to an external webhook
func
validateCSINodeInfo
(
nodeInfo
*
csiv1alpha1
.
CSINodeInfo
)
error
{
func
validateCSINodeInfo
(
nodeInfo
*
csiv1alpha1
.
CSINodeInfo
)
error
{
if
len
(
nodeInfo
.
CSI
Drivers
)
<
1
{
if
len
(
nodeInfo
.
Status
.
Drivers
)
<
1
{
return
fmt
.
Errorf
(
"at least one
CSI Driver entry is required
"
)
return
fmt
.
Errorf
(
"at least one
Driver entry is required in driver statuses
"
)
}
}
// check for duplicate entries for the same driver
if
len
(
nodeInfo
.
Spec
.
Drivers
)
<
1
{
return
fmt
.
Errorf
(
"at least one Driver entry is required in driver specs"
)
}
if
len
(
nodeInfo
.
Status
.
Drivers
)
!=
len
(
nodeInfo
.
Spec
.
Drivers
)
{
return
fmt
.
Errorf
(
""
)
}
// check for duplicate entries for the same driver in statuses
var
errors
[]
string
var
errors
[]
string
driverNames
:=
make
(
sets
.
String
)
driverNames
InStatuses
:=
make
(
sets
.
String
)
for
_
,
driverInfo
:=
range
nodeInfo
.
CSI
Drivers
{
for
_
,
driverInfo
:=
range
nodeInfo
.
Status
.
Drivers
{
if
driverNames
.
Has
(
driverInfo
.
Driver
)
{
if
driverNames
InStatuses
.
Has
(
driverInfo
.
Name
)
{
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"duplicate entries found for driver
%s"
,
driverNames
))
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"duplicate entries found for driver
: %s in driver statuses"
,
driverInfo
.
Name
))
}
}
driverNames
.
Insert
(
driverInfo
.
Driver
)
driverNamesInStatuses
.
Insert
(
driverInfo
.
Name
)
}
// check for duplicate entries for the same driver in specs
driverNamesInSpecs
:=
make
(
sets
.
String
)
for
_
,
driverInfo
:=
range
nodeInfo
.
Spec
.
Drivers
{
if
driverNamesInSpecs
.
Has
(
driverInfo
.
Name
)
{
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"duplicate entries found for driver: %s in driver specs"
,
driverInfo
.
Name
))
}
driverNamesInSpecs
.
Insert
(
driverInfo
.
Name
)
topoKeys
:=
make
(
sets
.
String
)
topoKeys
:=
make
(
sets
.
String
)
for
_
,
key
:=
range
driverInfo
.
TopologyKeys
{
for
_
,
key
:=
range
driverInfo
.
TopologyKeys
{
if
topoKeys
.
Has
(
key
)
{
if
topoKeys
.
Has
(
key
)
{
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"duplicate topology keys %s found for driver %s
"
,
key
,
driverInfo
.
Driver
))
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"duplicate topology keys %s found for driver %s
in driver specs"
,
key
,
driverInfo
.
Name
))
}
}
topoKeys
.
Insert
(
key
)
topoKeys
.
Insert
(
key
)
}
}
}
}
// check all entries in specs and status match
if
!
driverNamesInSpecs
.
Equal
(
driverNamesInStatuses
)
{
errors
=
append
(
errors
,
fmt
.
Sprintf
(
"list of drivers in specs: %v does not match list of drivers in statuses: %v"
,
driverNamesInSpecs
.
List
(),
driverNamesInStatuses
.
List
()))
}
if
len
(
errors
)
==
0
{
if
len
(
errors
)
==
0
{
return
nil
return
nil
}
}
...
...
pkg/volume/csi/nodeinfomanager/nodeinfomanager_test.go
View file @
05759a90
...
@@ -644,85 +644,271 @@ func TestValidateCSINodeInfo(t *testing.T) {
...
@@ -644,85 +644,271 @@ func TestValidateCSINodeInfo(t *testing.T) {
expectErr
bool
expectErr
bool
}{
}{
{
{
name
:
"multiple drivers with
same ids and different topology key
s"
,
name
:
"multiple drivers with
different node IDs, topology keys and statu
s"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
CSIDrivers
:
[]
csiv1alpha1
.
CSIDriverInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
Driver
:
"driver1"
,
{
NodeID
:
"node1"
,
Name
:
"driver1"
,
TopologyKeys
:
[]
string
{
"key1, key2"
},
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1, key2"
},
},
{
Name
:
"driverB"
,
NodeID
:
"nodeA"
,
TopologyKeys
:
[]
string
{
"keyA"
,
"keyB"
},
},
},
},
{
},
Driver
:
"driverB"
,
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
NodeID
:
"nodeA"
,
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
TopologyKeys
:
[]
string
{
"keyA"
,
"keyB"
},
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"in-tree"
,
},
{
Name
:
"driverB"
,
Available
:
false
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
},
},
},
expectErr
:
false
,
expectErr
:
false
,
},
},
{
{
name
:
"multiple drivers with same
ids and similar topology key
s"
,
name
:
"multiple drivers with same
node IDs, topology keys and statu
s"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
CSIDrivers
:
[]
csiv1alpha1
.
CSIDriverInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
Driver
:
"driver1"
,
{
NodeID
:
"node1"
,
Name
:
"driver1"
,
TopologyKeys
:
[]
string
{
"key1"
},
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
{
Name
:
"driver2"
,
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
},
},
{
},
Driver
:
"driver2"
,
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
NodeID
:
"node1"
,
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
TopologyKeys
:
[]
string
{
"key1"
},
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
{
Name
:
"driver2"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
},
},
},
expectErr
:
false
,
expectErr
:
false
,
},
},
{
{
name
:
"duplicate drivers"
,
name
:
"duplicate drivers in driver specs"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
{
Name
:
"driver1"
,
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
,
"key2"
},
},
{
Name
:
"driver1"
,
NodeID
:
"nodeX"
,
TopologyKeys
:
[]
string
{
"keyA"
,
"keyB"
},
},
},
},
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
expectErr
:
true
,
},
{
name
:
"duplicate drivers in driver statuses"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
{
Name
:
"driver1"
,
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
,
"key2"
},
},
},
},
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"in-tree"
,
},
{
Name
:
"driver1"
,
Available
:
false
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
expectErr
:
true
,
},
{
name
:
"single driver with duplicate topology keys in driver specs"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
{
Name
:
"driver1"
,
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
,
"key1"
},
},
},
},
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
expectErr
:
true
,
},
{
name
:
"multiple drivers with one set of duplicate topology keys in driver specs"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
CSIDrivers
:
[]
csiv1alpha1
.
CSIDriverInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
Driver
:
"driver1"
,
{
NodeID
:
"node1"
,
Name
:
"driver1"
,
TopologyKeys
:
[]
string
{
"key1"
,
"key2"
},
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
{
Name
:
"driver2"
,
NodeID
:
"nodeX"
,
TopologyKeys
:
[]
string
{
"keyA"
,
"keyA"
},
},
},
},
{
},
Driver
:
"driver1"
,
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
NodeID
:
"nodeX"
,
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
TopologyKeys
:
[]
string
{
"keyA"
,
"keyB"
},
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
{
Name
:
"driver2"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
},
},
},
expectErr
:
true
,
expectErr
:
true
,
},
},
{
{
name
:
"
single driver with duplicate topology keys
"
,
name
:
"
mismatch between drivers in specs and status (null intersection)
"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
CSIDrivers
:
[]
csiv1alpha1
.
CSIDriverInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
Driver
:
"driver1"
,
{
NodeID
:
"node1"
,
Name
:
"driver1"
,
TopologyKeys
:
[]
string
{
"key1"
,
"key1"
},
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
{
Name
:
"driver2"
,
NodeID
:
"nodeX"
,
TopologyKeys
:
[]
string
{
"keyA"
,
"keyA"
},
},
},
},
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
{
Name
:
"driver3"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
},
},
},
expectErr
:
true
,
expectErr
:
true
,
},
},
{
{
name
:
"m
ultiple drivers with one set of duplicate topology keys
"
,
name
:
"m
ismatch between drivers in specs and status (specs superset of status)
"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
CSIDrivers
:
[]
csiv1alpha1
.
CSIDriverInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
Driver
:
"driver1"
,
{
NodeID
:
"node1"
,
Name
:
"driver1"
,
TopologyKeys
:
[]
string
{
"key1"
},
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
{
Name
:
"driver2"
,
NodeID
:
"nodeX"
,
TopologyKeys
:
[]
string
{
"keyA"
,
"keyA"
},
},
},
},
{
},
Driver
:
"driver2"
,
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
NodeID
:
"nodeX"
,
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
TopologyKeys
:
[]
string
{
"keyA"
,
"keyA"
},
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
expectErr
:
true
,
},
{
name
:
"mismatch between drivers in specs and status (specs subset of status)"
,
nodeInfo
:
&
csiv1alpha1
.
CSINodeInfo
{
Spec
:
csiv1alpha1
.
CSINodeInfoSpec
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoSpec
{
{
Name
:
"driver1"
,
NodeID
:
"node1"
,
TopologyKeys
:
[]
string
{
"key1"
},
},
},
},
Status
:
csiv1alpha1
.
CSINodeInfoStatus
{
Drivers
:
[]
csiv1alpha1
.
CSIDriverInfoStatus
{
{
Name
:
"driver1"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
{
Name
:
"driver2"
,
Available
:
true
,
VolumePluginMechanism
:
"csi"
,
},
},
},
},
},
},
},
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment