mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-05 15:37:24 +00:00
Include CSIDriver SupportsFsGroup
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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: ¬PodInfoOnMount,
|
||||
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: ¬PodInfoOnMount,
|
||||
FSGroupPolicy: &invalidFSGroupPolicy,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, csiDriver := range errorCases {
|
||||
|
||||
Reference in New Issue
Block a user