Handle the CSI driver in VolumeSnapshotContent does not match case

In VolumeSnapshotContent, if the CSI driver does not match the plugin's,
the controller should skip this content instead of always processing it.
This PR also add a few tests related to snapshot and content static
binding.

During binding, if content specify its bound snapshot uid and it
does not match the snapshot's uid, the content object and also the
physical snapshot will be deleted. In this case, the controller will
treat the content as an orphan content because its snapshot object does
not exist (deleted) any more.
This commit is contained in:
Jing Xu
2018-09-20 15:21:18 -07:00
parent 5ed076f3db
commit c401b2331c
5 changed files with 151 additions and 59 deletions

View File

@@ -271,20 +271,12 @@ func (ctrl *csiSnapshotController) contentWorker() {
return false
}
content, err := ctrl.contentLister.Get(name)
// The content still exists in informer cache, the event must have
// been add/update/sync
if err == nil {
// Skip update if content is for another CSI driver
snapshotClassName := content.Spec.VolumeSnapshotClassName
if snapshotClassName != nil {
if snapshotClass, err := ctrl.classLister.Get(*snapshotClassName); err == nil {
if snapshotClass.Snapshotter != ctrl.snapshotterName {
return false
}
}
if ctrl.isDriverMatch(content) {
ctrl.updateContent(content)
}
// The content still exists in informer cache, the event must have
// been add/update/sync
ctrl.updateContent(content)
return false
}
if !errors.IsNotFound(err) {
@@ -322,6 +314,27 @@ func (ctrl *csiSnapshotController) contentWorker() {
}
}
// verify whether the driver specified in VolumeSnapshotContent matches the controller's driver name
func (ctrl *csiSnapshotController) isDriverMatch(content *crdv1.VolumeSnapshotContent) bool {
if content.Spec.VolumeSnapshotSource.CSI == nil {
// Skip this snapshot content if it not a CSI snapshot
return false
}
if content.Spec.VolumeSnapshotSource.CSI.Driver != ctrl.snapshotterName {
// Skip this snapshot content if the driver does not match
return false
}
snapshotClassName := content.Spec.VolumeSnapshotClassName
if snapshotClassName != nil {
if snapshotClass, err := ctrl.classLister.Get(*snapshotClassName); err == nil {
if snapshotClass.Snapshotter != ctrl.snapshotterName {
return false
}
}
}
return true
}
// checkAndUpdateSnapshotClass gets the VolumeSnapshotClass from VolumeSnapshot. If it is not set,
// gets it from default VolumeSnapshotClass and sets it. It also detects if snapshotter in the
// VolumeSnapshotClass is the same as the snapshotter in external controller.