cephfs: disallow creating small volumes from snapshot/volume

as per the CSI standard the size is optional parameter,
as we are allowing the clone to a bigger size
today we need to block the clone to a smaller size
as its a have side effects like data corruption etc.

Note:- Even though this check is present in kubernetes
sidecar as CSI is CO independent adding the check
here.

fixes: #2718

Signed-off-by: Madhu Rajanna <madhupr007@gmail.com>
This commit is contained in:
Madhu Rajanna 2022-01-17 12:44:39 +05:30 committed by mergify[bot]
parent 732ab13096
commit d357bebbc2

View File

@ -148,6 +148,35 @@ func checkContentSource(
return nil, nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source %v", volumeSource) return nil, nil, nil, status.Errorf(codes.InvalidArgument, "not a proper volume source %v", volumeSource)
} }
// checkValidCreateVolumeRequest checks if the request is valid
// CreateVolumeRequest by inspecting the request parameters.
func checkValidCreateVolumeRequest(
vol,
parentVol *store.VolumeOptions,
pvID *store.VolumeIdentifier,
sID *store.SnapshotIdentifier) error {
switch {
case pvID != nil:
if vol.Size < parentVol.Size {
return fmt.Errorf(
"cannot clone from volume %s: volume size %d is smaller than source volume size %d",
pvID.VolumeID,
parentVol.Size,
vol.Size)
}
case sID != nil:
if vol.Size < parentVol.Size {
return fmt.Errorf(
"cannot restore from snapshot %s: volume size %d is smaller than source volume size %d",
sID.SnapshotID,
parentVol.Size,
vol.Size)
}
}
return nil
}
// CreateVolume creates a reservation and the volume in backend, if it is not already present. // CreateVolume creates a reservation and the volume in backend, if it is not already present.
// nolint:gocognit,gocyclo,nestif,cyclop // TODO: reduce complexity // nolint:gocognit,gocyclo,nestif,cyclop // TODO: reduce complexity
func (cs *ControllerServer) CreateVolume( func (cs *ControllerServer) CreateVolume(
@ -199,6 +228,11 @@ func (cs *ControllerServer) CreateVolume(
defer parentVol.Destroy() defer parentVol.Destroy()
} }
err = checkValidCreateVolumeRequest(volOptions, parentVol, pvID, sID)
if err != nil {
return nil, status.Error(codes.InvalidArgument, err.Error())
}
vID, err := store.CheckVolExists(ctx, volOptions, parentVol, pvID, sID, cr) vID, err := store.CheckVolExists(ctx, volOptions, parentVol, pvID, sID, cr)
if err != nil { if err != nil {
if cerrors.IsCloneRetryError(err) { if cerrors.IsCloneRetryError(err) {