Enforce pod security policy for CSI inline

k3s-v1.15.3
Vladimir Vivien 2019-04-22 18:15:47 -05:00
parent 864e5e564a
commit 8e0cf65310
10 changed files with 220 additions and 32 deletions

View File

@ -209,7 +209,8 @@ type PodSecurityPolicySpec struct {
// +optional // +optional
AllowedFlexVolumes []AllowedFlexVolume AllowedFlexVolumes []AllowedFlexVolume
// AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. // AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
// An empty value means no CSI drivers can run inline within a pod spec. // An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
// This is an alpha field, and is only honored if the API server enables the CSIInlineVolume feature gate.
// +optional // +optional
AllowedCSIDrivers []AllowedCSIDriver AllowedCSIDrivers []AllowedCSIDriver
// AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. // AllowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.

View File

@ -281,6 +281,10 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
invalidProcMount := validPSP() invalidProcMount := validPSP()
invalidProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.ProcMountType("bogus")} invalidProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.ProcMountType("bogus")}
allowedCSIDriverPSP := validPSP()
allowedCSIDriverPSP.Spec.Volumes = []policy.FSType{policy.CSI}
allowedCSIDriverPSP.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{}}
type testCase struct { type testCase struct {
psp *policy.PodSecurityPolicy psp *policy.PodSecurityPolicy
errorType field.ErrorType errorType field.ErrorType
@ -447,6 +451,10 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
errorType: field.ErrorTypeRequired, errorType: field.ErrorTypeRequired,
errorDetail: "must specify a driver", errorDetail: "must specify a driver",
}, },
"CSI policy with empty allowed driver list": {
psp: allowedCSIDriverPSP,
errorType: field.ErrorTypeRequired,
},
"invalid allowedProcMountTypes": { "invalid allowedProcMountTypes": {
psp: invalidProcMount, psp: invalidProcMount,
errorType: field.ErrorTypeNotSupported, errorType: field.ErrorTypeNotSupported,
@ -549,6 +557,14 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
validProcMount := validPSP() validProcMount := validPSP()
validProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.DefaultProcMount, api.UnmaskedProcMount} validProcMount.Spec.AllowedProcMountTypes = []api.ProcMountType{api.DefaultProcMount, api.UnmaskedProcMount}
allowedCSIDriversWithCSIFsType := validPSP()
allowedCSIDriversWithCSIFsType.Spec.Volumes = []policy.FSType{policy.CSI}
allowedCSIDriversWithCSIFsType.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "foo"}}
allowedCSIDriversWithAllFsTypes := validPSP()
allowedCSIDriversWithAllFsTypes.Spec.Volumes = []policy.FSType{policy.All}
allowedCSIDriversWithAllFsTypes.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "bar"}}
successCases := map[string]struct { successCases := map[string]struct {
psp *policy.PodSecurityPolicy psp *policy.PodSecurityPolicy
}{ }{
@ -591,6 +607,12 @@ func TestValidatePodSecurityPolicy(t *testing.T) {
"valid allowedProcMountTypes": { "valid allowedProcMountTypes": {
psp: validProcMount, psp: validProcMount,
}, },
"allowed CSI drivers when FSType policy is set to CSI": {
psp: allowedCSIDriversWithCSIFsType,
},
"allowed CSI drivers when FSType policy is set to All": {
psp: allowedCSIDriversWithAllFsTypes,
},
} }
for k, v := range successCases { for k, v := range successCases {

View File

@ -3856,6 +3856,11 @@ func describePodSecurityPolicy(psp *policyv1beta1.PodSecurityPolicy) (string, er
if len(psp.Spec.AllowedFlexVolumes) > 0 { if len(psp.Spec.AllowedFlexVolumes) > 0 {
w.Write(LEVEL_1, "Allowed FlexVolume Types:\t%s\n", flexVolumesToString(psp.Spec.AllowedFlexVolumes)) w.Write(LEVEL_1, "Allowed FlexVolume Types:\t%s\n", flexVolumesToString(psp.Spec.AllowedFlexVolumes))
} }
if len(psp.Spec.AllowedCSIDrivers) > 0 {
w.Write(LEVEL_1, "Allowed CSI Drivers:\t%s\n", csiDriversToString(psp.Spec.AllowedCSIDrivers))
}
if len(psp.Spec.AllowedUnsafeSysctls) > 0 { if len(psp.Spec.AllowedUnsafeSysctls) > 0 {
w.Write(LEVEL_1, "Allowed Unsafe Sysctls:\t%s\n", sysctlsToString(psp.Spec.AllowedUnsafeSysctls)) w.Write(LEVEL_1, "Allowed Unsafe Sysctls:\t%s\n", sysctlsToString(psp.Spec.AllowedUnsafeSysctls))
} }
@ -3921,6 +3926,14 @@ func flexVolumesToString(flexVolumes []policyv1beta1.AllowedFlexVolume) string {
return stringOrDefaultValue(strings.Join(volumes, ","), "<all>") return stringOrDefaultValue(strings.Join(volumes, ","), "<all>")
} }
func csiDriversToString(csiDrivers []policyv1beta1.AllowedCSIDriver) string {
drivers := []string{}
for _, csiDriver := range csiDrivers {
drivers = append(drivers, "driver="+csiDriver.Name)
}
return stringOrDefaultValue(strings.Join(drivers, ","), "<all>")
}
func sysctlsToString(sysctls []string) string { func sysctlsToString(sysctls []string) string {
return stringOrNone(strings.Join(sysctls, ",")) return stringOrNone(strings.Join(sysctls, ","))
} }

View File

@ -42,6 +42,7 @@ go_test(
deps = [ deps = [
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/v1:go_default_library", "//pkg/apis/core/v1:go_default_library",
"//pkg/features:go_default_library",
"//pkg/security/apparmor:go_default_library", "//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/seccomp:go_default_library",
"//pkg/security/podsecuritypolicy/util:go_default_library", "//pkg/security/podsecuritypolicy/util:go_default_library",
@ -49,6 +50,8 @@ go_test(
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library",

View File

@ -233,6 +233,28 @@ func (s *simpleProvider) ValidatePod(pod *api.Pod) field.ErrorList {
allErrs = append(allErrs, s.strategies.SysctlsStrategy.Validate(pod)...) allErrs = append(allErrs, s.strategies.SysctlsStrategy.Validate(pod)...)
allErrs = append(allErrs, s.validatePodVolumes(pod)...)
if s.psp.Spec.RuntimeClass != nil {
allErrs = append(allErrs, validateRuntimeClassName(pod.Spec.RuntimeClassName, s.psp.Spec.RuntimeClass.AllowedRuntimeClassNames)...)
}
fldPath := field.NewPath("spec", "initContainers")
for i := range pod.Spec.InitContainers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.InitContainers[i], fldPath.Index(i))...)
}
fldPath = field.NewPath("spec", "containers")
for i := range pod.Spec.Containers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.Containers[i], fldPath.Index(i))...)
}
return allErrs
}
func (s *simpleProvider) validatePodVolumes(pod *api.Pod) field.ErrorList {
allErrs := field.ErrorList{}
if len(pod.Spec.Volumes) > 0 { if len(pod.Spec.Volumes) > 0 {
allowsAllVolumeTypes := psputil.PSPAllowsAllVolumes(s.psp) allowsAllVolumeTypes := psputil.PSPAllowsAllVolumes(s.psp)
allowedVolumes := psputil.FSTypeToStringSet(s.psp.Spec.Volumes) allowedVolumes := psputil.FSTypeToStringSet(s.psp.Spec.Volumes)
@ -250,7 +272,8 @@ func (s *simpleProvider) ValidatePod(pod *api.Pod) field.ErrorList {
continue continue
} }
if fsType == policy.HostPath { switch fsType {
case policy.HostPath:
allows, mustBeReadOnly := psputil.AllowsHostVolumePath(s.psp, v.HostPath.Path) allows, mustBeReadOnly := psputil.AllowsHostVolumePath(s.psp, v.HostPath.Path)
if !allows { if !allows {
allErrs = append(allErrs, field.Invalid( allErrs = append(allErrs, field.Invalid(
@ -279,40 +302,46 @@ func (s *simpleProvider) ValidatePod(pod *api.Pod) field.ErrorList {
} }
} }
} }
}
if fsType == policy.FlexVolume && len(s.psp.Spec.AllowedFlexVolumes) > 0 { case policy.FlexVolume:
found := false if len(s.psp.Spec.AllowedFlexVolumes) > 0 {
driver := v.FlexVolume.Driver found := false
for _, allowedFlexVolume := range s.psp.Spec.AllowedFlexVolumes { driver := v.FlexVolume.Driver
if driver == allowedFlexVolume.Driver { for _, allowedFlexVolume := range s.psp.Spec.AllowedFlexVolumes {
found = true if driver == allowedFlexVolume.Driver {
break found = true
break
}
}
if !found {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "volumes").Index(i).Child("driver"), driver,
"Flexvolume driver is not allowed to be used"))
} }
} }
if !found {
allErrs = append(allErrs, case policy.CSI:
field.Invalid(field.NewPath("spec", "volumes").Index(i).Child("driver"), driver, if utilfeature.DefaultFeatureGate.Enabled(features.CSIInlineVolume) {
"Flexvolume driver is not allowed to be used")) if len(s.psp.Spec.AllowedCSIDrivers) > 0 {
found := false
driver := v.CSI.Driver
for _, allowedCSIDriver := range s.psp.Spec.AllowedCSIDrivers {
if driver == allowedCSIDriver.Name {
found = true
break
}
}
if !found {
allErrs = append(allErrs,
field.Invalid(field.NewPath("spec", "volumes").Index(i).Child("csi", "driver"), driver,
"Inline CSI driver is not allowed to be used"))
}
}
} }
} }
} }
} }
if s.psp.Spec.RuntimeClass != nil {
allErrs = append(allErrs, validateRuntimeClassName(pod.Spec.RuntimeClassName, s.psp.Spec.RuntimeClass.AllowedRuntimeClassNames)...)
}
fldPath := field.NewPath("spec", "initContainers")
for i := range pod.Spec.InitContainers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.InitContainers[i], fldPath.Index(i))...)
}
fldPath = field.NewPath("spec", "containers")
for i := range pod.Spec.Containers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.Containers[i], fldPath.Index(i))...)
}
return allErrs return allErrs
} }

