Merge pull request #76915 from vladimirvivien/csi-inline-podsec-policy

CSI ephemeral - Enforcing pod security policy AllowedCSIDriver
This commit is contained in:
Kubernetes Prow Robot 2019-05-29 21:28:17 -07:00 committed by GitHub
commit 3aecf4350e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 228 additions and 38 deletions

View File

@ -12392,7 +12392,7 @@
"type": "boolean" "type": "boolean"
}, },
"allowedCSIDrivers": { "allowedCSIDrivers": {
"description": "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.", "description": "AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded 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.",
"items": { "items": {
"$ref": "#/definitions/io.k8s.api.extensions.v1beta1.AllowedCSIDriver" "$ref": "#/definitions/io.k8s.api.extensions.v1beta1.AllowedCSIDriver"
}, },
@ -13733,7 +13733,7 @@
"type": "boolean" "type": "boolean"
}, },
"allowedCSIDrivers": { "allowedCSIDrivers": {
"description": "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.", "description": "AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded 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.",
"items": { "items": {
"$ref": "#/definitions/io.k8s.api.policy.v1beta1.AllowedCSIDriver" "$ref": "#/definitions/io.k8s.api.policy.v1beta1.AllowedCSIDriver"
}, },

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

@ -872,7 +872,8 @@ message PodSecurityPolicySpec {
repeated AllowedFlexVolume allowedFlexVolumes = 18; repeated AllowedFlexVolume allowedFlexVolumes = 18;
// 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
repeated AllowedCSIDriver allowedCSIDrivers = 23; repeated AllowedCSIDriver allowedCSIDrivers = 23;

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

@ -470,7 +470,7 @@ var map_PodSecurityPolicySpec = map[string]string{
"allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.", "allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.",
"allowedHostPaths": "allowedHostPaths is a white list of allowed host paths. Empty indicates that all host paths may be used.", "allowedHostPaths": "allowedHostPaths is a white list of allowed host paths. Empty indicates that all host paths may be used.",
"allowedFlexVolumes": "allowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.", "allowedFlexVolumes": "allowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.",
"allowedCSIDrivers": "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.", "allowedCSIDrivers": "AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded 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.",
"allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.", "allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.",
"forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.", "forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.",
"allowedProcMountTypes": "AllowedProcMountTypes is a whitelist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.", "allowedProcMountTypes": "AllowedProcMountTypes is a whitelist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.",

View File

@ -299,7 +299,8 @@ message PodSecurityPolicySpec {
repeated AllowedFlexVolume allowedFlexVolumes = 18; repeated AllowedFlexVolume allowedFlexVolumes = 18;
// 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
repeated AllowedCSIDriver allowedCSIDrivers = 23; repeated AllowedCSIDriver allowedCSIDrivers = 23;

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.

View File

@ -179,7 +179,7 @@ var map_PodSecurityPolicySpec = map[string]string{
"allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.", "allowPrivilegeEscalation": "allowPrivilegeEscalation determines if a pod can request to allow privilege escalation. If unspecified, defaults to true.",
"allowedHostPaths": "allowedHostPaths is a white list of allowed host paths. Empty indicates that all host paths may be used.", "allowedHostPaths": "allowedHostPaths is a white list of allowed host paths. Empty indicates that all host paths may be used.",
"allowedFlexVolumes": "allowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.", "allowedFlexVolumes": "allowedFlexVolumes is a whitelist of allowed Flexvolumes. Empty or nil indicates that all Flexvolumes may be used. This parameter is effective only when the usage of the Flexvolumes is allowed in the \"volumes\" field.",
"allowedCSIDrivers": "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.", "allowedCSIDrivers": "AllowedCSIDrivers is a whitelist of inline CSI drivers that must be explicitly set to be embedded 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.",
"allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.", "allowedUnsafeSysctls": "allowedUnsafeSysctls is a list of explicitly allowed unsafe sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of allowed sysctls. Single * means all unsafe sysctls are allowed. Kubelet has to whitelist all allowed unsafe sysctls explicitly to avoid rejection.\n\nExamples: e.g. \"foo/*\" allows \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" allows \"foo.bar\", \"foo.baz\", etc.",
"forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.", "forbiddenSysctls": "forbiddenSysctls is a list of explicitly forbidden sysctls, defaults to none. Each entry is either a plain sysctl name or ends in \"*\" in which case it is considered as a prefix of forbidden sysctls. Single * means all sysctls are forbidden.\n\nExamples: e.g. \"foo/*\" forbids \"foo/bar\", \"foo/baz\", etc. e.g. \"foo.*\" forbids \"foo.bar\", \"foo.baz\", etc.",
"allowedProcMountTypes": "AllowedProcMountTypes is a whitelist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.", "allowedProcMountTypes": "AllowedProcMountTypes is a whitelist of allowed ProcMountTypes. Empty or nil indicates that only the DefaultProcMountType may be used. This requires the ProcMountType feature flag to be enabled.",