Skip to content

Commit

Permalink
Merge pull request kubernetes-csi#172 from xing-yang/binding_bug
Browse files Browse the repository at this point in the history
Verify PV/PVC binding and driver
  • Loading branch information
k8s-ci-robot authored Oct 8, 2019
2 parents 1a2decd + 712a334 commit 26c3eff
Show file tree
Hide file tree
Showing 4 changed files with 133 additions and 36 deletions.
18 changes: 13 additions & 5 deletions pkg/controller/framework_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -940,7 +940,15 @@ func newClaimArrayFinalizer(name, claimUID, capacity, boundToVolume string, phas
}

// newVolume returns a new volume with given attributes
func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, annotations ...string) *v1.PersistentVolume {
func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, driver string, namespace string, annotations ...string) *v1.PersistentVolume {
inDriverName := mockDriverName
if driver != "" {
inDriverName = driver
}
inNamespace := testNamespace
if namespace != "" {
inNamespace = namespace
}
volume := v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Expand All @@ -954,7 +962,7 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo
},
PersistentVolumeSource: v1.PersistentVolumeSource{
CSI: &v1.CSIPersistentVolumeSource{
Driver: mockDriverName,
Driver: inDriverName,
VolumeHandle: volumeHandle,
},
},
Expand All @@ -972,7 +980,7 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo
Kind: "PersistentVolumeClaim",
APIVersion: "v1",
UID: types.UID(boundToClaimUID),
Namespace: testNamespace,
Namespace: inNamespace,
Name: boundToClaimName,
}
}
Expand All @@ -982,9 +990,9 @@ func newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundTo

// newVolumeArray returns array with a single volume that would be returned by
// newVolume() with the same parameters.
func newVolumeArray(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string) []*v1.PersistentVolume {
func newVolumeArray(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName string, phase v1.PersistentVolumePhase, reclaimPolicy v1.PersistentVolumeReclaimPolicy, class string, driver string, namespace string) []*v1.PersistentVolume {
return []*v1.PersistentVolume{
newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName, phase, reclaimPolicy, class),
newVolume(name, volumeUID, volumeHandle, capacity, boundToClaimUID, boundToClaimName, phase, reclaimPolicy, class, driver, namespace),
}
}

Expand Down
29 changes: 29 additions & 0 deletions pkg/controller/snapshot_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -897,11 +897,40 @@ func (ctrl *csiSnapshotController) getVolumeFromVolumeSnapshot(snapshot *crdv1.V
return nil, fmt.Errorf("failed to retrieve PV %s from the API server: %q", pvName, err)
}

// Verify binding between PV/PVC is still valid
bound := ctrl.IsVolumeBoundToClaim(pv, pvc)
if bound == false {
klog.Warningf("binding between PV %s and PVC %s is broken", pvName, pvc.Name)
return nil, fmt.Errorf("claim in dataSource not bound or invalid")
}

// Verify driver for PVC is the same as driver for VolumeSnapshot
if pv.Spec.PersistentVolumeSource.CSI == nil || pv.Spec.PersistentVolumeSource.CSI.Driver != ctrl.snapshotterName {
klog.Warningf("driver for PV %s is different from driver %s for snapshot %s", pvName, ctrl.snapshotterName, snapshot.Name)
return nil, fmt.Errorf("claim in dataSource not bound or invalid")
}

klog.V(5).Infof("getVolumeFromVolumeSnapshot: snapshot [%s] PV name [%s]", snapshot.Name, pvName)

return pv, nil
}

// IsVolumeBoundToClaim returns true, if given volume is pre-bound or bound
// to specific claim. Both claim.Name and claim.Namespace must be equal.
// If claim.UID is present in volume.Spec.ClaimRef, it must be equal too.
func (ctrl *csiSnapshotController) IsVolumeBoundToClaim(volume *v1.PersistentVolume, claim *v1.PersistentVolumeClaim) bool {
if volume.Spec.ClaimRef == nil {
return false
}
if claim.Name != volume.Spec.ClaimRef.Name || claim.Namespace != volume.Spec.ClaimRef.Namespace {
return false
}
if volume.Spec.ClaimRef.UID != "" && claim.UID != volume.Spec.ClaimRef.UID {
return false
}
return true
}

func (ctrl *csiSnapshotController) getStorageClassFromVolumeSnapshot(snapshot *crdv1.VolumeSnapshot) (*storagev1.StorageClass, error) {
// Get storage class from PVC or PV
pvc, err := ctrl.getClaimFromVolumeSnapshot(snapshot)
Expand Down
Loading

0 comments on commit 26c3eff

Please sign in to comment.