View File

@ -25,12 +25,15 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
policy "k8s.io/api/policy/v1beta1" policy "k8s.io/api/policy/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/diff"
utilfeature "k8s.io/apiserver/pkg/util/feature"
featuregatetesting "k8s.io/component-base/featuregate/testing"
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/security/apparmor" "k8s.io/kubernetes/pkg/security/apparmor"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp" "k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util" psputil "k8s.io/kubernetes/pkg/security/podsecuritypolicy/util"
@ -172,6 +175,8 @@ func TestMutateContainerNonmutating(t *testing.T) {
} }
func TestValidatePodFailures(t *testing.T) { func TestValidatePodFailures(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
failHostNetworkPod := defaultPod() failHostNetworkPod := defaultPod()
failHostNetworkPod.Spec.SecurityContext.HostNetwork = true failHostNetworkPod.Spec.SecurityContext.HostNetwork = true
@ -328,6 +333,18 @@ func TestValidatePodFailures(t *testing.T) {
}, },
} }
failCSIDriverPod := defaultPod()
failCSIDriverPod.Spec.Volumes = []api.Volume{
{
Name: "csi volume pod",
VolumeSource: api.VolumeSource{
CSI: &api.CSIVolumeSource{
Driver: "csi.driver.foo",
},
},
},
}
errorCases := map[string]struct { errorCases := map[string]struct {
pod *api.Pod pod *api.Pod
psp *policy.PodSecurityPolicy psp *policy.PodSecurityPolicy
@ -433,6 +450,40 @@ func TestValidatePodFailures(t *testing.T) {
psp: allowFlexVolumesPSP(false, true), psp: allowFlexVolumesPSP(false, true),
expectedError: "Flexvolume driver is not allowed to be used", expectedError: "Flexvolume driver is not allowed to be used",
}, },
"CSI policy using disallowed CDI driver": {
pod: failCSIDriverPod,
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.Volumes = []policy.FSType{policy.CSI}
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "csi.driver.disallowed"}}
return psp
}(),
expectedError: "Inline CSI driver is not allowed to be used",
},
"Using inline CSI driver with no policy specified": {
pod: failCSIDriverPod,
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "csi.driver.foo"}}
return psp
}(),
expectedError: "csi volumes are not allowed to be used",
},
"policy.All using disallowed CDI driver": {
pod: failCSIDriverPod,
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.Volumes = []policy.FSType{policy.All}
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "csi.driver.disallowed"}}
return psp
}(),
expectedError: "Inline CSI driver is not allowed to be used",
},
"CSI inline volumes without proper policy set": {
pod: failCSIDriverPod,
psp: defaultPSP(),
expectedError: "csi volumes are not allowed to be used",
},
} }
for name, test := range errorCases { for name, test := range errorCases {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
@ -616,6 +667,8 @@ func TestValidateContainerFailures(t *testing.T) {
} }
func TestValidatePodSuccess(t *testing.T) { func TestValidatePodSuccess(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
hostNetworkPSP := defaultPSP() hostNetworkPSP := defaultPSP()
hostNetworkPSP.Spec.HostNetwork = true hostNetworkPSP.Spec.HostNetwork = true
hostNetworkPod := defaultPod() hostNetworkPod := defaultPod()
@ -806,6 +859,34 @@ func TestValidatePodSuccess(t *testing.T) {
}, },
} }
csiDriverPod := defaultPod()
csiDriverPod.Spec.Volumes = []api.Volume{
{
Name: "csi inline driver",
VolumeSource: api.VolumeSource{
CSI: &api.CSIVolumeSource{
Driver: "foo",
},
},
},
{
Name: "csi inline driver 2",
VolumeSource: api.VolumeSource{
CSI: &api.CSIVolumeSource{
Driver: "bar",
},
},
},
{
Name: "csi inline driver 3",
VolumeSource: api.VolumeSource{
CSI: &api.CSIVolumeSource{
Driver: "baz",
},
},
},
}
successCases := map[string]struct { successCases := map[string]struct {
pod *api.Pod pod *api.Pod
psp *policy.PodSecurityPolicy psp *policy.PodSecurityPolicy
@ -886,6 +967,33 @@ func TestValidatePodSuccess(t *testing.T) {
pod: flexVolumePod, pod: flexVolumePod,
psp: allowFlexVolumesPSP(true, false), psp: allowFlexVolumesPSP(true, false),
}, },
"CSI policy with no CSI volumes used": {
pod: defaultPod(),
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.Volumes = []policy.FSType{policy.CSI}
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "foo"}, {Name: "bar"}, {Name: "baz"}}
return psp
}(),
},
"CSI policy with CSI inline volumes used": {
pod: csiDriverPod,
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.Volumes = []policy.FSType{policy.CSI}
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "foo"}, {Name: "bar"}, {Name: "baz"}}
return psp
}(),
},
"policy.All with CSI inline volumes used": {
pod: csiDriverPod,
psp: func() *policy.PodSecurityPolicy {
psp := defaultPSP()
psp.Spec.Volumes = []policy.FSType{policy.All}
psp.Spec.AllowedCSIDrivers = []policy.AllowedCSIDriver{{Name: "foo"}, {Name: "bar"}, {Name: "baz"}}
return psp
}(),
},
} }
for name, test := range successCases { for name, test := range successCases {
@ -1218,6 +1326,8 @@ func defaultV1Pod() *v1.Pod {
// a pod with that type of volume and deny it, accept it explicitly, or accept it with // a pod with that type of volume and deny it, accept it explicitly, or accept it with
// the FSTypeAll wildcard. // the FSTypeAll wildcard.
func TestValidateAllowedVolumes(t *testing.T) { func TestValidateAllowedVolumes(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
val := reflect.ValueOf(api.VolumeSource{}) val := reflect.ValueOf(api.VolumeSource{})
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {

View File

@ -41,6 +41,7 @@ go_test(
"//pkg/apis/core:go_default_library", "//pkg/apis/core:go_default_library",
"//pkg/apis/core/v1:go_default_library", "//pkg/apis/core/v1:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library",
"//pkg/security/apparmor:go_default_library", "//pkg/security/apparmor:go_default_library",
"//pkg/security/podsecuritypolicy:go_default_library", "//pkg/security/podsecuritypolicy:go_default_library",
"//pkg/security/podsecuritypolicy/seccomp:go_default_library", "//pkg/security/podsecuritypolicy/seccomp:go_default_library",
@ -56,7 +57,9 @@ go_test(
"//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authentication/user:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library", "//staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/utils/pointer:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library",
], ],

View File

@ -35,11 +35,14 @@ import (
"k8s.io/apiserver/pkg/authentication/user" "k8s.io/apiserver/pkg/authentication/user"
"k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/authorization/authorizerfactory" "k8s.io/apiserver/pkg/authorization/authorizerfactory"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
kapi "k8s.io/kubernetes/pkg/apis/core" kapi "k8s.io/kubernetes/pkg/apis/core"
k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1" k8s_api_v1 "k8s.io/kubernetes/pkg/apis/core/v1"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/security/apparmor" "k8s.io/kubernetes/pkg/security/apparmor"
kpsp "k8s.io/kubernetes/pkg/security/podsecuritypolicy" kpsp "k8s.io/kubernetes/pkg/security/podsecuritypolicy"
"k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp" "k8s.io/kubernetes/pkg/security/podsecuritypolicy/seccomp"
@ -625,6 +628,8 @@ func TestAdmitCaps(t *testing.T) {
} }
func TestAdmitVolumes(t *testing.T) { func TestAdmitVolumes(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.CSIInlineVolume, true)()
val := reflect.ValueOf(kapi.VolumeSource{}) val := reflect.ValueOf(kapi.VolumeSource{})
for i := 0; i < val.NumField(); i++ { for i := 0; i < val.NumField(); i++ {

View File

@ -929,7 +929,8 @@ type PodSecurityPolicySpec struct {
// +optional // +optional
AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"` AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"`
// AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. // AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
// An empty value means no CSI drivers can run inline within a pod spec. // An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
// This is an alpha field, and is only honored if the API server enables the CSIInlineVolume feature gate.
// +optional // +optional
AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"` AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"`
// allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.

View File

@ -17,7 +17,7 @@ limitations under the License.
package v1beta1 package v1beta1
import ( import (
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/intstr"
) )
@ -217,7 +217,8 @@ type PodSecurityPolicySpec struct {
// +optional // +optional
AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"` AllowedFlexVolumes []AllowedFlexVolume `json:"allowedFlexVolumes,omitempty" protobuf:"bytes,18,rep,name=allowedFlexVolumes"`
// AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec. // AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded within a pod spec.
// An empty value means no CSI drivers can run inline within a pod spec. // An empty value indicates that any CSI driver can be used for inline ephemeral volumes.
// This is an alpha field, and is only honored if the API server enables the CSIInlineVolume feature gate.
// +optional // +optional
AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"` AllowedCSIDrivers []AllowedCSIDriver `json:"allowedCSIDrivers,omitempty" protobuf:"bytes,23,rep,name=allowedCSIDrivers"`
// allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. // allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none.