From 902e4168787f2734cf4324881eb5f89e0d5c1e75 Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Thu, 21 Jan 2016 09:47:35 -0400 Subject: [PATCH 1/3] UPSTREAM: : v1beta3 scc v1beta3 changes for new SCC allowEmptyDirVolumePlugin. Uses bool pointers to allow distinction between set vs unset, allowing us to roll this change out without affecting the default behaviour today which is to implicitly allow EmptyDir volumes. --- .../pkg/api/v1beta3/conversion_generated.go | 4 ++ .../pkg/api/v1beta3/deep_copy_generated.go | 6 ++ .../kubernetes/pkg/api/v1beta3/defaults.go | 6 ++ .../pkg/api/v1beta3/defaults_test.go | 56 ++++++++++++++----- .../kubernetes/pkg/api/v1beta3/types.go | 2 + 5 files changed, 61 insertions(+), 13 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go index 486c7c492972..e34476fe5c7b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/conversion_generated.go @@ -2054,6 +2054,7 @@ func convert_api_SecurityContextConstraints_To_v1beta3_SecurityContextConstraint out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowEmptyDirVolumePlugin = &in.AllowEmptyDirVolumePlugin out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID @@ -4318,6 +4319,9 @@ func convert_v1beta3_SecurityContextConstraints_To_api_SecurityContextConstraint out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + if in.AllowEmptyDirVolumePlugin != nil { + out.AllowEmptyDirVolumePlugin = *in.AllowEmptyDirVolumePlugin + } out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go index cc0d540d1fba..3bd7323a7e5a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/deep_copy_generated.go @@ -2053,6 +2053,12 @@ func deepCopy_v1beta3_SecurityContextConstraints(in SecurityContextConstraints, out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + if in.AllowEmptyDirVolumePlugin != nil { + out.AllowEmptyDirVolumePlugin = new(bool) + *out.AllowEmptyDirVolumePlugin = *in.AllowEmptyDirVolumePlugin + } else { + out.AllowEmptyDirVolumePlugin = nil + } out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go index cf8cf863f140..d81bace25bee 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults.go @@ -231,4 +231,10 @@ func defaultSecurityContextConstraints(scc *SecurityContextConstraints) { if len(scc.SupplementalGroups.Type) == 0 { scc.SupplementalGroups.Type = SupplementalGroupsStrategyRunAsAny } + + // EmptyDir volumes were implicitly allowed originally, always default this to true. + if scc.AllowEmptyDirVolumePlugin == nil { + scc.AllowEmptyDirVolumePlugin = new(bool) + *scc.AllowEmptyDirVolumePlugin = true + } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go index 9c5f9983644c..15fb596bf30d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/defaults_test.go @@ -527,15 +527,22 @@ func areSecurityContextAndContainerEqual(c *versioned.Container) (bool, []string return equal, issues } +func newBool(b bool) *bool { + ptr := new(bool) + ptr = &b + return ptr +} + func TestDefaultSecurityContextConstraints(t *testing.T) { if !registered.IsAllowedVersion(versioned.SchemeGroupVersion) { return } tests := map[string]struct { - scc *versioned.SecurityContextConstraints - expectedFSGroup versioned.FSGroupStrategyType - expectedSupGroup versioned.SupplementalGroupsStrategyType + scc *versioned.SecurityContextConstraints + expectedFSGroup versioned.FSGroupStrategyType + expectedSupGroup versioned.SupplementalGroupsStrategyType + expectedAllowEmptyDir bool }{ "shouldn't default": { scc: &versioned.SecurityContextConstraints{ @@ -545,9 +552,11 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { SupplementalGroups: versioned.SupplementalGroupsStrategyOptions{ Type: versioned.SupplementalGroupsStrategyMustRunAs, }, + AllowEmptyDirVolumePlugin: newBool(false), }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: false, }, "default fsgroup runAsAny": { scc: &versioned.SecurityContextConstraints{ @@ -558,8 +567,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.SupplementalGroupsStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyRunAsAny, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyRunAsAny, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: true, }, "default sup group runAsAny": { scc: &versioned.SecurityContextConstraints{ @@ -570,8 +580,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.FSGroupStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, }, "default fsgroup runAsAny with mustRunAs UID strat": { scc: &versioned.SecurityContextConstraints{ @@ -582,8 +593,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.SupplementalGroupsStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyRunAsAny, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyRunAsAny, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: true, }, "default sup group runAsAny with mustRunAs UID strat": { scc: &versioned.SecurityContextConstraints{ @@ -594,8 +606,23 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.FSGroupStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, + }, + "preserve AllowEmptyDirVolumePlugin set to true": { + scc: &versioned.SecurityContextConstraints{ + AllowEmptyDirVolumePlugin: newBool(true), + RunAsUser: versioned.RunAsUserStrategyOptions{ + Type: versioned.RunAsUserStrategyMustRunAsRange, + }, + FSGroup: versioned.FSGroupStrategyOptions{ + Type: versioned.FSGroupStrategyMustRunAs, + }, + }, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, }, } for k, v := range tests { @@ -608,5 +635,8 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { if scc.SupplementalGroups.Type != v.expectedSupGroup { t.Errorf("%s has invalid supplemental group. Expected: %v got: %v", k, v.expectedSupGroup, scc.SupplementalGroups.Type) } + if *scc.AllowEmptyDirVolumePlugin != v.expectedAllowEmptyDir { + t.Errorf("%s has invalid AllowEmptyDirVolumePlugin. Expected: %t got: %t", k, v.expectedAllowEmptyDir, *scc.AllowEmptyDirVolumePlugin) + } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go index d0189949165d..839ee1f2188d 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1beta3/types.go @@ -2105,6 +2105,8 @@ type SecurityContextConstraints struct { AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` + // AllowEmptyDirVolumePlugin determines if the policy allow containers to use the EmptyDir volume plugin + AllowEmptyDirVolumePlugin *bool `json:"allowEmptyDirVolumePlugin" description:"allow the use of the empty dir volume plugin; defaults to true"` // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` // AllowHostPorts determines if the policy allows host ports in the containers. From 7d1b481afcfa4aecd7669f345c491893fdd286dd Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Thu, 21 Jan 2016 09:49:52 -0400 Subject: [PATCH 2/3] UPSTREAM: : scc SCC support for allowing emptyDir volumes. Preserves current default behaviour of allowing. --- .../kubernetes/pkg/api/deep_copy_generated.go | 1 + .../src/k8s.io/kubernetes/pkg/api/types.go | 2 + .../pkg/api/v1/conversion_generated.go | 4 ++ .../pkg/api/v1/deep_copy_generated.go | 6 ++ .../k8s.io/kubernetes/pkg/api/v1/defaults.go | 6 ++ .../kubernetes/pkg/api/v1/defaults_test.go | 56 ++++++++++++++----- .../src/k8s.io/kubernetes/pkg/api/v1/types.go | 2 + .../pkg/kubectl/resource_printer.go | 6 +- .../securitycontextconstraints/provider.go | 15 +++-- .../provider_test.go | 36 +++++++++++- 10 files changed, 113 insertions(+), 21 deletions(-) diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go index 48bf0b3e9e36..fe146804376b 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/deep_copy_generated.go @@ -2532,6 +2532,7 @@ func deepCopy_api_SecurityContextConstraints(in SecurityContextConstraints, out out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowEmptyDirVolumePlugin = in.AllowEmptyDirVolumePlugin out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go index 8dc5d468ae88..15c5527609b6 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/types.go @@ -2326,6 +2326,8 @@ type SecurityContextConstraints struct { AllowedCapabilities []Capability // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin AllowHostDirVolumePlugin bool + // AllowEmptyDirVolumePlugin determines if the policy allow containers to use the EmptyDir volume plugin + AllowEmptyDirVolumePlugin bool // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. AllowHostNetwork bool // AllowHostPorts determines if the policy allows host ports in the containers. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go index 5f6dec27421c..4f72d51a0098 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/conversion_generated.go @@ -2866,6 +2866,7 @@ func autoConvert_api_SecurityContextConstraints_To_v1_SecurityContextConstraints out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + out.AllowEmptyDirVolumePlugin = &in.AllowEmptyDirVolumePlugin out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID @@ -6084,6 +6085,9 @@ func autoConvert_v1_SecurityContextConstraints_To_api_SecurityContextConstraints out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + if in.AllowEmptyDirVolumePlugin != nil { + out.AllowEmptyDirVolumePlugin = *in.AllowEmptyDirVolumePlugin + } out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go index 033bfbf254ca..a0454c15d37a 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/deep_copy_generated.go @@ -2263,6 +2263,12 @@ func deepCopy_v1_SecurityContextConstraints(in SecurityContextConstraints, out * out.AllowedCapabilities = nil } out.AllowHostDirVolumePlugin = in.AllowHostDirVolumePlugin + if in.AllowEmptyDirVolumePlugin != nil { + out.AllowEmptyDirVolumePlugin = new(bool) + *out.AllowEmptyDirVolumePlugin = *in.AllowEmptyDirVolumePlugin + } else { + out.AllowEmptyDirVolumePlugin = nil + } out.AllowHostNetwork = in.AllowHostNetwork out.AllowHostPorts = in.AllowHostPorts out.AllowHostPID = in.AllowHostPID diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go index 3cb6d13b4d1e..13505aa37774 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults.go @@ -312,4 +312,10 @@ func defaultSecurityContextConstraints(scc *SecurityContextConstraints) { if len(scc.SupplementalGroups.Type) == 0 { scc.SupplementalGroups.Type = SupplementalGroupsStrategyRunAsAny } + + // EmptyDir volumes were implicitly allowed originally, always default this to true. + if scc.AllowEmptyDirVolumePlugin == nil { + scc.AllowEmptyDirVolumePlugin = new(bool) + *scc.AllowEmptyDirVolumePlugin = true + } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go index 6e97409b1b10..8c09605437f8 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/defaults_test.go @@ -644,11 +644,18 @@ func TestSetDefaultProbe(t *testing.T) { } } +func newBool(b bool) *bool { + ptr := new(bool) + ptr = &b + return ptr +} + func TestDefaultSecurityContextConstraints(t *testing.T) { tests := map[string]struct { - scc *versioned.SecurityContextConstraints - expectedFSGroup versioned.FSGroupStrategyType - expectedSupGroup versioned.SupplementalGroupsStrategyType + scc *versioned.SecurityContextConstraints + expectedFSGroup versioned.FSGroupStrategyType + expectedSupGroup versioned.SupplementalGroupsStrategyType + expectedAllowEmptyDir bool }{ "shouldn't default": { scc: &versioned.SecurityContextConstraints{ @@ -658,9 +665,11 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { SupplementalGroups: versioned.SupplementalGroupsStrategyOptions{ Type: versioned.SupplementalGroupsStrategyMustRunAs, }, + AllowEmptyDirVolumePlugin: newBool(false), }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: false, }, "default fsgroup runAsAny": { scc: &versioned.SecurityContextConstraints{ @@ -671,8 +680,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.SupplementalGroupsStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyRunAsAny, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyRunAsAny, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: true, }, "default sup group runAsAny": { scc: &versioned.SecurityContextConstraints{ @@ -683,8 +693,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.FSGroupStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, }, "default fsgroup runAsAny with mustRunAs UID strat": { scc: &versioned.SecurityContextConstraints{ @@ -695,8 +706,9 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.SupplementalGroupsStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyRunAsAny, - expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedFSGroup: versioned.FSGroupStrategyRunAsAny, + expectedSupGroup: versioned.SupplementalGroupsStrategyMustRunAs, + expectedAllowEmptyDir: true, }, "default sup group runAsAny with mustRunAs UID strat": { scc: &versioned.SecurityContextConstraints{ @@ -707,8 +719,23 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { Type: versioned.FSGroupStrategyMustRunAs, }, }, - expectedFSGroup: versioned.FSGroupStrategyMustRunAs, - expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, + }, + "preserve AllowEmptyDirVolumePlugin set to true": { + scc: &versioned.SecurityContextConstraints{ + AllowEmptyDirVolumePlugin: newBool(true), + RunAsUser: versioned.RunAsUserStrategyOptions{ + Type: versioned.RunAsUserStrategyMustRunAsRange, + }, + FSGroup: versioned.FSGroupStrategyOptions{ + Type: versioned.FSGroupStrategyMustRunAs, + }, + }, + expectedFSGroup: versioned.FSGroupStrategyMustRunAs, + expectedSupGroup: versioned.SupplementalGroupsStrategyRunAsAny, + expectedAllowEmptyDir: true, }, } for k, v := range tests { @@ -721,5 +748,8 @@ func TestDefaultSecurityContextConstraints(t *testing.T) { if scc.SupplementalGroups.Type != v.expectedSupGroup { t.Errorf("%s has invalid supplemental group. Expected: %v got: %v", k, v.expectedSupGroup, scc.SupplementalGroups.Type) } + if *scc.AllowEmptyDirVolumePlugin != v.expectedAllowEmptyDir { + t.Errorf("%s has invalid AllowEmptyDirVolumePlugin. Expected: %t got: %t", k, v.expectedAllowEmptyDir, *scc.AllowEmptyDirVolumePlugin) + } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go index bf289c72bb64..2d19383c5a78 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/api/v1/types.go @@ -2738,6 +2738,8 @@ type SecurityContextConstraints struct { AllowedCapabilities []Capability `json:"allowedCapabilities" description:"capabilities that are allowed to be added"` // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin" description:"allow the use of the host dir volume plugin"` + // AllowEmptyDirVolumePlugin determines if the policy allow containers to use the EmptyDir volume plugin + AllowEmptyDirVolumePlugin *bool `json:"allowEmptyDirVolumePlugin" description:"allow the use of the empty dir volume plugin; defaults to true"` // AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec. AllowHostNetwork bool `json:"allowHostNetwork" description:"allow the use of the hostNetwork in the pod spec"` // AllowHostPorts determines if the policy allows host ports in the containers. diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go index 8dab04150b87..b4ef5618b238 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/kubectl/resource_printer.go @@ -417,7 +417,7 @@ var horizontalPodAutoscalerColumns = []string{"NAME", "REFERENCE", "TARGET", "CU var withNamespacePrefixColumns = []string{"NAMESPACE"} // TODO(erictune): print cluster name too. var deploymentColumns = []string{"NAME", "UPDATEDREPLICAS", "AGE"} var configMapColumns = []string{"NAME", "DATA", "AGE"} -var securityContextConstraintsColumns = []string{"NAME", "PRIV", "CAPS", "HOSTDIR", "SELINUX", "RUNASUSER", "FSGROUP", "SUPGROUP", "PRIORITY"} +var securityContextConstraintsColumns = []string{"NAME", "PRIV", "CAPS", "HOSTDIR", "EMPTYDIR", "SELINUX", "RUNASUSER", "FSGROUP", "SUPGROUP", "PRIORITY"} // addDefaultHandlers adds print handlers for default Kubernetes types. func (h *HumanReadablePrinter) addDefaultHandlers() { @@ -1766,8 +1766,8 @@ func printSecurityContextConstraints(item *api.SecurityContextConstraints, w io. priority = strconv.Itoa(*item.Priority) } - _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%s\t%s\t%s\t%s\t%s\n", item.Name, item.AllowPrivilegedContainer, - item.AllowedCapabilities, item.AllowHostDirVolumePlugin, item.SELinuxContext.Type, + _, err := fmt.Fprintf(w, "%s\t%t\t%v\t%t\t%t\t%s\t%s\t%s\t%s\t%s\n", item.Name, item.AllowPrivilegedContainer, + item.AllowedCapabilities, item.AllowHostDirVolumePlugin, item.AllowEmptyDirVolumePlugin, item.SELinuxContext.Type, item.RunAsUser.Type, item.FSGroup.Type, item.SupplementalGroups.Type, priority) return err } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go index 813c0aad9236..aafeae5b5243 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider.go @@ -243,10 +243,17 @@ func (s *simpleProvider) ValidateContainerSecurityContext(pod *api.Pod, containe allErrs = append(allErrs, s.capabilitiesStrategy.Validate(pod, container)...) - if !s.scc.AllowHostDirVolumePlugin { - for _, v := range pod.Spec.Volumes { - if v.HostPath != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("volumeMounts"), v.Name, "Host Volumes are not allowed to be used")) + if !s.scc.AllowHostDirVolumePlugin || !s.scc.AllowEmptyDirVolumePlugin { + for i, v := range pod.Spec.Volumes { + if !s.scc.AllowHostDirVolumePlugin && v.HostPath != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("volumes").Index(i), "hostPath", + "HostPath volumes are not allowed to be used")) + } + if !s.scc.AllowEmptyDirVolumePlugin && v.EmptyDir != nil { + allErrs = append(allErrs, field.Invalid( + fldPath.Child("volumes").Index(i), "emptyDir", + "EmptyDir volumes are not allowed to be used")) } } } diff --git a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go index 145e76bd8c78..75793ddfce77 100644 --- a/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go +++ b/Godeps/_workspace/src/k8s.io/kubernetes/pkg/securitycontextconstraints/provider_test.go @@ -313,6 +313,19 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) { }, } + failEmptyDirSCC := defaultSCC() + failEmptyDirSCC.AllowEmptyDirVolumePlugin = false + + failEmptyDirPod := defaultPod() + failEmptyDirPod.Spec.Volumes = []api.Volume{ + { + Name: "bad emptyDir volume", + VolumeSource: api.VolumeSource{ + EmptyDir: &api.EmptyDirVolumeSource{}, + }, + }, + } + failHostPortPod := defaultPod() failHostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} @@ -344,7 +357,12 @@ func TestValidateContainerSecurityContextFailures(t *testing.T) { "failHostDirSCC": { pod: failHostDirPod, scc: defaultSCC(), - expectedError: "Host Volumes are not allowed to be used", + expectedError: "HostPath volumes are not allowed to be used", + }, + "failEmptyDirSCC": { + pod: failEmptyDirPod, + scc: failEmptyDirSCC, + expectedError: "EmptyDir volumes are not allowed to be used", }, "failHostPortSCC": { pod: failHostPortPod, @@ -545,6 +563,18 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) { hostPortPod := defaultPod() hostPortPod.Spec.Containers[0].Ports = []api.ContainerPort{{HostPort: 1}} + allowEmptyDirSCC := defaultSCC() + allowEmptyDirSCC.AllowEmptyDirVolumePlugin = true + emptyDirPod := defaultPod() + emptyDirPod.Spec.Volumes = []api.Volume{ + { + Name: "emptyDir volume", + VolumeSource: api.VolumeSource{ + EmptyDir: &api.EmptyDirVolumeSource{}, + }, + }, + } + errorCases := map[string]struct { pod *api.Pod scc *api.SecurityContextConstraints @@ -577,6 +607,10 @@ func TestValidateContainerSecurityContextSuccess(t *testing.T) { pod: hostPortPod, scc: hostPortSCC, }, + "pass allowEmptyDir SCC": { + pod: emptyDirPod, + scc: allowEmptyDirSCC, + }, } for k, v := range errorCases { From b6f497d685a40591b9c75954f90058273489970a Mon Sep 17 00:00:00 2001 From: Devan Goodwin Date: Thu, 21 Jan 2016 09:51:59 -0400 Subject: [PATCH 3/3] Updates to use the SCC allowEmptyDirVolumePlugin setting. --- api/swagger-spec/api-v1.json | 5 ++++ .../proposals/security-context-constraints.md | 2 ++ .../securitycontextconstraints.go | 30 +++++++++++-------- 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/api/swagger-spec/api-v1.json b/api/swagger-spec/api-v1.json index c34a6622fcab..b6c0b2196be6 100644 --- a/api/swagger-spec/api-v1.json +++ b/api/swagger-spec/api-v1.json @@ -16763,6 +16763,7 @@ "requiredDropCapabilities", "allowedCapabilities", "allowHostDirVolumePlugin", + "allowEmptyDirVolumePlugin", "allowHostNetwork", "allowHostPorts", "allowHostPID", @@ -16814,6 +16815,10 @@ "type": "boolean", "description": "AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin" }, + "allowEmptyDirVolumePlugin": { + "type": "boolean", + "description": "allow the use of the empty dir volume plugin; defaults to true" + }, "allowHostNetwork": { "type": "boolean", "description": "AllowHostNetwork determines if the policy allows the use of HostNetwork in the pod spec." diff --git a/docs/proposals/security-context-constraints.md b/docs/proposals/security-context-constraints.md index f8b1548e9eb0..497b7d08f565 100644 --- a/docs/proposals/security-context-constraints.md +++ b/docs/proposals/security-context-constraints.md @@ -90,6 +90,8 @@ type SecurityContextConstraints struct { AllowedCapabilities []CapabilityType `json:"allowedCapabilities,omitempty" description:"capabilities that are allowed to be added"` // AllowHostDirVolumePlugin determines if the policy allow containers to use the HostDir volume plugin AllowHostDirVolumePlugin bool `json:"allowHostDirVolumePlugin,omitempty" description:"allow the use of the host dir volume plugin"` + // AllowEmptyDirVolumePlugin determines if the policy allow containers to use the EmptyDir volume plugin + AllowEmptyDirVolumePlugin bool `json:"allowEmptyDirVolumePlugin,omitempty" description:"allow the use of the empty dir volume plugin"` // SELinuxContext is the strategy that will dictate what labels will be set in the SecurityContext. SELinuxContext SELinuxContextStrategyOptions `json:"seLinuxContext,omitempty" description:"strategy used to generate SELinuxOptions"` // RunAsUser is the strategy that will dictate what RunAsUser is used in the SecurityContext. diff --git a/pkg/cmd/server/bootstrappolicy/securitycontextconstraints.go b/pkg/cmd/server/bootstrappolicy/securitycontextconstraints.go index b861d98c76cd..a07a1b4a4632 100644 --- a/pkg/cmd/server/bootstrappolicy/securitycontextconstraints.go +++ b/pkg/cmd/server/bootstrappolicy/securitycontextconstraints.go @@ -57,12 +57,13 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintPrivilegedDesc, }, }, - AllowPrivilegedContainer: true, - AllowHostDirVolumePlugin: true, - AllowHostNetwork: true, - AllowHostPorts: true, - AllowHostPID: true, - AllowHostIPC: true, + AllowPrivilegedContainer: true, + AllowHostDirVolumePlugin: true, + AllowEmptyDirVolumePlugin: true, + AllowHostNetwork: true, + AllowHostPorts: true, + AllowHostPID: true, + AllowHostIPC: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ Type: kapi.SELinuxStrategyRunAsAny, }, @@ -85,6 +86,7 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintNonRootDesc, }, }, + AllowEmptyDirVolumePlugin: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy @@ -112,7 +114,8 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintHostMountAndAnyUIDDesc, }, }, - AllowHostDirVolumePlugin: true, + AllowHostDirVolumePlugin: true, + AllowEmptyDirVolumePlugin: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy @@ -141,11 +144,12 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintHostNSDesc, }, }, - AllowHostDirVolumePlugin: true, - AllowHostNetwork: true, - AllowHostPorts: true, - AllowHostPID: true, - AllowHostIPC: true, + AllowHostDirVolumePlugin: true, + AllowEmptyDirVolumePlugin: true, + AllowHostNetwork: true, + AllowHostPorts: true, + AllowHostPID: true, + AllowHostIPC: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy @@ -173,6 +177,7 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintRestrictedDesc, }, }, + AllowEmptyDirVolumePlugin: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy @@ -202,6 +207,7 @@ func GetBootstrapSecurityContextConstraints(sccNameToAdditionalGroups map[string DescriptionAnnotation: SecurityContextConstraintsAnyUIDDesc, }, }, + AllowEmptyDirVolumePlugin: true, SELinuxContext: kapi.SELinuxContextStrategyOptions{ // This strategy requires that annotations on the namespace which will be populated // by the admission controller. If namespaces are not annotated creating the strategy