Include CSIDriver SupportsFsGroup

This commit is contained in:
Christian Huffman
2020-06-10 14:54:48 -04:00
parent 70f68dbf74
commit 58bd3e5230
13 changed files with 369 additions and 38 deletions

View File

@@ -277,6 +277,14 @@ type CSIDriverSpec struct {
// +optional
AttachRequired *bool
// Defines if the underlying volume supports changing ownership and
// permission of the volume before being mounted.
// Refer to the specific FSGroupPolicy values for additional details.
// This field is alpha-level, and is only honored by servers
// that enable the CSIVolumeFSGroupPolicy feature gate.
// +optional
FSGroupPolicy *FSGroupPolicy
// If set to true, podInfoOnMount indicates this CSI volume driver
// requires additional pod information (like podName, podUID, etc.) during
// mount operations.
@@ -331,6 +339,37 @@ type CSIDriverSpec struct {
StorageCapacity *bool
}
// FSGroupPolicy specifies if a CSI Driver supports modifying
// volume ownership and permissions of the volume to be mounted.
// More modes may be added in the future.
type FSGroupPolicy string
const (
// ReadWriteOnceWithFSTypeFSGroupPolicy indicates that each volume will be examined
// to determine if the volume ownership and permissions
// should be modified. If a fstype is defined and the volume's access mode
// contains ReadWriteOnce, then the defined fsGroup will be applied.
// This mode should be defined if it's expected that the
// fsGroup may need to be modified depending on the pod's SecurityPolicy.
// This is the default behavior if no other FSGroupPolicy is defined.
ReadWriteOnceWithFSTypeFSGroupPolicy FSGroupPolicy = "ReadWriteOnceWithFSType"
// FileFSGroupPolicy indicates that CSI driver supports volume ownership
// and permission change via fsGroup, and Kubernetes may use fsGroup
// to change permissions and ownership of the volume to match user requested fsGroup in
// the pod's SecurityPolicy regardless of fstype or access mode.
// This mode should be defined if the fsGroup is expected to always change on mount
FileFSGroupPolicy FSGroupPolicy = "File"
// NoneFSGroupPolicy indicates that volumes will be mounted without performing
// any ownership or permission modifications, as the CSIDriver does not support
// these operations.
// This mode should be selected if the CSIDriver does not support fsGroup modifications,
// for example when Kubernetes cannot change ownership and permissions on a volume due
// to root-squash settings on a NFS volume.
NoneFSGroupPolicy FSGroupPolicy = "None"
)
// VolumeLifecycleMode specifies how a CSI volume is used in Kubernetes.
// More modes may be added in the future.
type VolumeLifecycleMode string

View File

@@ -53,6 +53,10 @@ func SetDefaults_CSIDriver(obj *storagev1.CSIDriver) {
obj.Spec.StorageCapacity = new(bool)
*(obj.Spec.StorageCapacity) = false
}
if obj.Spec.FSGroupPolicy == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIVolumeFSGroupPolicy) {
obj.Spec.FSGroupPolicy = new(storagev1.FSGroupPolicy)
*obj.Spec.FSGroupPolicy = storagev1.ReadWriteOnceWithFSTypeFSGroupPolicy
}
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1.VolumeLifecyclePersistent)
}

View File

@@ -17,7 +17,7 @@ limitations under the License.
package v1beta1
import (
"k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
storagev1beta1 "k8s.io/api/storage/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
utilfeature "k8s.io/apiserver/pkg/util/feature"
@@ -53,6 +53,10 @@ func SetDefaults_CSIDriver(obj *storagev1beta1.CSIDriver) {
obj.Spec.StorageCapacity = new(bool)
*(obj.Spec.StorageCapacity) = false
}
if obj.Spec.FSGroupPolicy == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIVolumeFSGroupPolicy) {
obj.Spec.FSGroupPolicy = new(storagev1beta1.FSGroupPolicy)
*obj.Spec.FSGroupPolicy = storagev1beta1.ReadWriteOnceWithFSTypeFSGroupPolicy
}
if len(obj.Spec.VolumeLifecycleModes) == 0 && utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
obj.Spec.VolumeLifecycleModes = append(obj.Spec.VolumeLifecycleModes, storagev1beta1.VolumeLifecyclePersistent)
}

View File

@@ -421,6 +421,7 @@ func validateCSIDriverSpec(
allErrs = append(allErrs, validateAttachRequired(spec.AttachRequired, fldPath.Child("attachedRequired"))...)
allErrs = append(allErrs, validatePodInfoOnMount(spec.PodInfoOnMount, fldPath.Child("podInfoOnMount"))...)
allErrs = append(allErrs, validateStorageCapacity(spec.StorageCapacity, fldPath.Child("storageCapacity"))...)
allErrs = append(allErrs, validateFSGroupPolicy(spec.FSGroupPolicy, fldPath.Child("fsGroupPolicy"))...)
allErrs = append(allErrs, validateVolumeLifecycleModes(spec.VolumeLifecycleModes, fldPath.Child("volumeLifecycleModes"))...)
return allErrs
}
@@ -451,6 +452,21 @@ func validateStorageCapacity(storageCapacity *bool, fldPath *field.Path) field.E
if storageCapacity == nil && utilfeature.DefaultFeatureGate.Enabled(features.CSIStorageCapacity) {
allErrs = append(allErrs, field.Required(fldPath, ""))
}
}
var supportedFSGroupPolicy = sets.NewString(string(storage.ReadWriteOnceWithFSTypeFSGroupPolicy), string(storage.FileFSGroupPolicy), string(storage.NoneFSGroupPolicy))
// validateFSGroupPolicy tests if FSGroupPolicy contains an appropriate value.
func validateFSGroupPolicy(fsGroupPolicy *storage.FSGroupPolicy, fldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}
if fsGroupPolicy == nil {
// This is not a required field, so if nothing is provided simply return
return allErrs
}
if !supportedFSGroupPolicy.Has(string(*fsGroupPolicy)) {
allErrs = append(allErrs, field.NotSupported(fldPath, fsGroupPolicy, supportedFSGroupPolicy.List()))
}
return allErrs
}

View File

@@ -1665,6 +1665,9 @@ func TestCSIDriverValidation(t *testing.T) {
attachNotRequired := false
podInfoOnMount := true
notPodInfoOnMount := false
supportedFSGroupPolicy := storage.FileFSGroupPolicy
invalidFSGroupPolicy := storage.ReadWriteOnceWithFSTypeFSGroupPolicy
invalidFSGroupPolicy = "invalid-mode"
successCases := []storage.CSIDriver{
{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
@@ -1769,6 +1772,14 @@ func TestCSIDriverValidation(t *testing.T) {
},
},
},
{
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount,
FSGroupPolicy: &supportedFSGroupPolicy,
},
},
}
for _, csiDriver := range successCases {
@@ -1818,6 +1829,15 @@ func TestCSIDriverValidation(t *testing.T) {
},
},
},
{
// invalid fsGroupPolicy
ObjectMeta: metav1.ObjectMeta{Name: driverName},
Spec: storage.CSIDriverSpec{
AttachRequired: &attachNotRequired,
PodInfoOnMount: &notPodInfoOnMount,
FSGroupPolicy: &invalidFSGroupPolicy,
},
},
}
for _, csiDriver := range errorCases {