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/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. 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 { 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