mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Merge pull request #13939 from pmorie/pod-sc-minimal
Add PodSecurityContext and backward compatibility tests
This commit is contained in:
commit
87fe1f4af8
@ -12646,6 +12646,10 @@
|
||||
"type": "boolean",
|
||||
"description": "Use the host's ipc namespace. Optional: Default to false."
|
||||
},
|
||||
"securityContext": {
|
||||
"$ref": "v1.PodSecurityContext",
|
||||
"description": "SecurityContext holds pod-level security attributes and common container settings"
|
||||
},
|
||||
"imagePullSecrets": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
@ -13201,6 +13205,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"v1.PodSecurityContext": {
|
||||
"id": "v1.PodSecurityContext",
|
||||
"description": "PodSecurityContext holds pod-level security attributes and common container settings.",
|
||||
"properties": {}
|
||||
},
|
||||
"v1.PodStatus": {
|
||||
"id": "v1.PodStatus",
|
||||
"description": "PodStatus represents information about the status of a pod. Status may trail the actual state of a system.",
|
||||
|
@ -24,6 +24,9 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/google/gofuzz"
|
||||
)
|
||||
|
||||
func TestDeepCopyApiObjects(t *testing.T) {
|
||||
@ -31,21 +34,34 @@ func TestDeepCopyApiObjects(t *testing.T) {
|
||||
for _, version := range []string{"", testapi.Default.Version()} {
|
||||
f := apitesting.FuzzerFor(t, version, rand.NewSource(rand.Int63()))
|
||||
for kind := range api.Scheme.KnownTypes(version) {
|
||||
item, err := api.Scheme.New(version, kind)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not create a %s: %s", kind, err)
|
||||
}
|
||||
f.Fuzz(item)
|
||||
itemCopy, err := api.Scheme.DeepCopy(item)
|
||||
if err != nil {
|
||||
t.Errorf("Could not deep copy a %s: %s", kind, err)
|
||||
continue
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(item, itemCopy) {
|
||||
t.Errorf("\nexpected %#v\ngot %#v", item, itemCopy)
|
||||
}
|
||||
doDeepCopyTest(t, version, kind, f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doDeepCopyTest(t *testing.T, version, kind string, f *fuzz.Fuzzer) {
|
||||
item, err := api.Scheme.New(version, kind)
|
||||
if err != nil {
|
||||
t.Fatalf("Could not create a %s: %s", kind, err)
|
||||
}
|
||||
f.Fuzz(item)
|
||||
itemCopy, err := api.Scheme.DeepCopy(item)
|
||||
if err != nil {
|
||||
t.Errorf("Could not deep copy a %s: %s", kind, err)
|
||||
return
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(item, itemCopy) {
|
||||
t.Errorf("\nexpected: %#v\n\ngot: %#v\n\ndiff: %v", item, itemCopy, util.ObjectDiff(item, itemCopy))
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeepCopySingleType(t *testing.T) {
|
||||
for i := 0; i < *fuzzIters; i++ {
|
||||
for _, version := range []string{"", testapi.Default.Version()} {
|
||||
f := apitesting.FuzzerFor(t, version, rand.NewSource(rand.Int63()))
|
||||
doDeepCopyTest(t, version, "Pod", f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1481,6 +1481,13 @@ func deepCopy_api_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *c
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_PodSecurityContext(in PodSecurityContext, out *PodSecurityContext, c *conversion.Cloner) error {
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error {
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]Volume, len(in.Volumes))
|
||||
@ -1526,9 +1533,14 @@ func deepCopy_api_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error
|
||||
}
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(PodSecurityContext)
|
||||
if err := deepCopy_api_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -2380,6 +2392,7 @@ func init() {
|
||||
deepCopy_api_PodList,
|
||||
deepCopy_api_PodLogOptions,
|
||||
deepCopy_api_PodProxyOptions,
|
||||
deepCopy_api_PodSecurityContext,
|
||||
deepCopy_api_PodSpec,
|
||||
deepCopy_api_PodStatus,
|
||||
deepCopy_api_PodStatusResult,
|
||||
|
@ -108,7 +108,7 @@ func TestSpecificKind(t *testing.T) {
|
||||
api.Scheme.Log(t)
|
||||
defer api.Scheme.Log(nil)
|
||||
|
||||
kind := "PodList"
|
||||
kind := "Pod"
|
||||
doRoundTripTest(kind, t)
|
||||
}
|
||||
|
||||
@ -169,6 +169,8 @@ func TestEncode_Ptr(t *testing.T) {
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
obj := runtime.Object(pod)
|
||||
@ -181,7 +183,8 @@ func TestEncode_Ptr(t *testing.T) {
|
||||
t.Fatalf("Got wrong type")
|
||||
}
|
||||
if !api.Semantic.DeepEqual(obj2, pod) {
|
||||
t.Errorf("Expected:\n %#v,\n Got:\n %#v", pod, obj2)
|
||||
t.Errorf("\nExpected:\n\n %#v,\n\nGot:\n\n %#vDiff: %v\n\n", pod, obj2, util.ObjectDiff(obj2, pod))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
144
pkg/api/testing/compat/compatibility_tester.go
Normal file
144
pkg/api/testing/compat/compatibility_tester.go
Normal file
@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package compat
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/fielderrors"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
)
|
||||
|
||||
// Based on: https://github.com/openshift/origin/blob/master/pkg/api/compatibility_test.go
|
||||
//
|
||||
// TestCompatibility reencodes the input using the codec for the given
|
||||
// version and checks for the presence of the expected keys and absent
|
||||
// keys in the resulting JSON.
|
||||
func TestCompatibility(
|
||||
t *testing.T,
|
||||
version string,
|
||||
input []byte,
|
||||
validator func(obj runtime.Object) fielderrors.ValidationErrorList,
|
||||
expectedKeys map[string]string,
|
||||
absentKeys []string,
|
||||
) {
|
||||
|
||||
// Decode
|
||||
codec := runtime.CodecFor(api.Scheme, version)
|
||||
obj, err := codec.Decode(input)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// Validate
|
||||
errs := validator(obj)
|
||||
if len(errs) != 0 {
|
||||
t.Fatalf("Unexpected validation errors: %v", errs)
|
||||
}
|
||||
|
||||
// Encode
|
||||
output, err := codec.Encode(obj)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// Validate old and new fields are encoded
|
||||
generic := map[string]interface{}{}
|
||||
if err := json.Unmarshal(output, &generic); err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
hasError := false
|
||||
for k, expectedValue := range expectedKeys {
|
||||
keys := strings.Split(k, ".")
|
||||
if actualValue, ok, err := getJSONValue(generic, keys...); err != nil || !ok {
|
||||
t.Errorf("Unexpected error for %s: %v", k, err)
|
||||
hasError = true
|
||||
} else if !reflect.DeepEqual(expectedValue, fmt.Sprintf("%v", actualValue)) {
|
||||
hasError = true
|
||||
t.Errorf("Unexpected value for %v: expected %v, got %v", k, expectedValue, actualValue)
|
||||
}
|
||||
}
|
||||
|
||||
for _, absentKey := range absentKeys {
|
||||
keys := strings.Split(absentKey, ".")
|
||||
actualValue, ok, err := getJSONValue(generic, keys...)
|
||||
if err == nil || ok {
|
||||
t.Errorf("Unexpected value found for for key %s: %v", absentKey, actualValue)
|
||||
hasError = true
|
||||
}
|
||||
}
|
||||
|
||||
if hasError {
|
||||
printer := new(kubectl.JSONPrinter)
|
||||
printer.PrintObj(obj, os.Stdout)
|
||||
t.Logf("2: Encoded value: %#v", string(output))
|
||||
}
|
||||
}
|
||||
|
||||
func getJSONValue(data map[string]interface{}, keys ...string) (interface{}, bool, error) {
|
||||
// No keys, current value is it
|
||||
if len(keys) == 0 {
|
||||
return data, true, nil
|
||||
}
|
||||
|
||||
// Get the key (and optional index)
|
||||
key := keys[0]
|
||||
index := -1
|
||||
if matches := regexp.MustCompile(`^(.*)\[(\d+)\]$`).FindStringSubmatch(key); len(matches) > 0 {
|
||||
key = matches[1]
|
||||
index, _ = strconv.Atoi(matches[2])
|
||||
}
|
||||
|
||||
// Look up the value
|
||||
value, ok := data[key]
|
||||
if !ok {
|
||||
return nil, false, fmt.Errorf("No key %s found", key)
|
||||
}
|
||||
|
||||
// Get the indexed value if an index is specified
|
||||
if index >= 0 {
|
||||
valueSlice, ok := value.([]interface{})
|
||||
if !ok {
|
||||
return nil, false, fmt.Errorf("Key %s did not hold a slice", key)
|
||||
}
|
||||
if index >= len(valueSlice) {
|
||||
return nil, false, fmt.Errorf("Index %d out of bounds for slice at key: %v", index, key)
|
||||
}
|
||||
value = valueSlice[index]
|
||||
}
|
||||
|
||||
if len(keys) == 1 {
|
||||
return value, true, nil
|
||||
}
|
||||
|
||||
childData, ok := value.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, false, fmt.Errorf("Key %s did not hold a map", keys[0])
|
||||
}
|
||||
return getJSONValue(childData, keys[1:]...)
|
||||
}
|
@ -92,14 +92,18 @@ func FuzzerFor(t *testing.T, version string, src rand.Source) *fuzz.Fuzzer {
|
||||
j.LabelSelector, _ = labels.Parse("a=b")
|
||||
j.FieldSelector, _ = fields.ParseSelector("a=b")
|
||||
},
|
||||
func(j *api.PodSpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(j)
|
||||
func(s *api.PodSpec, c fuzz.Continue) {
|
||||
c.FuzzNoCustom(s)
|
||||
// has a default value
|
||||
ttl := int64(30)
|
||||
if c.RandBool() {
|
||||
ttl = int64(c.Uint32())
|
||||
}
|
||||
j.TerminationGracePeriodSeconds = &ttl
|
||||
s.TerminationGracePeriodSeconds = &ttl
|
||||
|
||||
if s.SecurityContext == nil {
|
||||
s.SecurityContext = &api.PodSecurityContext{}
|
||||
}
|
||||
},
|
||||
func(j *api.PodPhase, c fuzz.Continue) {
|
||||
statuses := []api.PodPhase{api.PodPending, api.PodRunning, api.PodFailed, api.PodUnknown}
|
||||
|
32
pkg/api/testing/pod_specs.go
Normal file
32
pkg/api/testing/pod_specs.go
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package testing
|
||||
|
||||
import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// DeepEqualSafePodSpec returns a PodSpec which is ready to be used with api.Semantic.DeepEqual
|
||||
func DeepEqualSafePodSpec() api.PodSpec {
|
||||
grace := int64(30)
|
||||
return api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
}
|
||||
}
|
@ -986,20 +986,27 @@ type PodSpec struct {
|
||||
// the scheduler simply schedules this pod onto that node, assuming that it fits resource
|
||||
// requirements.
|
||||
NodeName string `json:"nodeName,omitempty"`
|
||||
// Use the host's network namespace. If this option is set, the ports that will be
|
||||
// SecurityContext holds pod-level security attributes and common container settings
|
||||
SecurityContext *PodSecurityContext `json:"securityContext,omitempty"`
|
||||
// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
||||
// If specified, these secrets will be passed to individual puller implementations for them to use. For example,
|
||||
// in the case of docker, only DockerConfig type secrets are honored.
|
||||
ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"`
|
||||
}
|
||||
|
||||
// PodSecurityContext holds pod-level security attributes and common container settings.
|
||||
type PodSecurityContext struct {
|
||||
// Use the host's network namespace. If this option is set, the ports that will be
|
||||
// used must be specified.
|
||||
// Optional: Default to false.
|
||||
// Optional: Default to false
|
||||
HostNetwork bool `json:"hostNetwork,omitempty"`
|
||||
|
||||
// Use the host's pid namespace.
|
||||
// Optional: Default to false.
|
||||
HostPID bool `json:"hostPID,omitempty"`
|
||||
// Use the host's ipc namespace.
|
||||
// Optional: Default to false.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
||||
// If specified, these secrets will be passed to individual puller implementations for them to use. For example,
|
||||
// in the case of docker, only DockerConfig type secrets are honored.
|
||||
ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"`
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
|
166
pkg/api/v1/backward_compatibility_test.go
Normal file
166
pkg/api/v1/backward_compatibility_test.go
Normal file
@ -0,0 +1,166 @@
|
||||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testing/compat"
|
||||
"k8s.io/kubernetes/pkg/api/validation"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/fielderrors"
|
||||
)
|
||||
|
||||
func TestCompatibility_v1_PodSecurityContext(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
input string
|
||||
expectedKeys map[string]string
|
||||
absentKeys []string
|
||||
}{
|
||||
{
|
||||
name: "hostNetwork = true",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostNetwork": true,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
expectedKeys: map[string]string{
|
||||
"spec.hostNetwork": "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hostNetwork = false",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostNetwork": false,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
absentKeys: []string{
|
||||
"spec.hostNetwork",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hostIPC = true",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostIPC": true,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
expectedKeys: map[string]string{
|
||||
"spec.hostIPC": "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hostIPC = false",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostIPC": false,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
absentKeys: []string{
|
||||
"spec.hostIPC",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hostPID = true",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostPID": true,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
expectedKeys: map[string]string{
|
||||
"spec.hostPID": "true",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "hostPID = false",
|
||||
input: `
|
||||
{
|
||||
"kind":"Pod",
|
||||
"apiVersion":"v1",
|
||||
"metadata":{"name":"my-pod-name", "namespace":"my-pod-namespace"},
|
||||
"spec": {
|
||||
"hostPID": false,
|
||||
"containers":[{
|
||||
"name":"a",
|
||||
"image":"my-container-image"
|
||||
}]
|
||||
}
|
||||
}
|
||||
`,
|
||||
absentKeys: []string{
|
||||
"spec.hostPID",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
validator := func(obj runtime.Object) fielderrors.ValidationErrorList {
|
||||
return validation.ValidatePodSpec(&(obj.(*api.Pod).Spec))
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Logf("Testing 1.0.0 backward compatibility for %v", tc.name)
|
||||
compat.TestCompatibility(t, "v1", []byte(tc.input), validator, tc.expectedKeys, tc.absentKeys)
|
||||
}
|
||||
}
|
@ -283,9 +283,16 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conversi
|
||||
// DeprecatedServiceAccount is an alias for ServiceAccountName.
|
||||
out.DeprecatedServiceAccount = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(PodSecurityContext)
|
||||
if err := convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.HostPID = in.SecurityContext.HostPID
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -352,9 +359,18 @@ func convert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conversi
|
||||
out.ServiceAccountName = in.DeprecatedServiceAccount
|
||||
}
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
if err := convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if out.SecurityContext == nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
}
|
||||
out.SecurityContext.HostNetwork = in.HostNetwork
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -392,3 +408,17 @@ func convert_v1_ServiceSpec_To_api_ServiceSpec(in *ServiceSpec, out *api.Service
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *PodSecurityContext, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.PodSecurityContext))(in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*PodSecurityContext))(in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -2084,9 +2084,13 @@ func autoconvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *PodSpec, s conv
|
||||
}
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -5094,9 +5098,16 @@ func autoconvert_v1_PodSpec_To_api_PodSpec(in *PodSpec, out *api.PodSpec, s conv
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
// in.DeprecatedServiceAccount has no peer in out
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
// in.HostNetwork has no peer in out
|
||||
// in.HostPID has no peer in out
|
||||
// in.HostIPC has no peer in out
|
||||
if in.SecurityContext != nil {
|
||||
if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
|
@ -1501,6 +1501,10 @@ func deepCopy_v1_PodProxyOptions(in PodProxyOptions, out *PodProxyOptions, c *co
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_PodSecurityContext(in PodSecurityContext, out *PodSecurityContext, c *conversion.Cloner) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error {
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]Volume, len(in.Volumes))
|
||||
@ -1550,6 +1554,14 @@ func deepCopy_v1_PodSpec(in PodSpec, out *PodSpec, c *conversion.Cloner) error {
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(PodSecurityContext)
|
||||
if err := deepCopy_v1_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -2393,6 +2405,7 @@ func init() {
|
||||
deepCopy_v1_PodList,
|
||||
deepCopy_v1_PodLogOptions,
|
||||
deepCopy_v1_PodProxyOptions,
|
||||
deepCopy_v1_PodSecurityContext,
|
||||
deepCopy_v1_PodSpec,
|
||||
deepCopy_v1_PodStatus,
|
||||
deepCopy_v1_PodStatusResult,
|
||||
|
@ -116,6 +116,9 @@ func addDefaultingFuncs() {
|
||||
if obj.HostNetwork {
|
||||
defaultHostNetworkPorts(&obj.Containers)
|
||||
}
|
||||
if obj.SecurityContext == nil {
|
||||
obj.SecurityContext = &PodSecurityContext{}
|
||||
}
|
||||
if obj.TerminationGracePeriodSeconds == nil {
|
||||
period := int64(DefaultTerminationGracePeriodSeconds)
|
||||
obj.TerminationGracePeriodSeconds = &period
|
||||
|
@ -1238,6 +1238,8 @@ type PodSpec struct {
|
||||
// Use the host's ipc namespace.
|
||||
// Optional: Default to false.
|
||||
HostIPC bool `json:"hostIPC,omitempty"`
|
||||
// SecurityContext holds pod-level security attributes and common container settings
|
||||
SecurityContext *PodSecurityContext `json:"securityContext,omitempty"`
|
||||
// ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec.
|
||||
// If specified, these secrets will be passed to individual puller implementations for them to use. For example,
|
||||
// in the case of docker, only DockerConfig type secrets are honored.
|
||||
@ -1245,6 +1247,10 @@ type PodSpec struct {
|
||||
ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty" patchStrategy:"merge" patchMergeKey:"name"`
|
||||
}
|
||||
|
||||
// PodSecurityContext holds pod-level security attributes and common container settings.
|
||||
type PodSecurityContext struct {
|
||||
}
|
||||
|
||||
// PodStatus represents information about the status of a pod. Status may trail the actual
|
||||
// state of a system.
|
||||
type PodStatus struct {
|
||||
|
@ -973,6 +973,14 @@ func (PodProxyOptions) SwaggerDoc() map[string]string {
|
||||
return map_PodProxyOptions
|
||||
}
|
||||
|
||||
var map_PodSecurityContext = map[string]string{
|
||||
"": "PodSecurityContext holds pod-level security attributes and common container settings.",
|
||||
}
|
||||
|
||||
func (PodSecurityContext) SwaggerDoc() map[string]string {
|
||||
return map_PodSecurityContext
|
||||
}
|
||||
|
||||
var map_PodSpec = map[string]string{
|
||||
"": "PodSpec is a description of a pod.",
|
||||
"volumes": "List of volumes that can be mounted by containers belonging to the pod. More info: http://releases.k8s.io/HEAD/docs/user-guide/volumes.md",
|
||||
@ -988,6 +996,7 @@ var map_PodSpec = map[string]string{
|
||||
"hostNetwork": "Host networking requested for this pod. Use the host's network namespace. If this option is set, the ports that will be used must be specified. Default to false.",
|
||||
"hostPID": "Use the host's pid namespace. Optional: Default to false.",
|
||||
"hostIPC": "Use the host's ipc namespace. Optional: Default to false.",
|
||||
"securityContext": "SecurityContext holds pod-level security attributes and common container settings",
|
||||
"imagePullSecrets": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: http://releases.k8s.io/HEAD/docs/user-guide/images.md#specifying-imagepullsecrets-on-a-pod",
|
||||
}
|
||||
|
||||
|
@ -1107,7 +1107,7 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList {
|
||||
allErrs = append(allErrs, validateRestartPolicy(&spec.RestartPolicy).Prefix("restartPolicy")...)
|
||||
allErrs = append(allErrs, validateDNSPolicy(&spec.DNSPolicy).Prefix("dnsPolicy")...)
|
||||
allErrs = append(allErrs, ValidateLabels(spec.NodeSelector, "nodeSelector")...)
|
||||
allErrs = append(allErrs, validateHostNetwork(spec.HostNetwork, spec.Containers).Prefix("hostNetwork")...)
|
||||
allErrs = append(allErrs, ValidatePodSecurityContext(spec.SecurityContext, spec).Prefix("securityContext")...)
|
||||
allErrs = append(allErrs, validateImagePullSecrets(spec.ImagePullSecrets).Prefix("imagePullSecrets")...)
|
||||
if len(spec.ServiceAccountName) > 0 {
|
||||
if ok, msg := ValidateServiceAccountName(spec.ServiceAccountName, false); !ok {
|
||||
@ -1123,6 +1123,17 @@ func ValidatePodSpec(spec *api.PodSpec) errs.ValidationErrorList {
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodSecurityContext test that the specified PodSecurityContext has valid data.
|
||||
func ValidatePodSecurityContext(securityContext *api.PodSecurityContext, spec *api.PodSpec) errs.ValidationErrorList {
|
||||
allErrs := errs.ValidationErrorList{}
|
||||
|
||||
if securityContext != nil {
|
||||
allErrs = append(allErrs, validateHostNetwork(securityContext.HostNetwork, spec.Containers).Prefix("hostNetwork")...)
|
||||
}
|
||||
|
||||
return allErrs
|
||||
}
|
||||
|
||||
// ValidatePodUpdate tests to see if the update is legal for an end user to make. newPod is updated with fields
|
||||
// that cannot be changed.
|
||||
func ValidatePodUpdate(newPod, oldPod *api.Pod) errs.ValidationErrorList {
|
||||
|
@ -1259,20 +1259,25 @@ func TestValidatePodSpec(t *testing.T) {
|
||||
{HostPort: 8080, ContainerPort: 8080, Protocol: "TCP"}},
|
||||
},
|
||||
},
|
||||
HostNetwork: true,
|
||||
HostIPC: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
{ // Populate HostIPC.
|
||||
HostIPC: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostIPC: true,
|
||||
},
|
||||
Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
{ // Populate HostPID.
|
||||
HostPID: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostPID: true,
|
||||
},
|
||||
Volumes: []api.Volume{{Name: "vol", VolumeSource: api.VolumeSource{EmptyDir: &api.EmptyDirVolumeSource{}}}},
|
||||
Containers: []api.Container{{Name: "ctr", Image: "image", ImagePullPolicy: "IfNotPresent"}},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
@ -1324,7 +1329,9 @@ func TestValidatePodSpec(t *testing.T) {
|
||||
{HostPort: 8080, ContainerPort: 2600, Protocol: "TCP"}},
|
||||
},
|
||||
},
|
||||
HostNetwork: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
},
|
||||
|
@ -459,6 +459,13 @@ func deepCopy_api_PersistentVolumeClaimVolumeSource(in api.PersistentVolumeClaim
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_PodSecurityContext(in api.PodSecurityContext, out *api.PodSecurityContext, c *conversion.Cloner) error {
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_api_PodSpec(in api.PodSpec, out *api.PodSpec, c *conversion.Cloner) error {
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]api.Volume, len(in.Volumes))
|
||||
@ -504,9 +511,14 @@ func deepCopy_api_PodSpec(in api.PodSpec, out *api.PodSpec, c *conversion.Cloner
|
||||
}
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
if err := deepCopy_api_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -1525,6 +1537,7 @@ func init() {
|
||||
deepCopy_api_ObjectFieldSelector,
|
||||
deepCopy_api_ObjectMeta,
|
||||
deepCopy_api_PersistentVolumeClaimVolumeSource,
|
||||
deepCopy_api_PodSecurityContext,
|
||||
deepCopy_api_PodSpec,
|
||||
deepCopy_api_PodTemplateSpec,
|
||||
deepCopy_api_Probe,
|
||||
|
@ -97,9 +97,16 @@ func convert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s conve
|
||||
// DeprecatedServiceAccount is an alias for ServiceAccountName.
|
||||
out.DeprecatedServiceAccount = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(v1.PodSecurityContext)
|
||||
if err := convert_api_PodSecurityContext_To_v1_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
out.HostNetwork = in.SecurityContext.HostNetwork
|
||||
out.HostPID = in.SecurityContext.HostPID
|
||||
out.HostIPC = in.SecurityContext.HostIPC
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -166,9 +173,19 @@ func convert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s conve
|
||||
out.ServiceAccountName = in.DeprecatedServiceAccount
|
||||
}
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
if err := convert_v1_PodSecurityContext_To_api_PodSecurityContext(in.SecurityContext, out.SecurityContext, s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if out.SecurityContext == nil {
|
||||
out.SecurityContext = new(api.PodSecurityContext)
|
||||
}
|
||||
out.SecurityContext.HostNetwork = in.HostNetwork
|
||||
out.SecurityContext.HostPID = in.HostPID
|
||||
out.SecurityContext.HostIPC = in.HostIPC
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -309,3 +326,17 @@ func convert_v1alpha1_RollingUpdateDeployment_To_experimental_RollingUpdateDeplo
|
||||
out.MinReadySeconds = in.MinReadySeconds
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_api_PodSecurityContext_To_v1_PodSecurityContext(in *api.PodSecurityContext, out *v1.PodSecurityContext, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*api.PodSecurityContext))(in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func convert_v1_PodSecurityContext_To_api_PodSecurityContext(in *v1.PodSecurityContext, out *api.PodSecurityContext, s conversion.Scope) error {
|
||||
if defaulting, found := s.DefaultingInterface(reflect.TypeOf(*in)); found {
|
||||
defaulting.(func(*v1.PodSecurityContext))(in)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -708,9 +708,13 @@ func autoconvert_api_PodSpec_To_v1_PodSpec(in *api.PodSpec, out *v1.PodSpec, s c
|
||||
}
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -1755,9 +1759,16 @@ func autoconvert_v1_PodSpec_To_api_PodSpec(in *v1.PodSpec, out *api.PodSpec, s c
|
||||
out.ServiceAccountName = in.ServiceAccountName
|
||||
// in.DeprecatedServiceAccount has no peer in out
|
||||
out.NodeName = in.NodeName
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
// in.HostNetwork has no peer in out
|
||||
// in.HostPID has no peer in out
|
||||
// in.HostIPC has no peer in out
|
||||
if in.SecurityContext != nil {
|
||||
if err := s.Convert(&in.SecurityContext, &out.SecurityContext, 0); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]api.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
|
@ -497,6 +497,10 @@ func deepCopy_v1_PersistentVolumeClaimVolumeSource(in v1.PersistentVolumeClaimVo
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_PodSecurityContext(in v1.PodSecurityContext, out *v1.PodSecurityContext, c *conversion.Cloner) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func deepCopy_v1_PodSpec(in v1.PodSpec, out *v1.PodSpec, c *conversion.Cloner) error {
|
||||
if in.Volumes != nil {
|
||||
out.Volumes = make([]v1.Volume, len(in.Volumes))
|
||||
@ -546,6 +550,14 @@ func deepCopy_v1_PodSpec(in v1.PodSpec, out *v1.PodSpec, c *conversion.Cloner) e
|
||||
out.HostNetwork = in.HostNetwork
|
||||
out.HostPID = in.HostPID
|
||||
out.HostIPC = in.HostIPC
|
||||
if in.SecurityContext != nil {
|
||||
out.SecurityContext = new(v1.PodSecurityContext)
|
||||
if err := deepCopy_v1_PodSecurityContext(*in.SecurityContext, out.SecurityContext, c); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
out.SecurityContext = nil
|
||||
}
|
||||
if in.ImagePullSecrets != nil {
|
||||
out.ImagePullSecrets = make([]v1.LocalObjectReference, len(in.ImagePullSecrets))
|
||||
for i := range in.ImagePullSecrets {
|
||||
@ -1551,6 +1563,7 @@ func init() {
|
||||
deepCopy_v1_ObjectFieldSelector,
|
||||
deepCopy_v1_ObjectMeta,
|
||||
deepCopy_v1_PersistentVolumeClaimVolumeSource,
|
||||
deepCopy_v1_PodSecurityContext,
|
||||
deepCopy_v1_PodSpec,
|
||||
deepCopy_v1_PodTemplateSpec,
|
||||
deepCopy_v1_Probe,
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
@ -39,7 +40,6 @@ import (
|
||||
)
|
||||
|
||||
func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList) {
|
||||
grace := int64(30)
|
||||
pods := &api.PodList{
|
||||
ListMeta: unversioned.ListMeta{
|
||||
ResourceVersion: "15",
|
||||
@ -47,19 +47,11 @@ func testData() (*api.PodList, *api.ServiceList, *api.ReplicationControllerList)
|
||||
Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -567,7 +559,6 @@ func TestGetMultipleTypeObjectsWithDirectReference(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func watchTestData() ([]api.Pod, []watch.Event) {
|
||||
grace := int64(30)
|
||||
pods := []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
@ -575,11 +566,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
||||
Namespace: "test",
|
||||
ResourceVersion: "10",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
}
|
||||
events := []watch.Event{
|
||||
@ -591,11 +578,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
||||
Namespace: "test",
|
||||
ResourceVersion: "11",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -606,11 +589,7 @@ func watchTestData() ([]api.Pod, []watch.Event) {
|
||||
Namespace: "test",
|
||||
ResourceVersion: "12",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -652,7 +631,7 @@ func TestWatchSelector(t *testing.T) {
|
||||
expected := []runtime.Object{&api.PodList{Items: pods}, events[0].Object, events[1].Object}
|
||||
actual := tf.Printer.(*testPrinter).Objects
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Errorf("unexpected object: %#v %#v", expected[0], actual[0])
|
||||
t.Errorf("unexpected object:\nExpected: %#v\n\nGot: %#v\n\n", expected[0], actual[0])
|
||||
}
|
||||
if len(buf.String()) == 0 {
|
||||
t.Errorf("unexpected empty output")
|
||||
@ -690,7 +669,7 @@ func TestWatchResource(t *testing.T) {
|
||||
expected := []runtime.Object{&pods[0], events[0].Object, events[1].Object}
|
||||
actual := tf.Printer.(*testPrinter).Objects
|
||||
if !reflect.DeepEqual(expected, actual) {
|
||||
t.Errorf("unexpected object: %#v", actual)
|
||||
t.Errorf("unexpected object:\nExpected: %#v\n\nGot: %#v\n\n", expected, actual)
|
||||
}
|
||||
if len(buf.String()) == 0 {
|
||||
t.Errorf("unexpected empty output")
|
||||
|
@ -29,6 +29,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/util/fielderrors"
|
||||
)
|
||||
@ -54,11 +55,7 @@ func TestMerge(t *testing.T) {
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
/* TODO: uncomment this test once Merge is updated to use
|
||||
@ -127,6 +124,7 @@ func TestMerge(t *testing.T) {
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -32,6 +32,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -83,7 +84,6 @@ func fakeClientWith(testName string, t *testing.T, data map[string]string) Clien
|
||||
}
|
||||
|
||||
func testData() (*api.PodList, *api.ServiceList) {
|
||||
grace := int64(30)
|
||||
pods := &api.PodList{
|
||||
ListMeta: unversioned.ListMeta{
|
||||
ResourceVersion: "15",
|
||||
@ -91,19 +91,11 @@ func testData() (*api.PodList, *api.ServiceList) {
|
||||
Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "test", ResourceVersion: "10"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", Namespace: "test", ResourceVersion: "11"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
@ -129,7 +130,6 @@ func TestHelperCreate(t *testing.T) {
|
||||
return true
|
||||
}
|
||||
|
||||
grace := int64(30)
|
||||
tests := []struct {
|
||||
Resp *http.Response
|
||||
RespFunc fake.HTTPClientFunc
|
||||
@ -173,11 +173,7 @@ func TestHelperCreate(t *testing.T) {
|
||||
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"}},
|
||||
ExpectObject: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
Resp: &http.Response{StatusCode: http.StatusOK, Body: objBody(&unversioned.Status{Status: unversioned.StatusSuccess})},
|
||||
Req: expectPost,
|
||||
@ -384,7 +380,6 @@ func TestHelperReplace(t *testing.T) {
|
||||
return true
|
||||
}
|
||||
|
||||
grace := int64(30)
|
||||
tests := []struct {
|
||||
Resp *http.Response
|
||||
RespFunc fake.HTTPClientFunc
|
||||
@ -421,11 +416,7 @@ func TestHelperReplace(t *testing.T) {
|
||||
Object: &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}},
|
||||
ExpectObject: &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "10"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
Overwrite: true,
|
||||
RespFunc: func(req *http.Request) (*http.Response, error) {
|
||||
|
@ -28,6 +28,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/fake"
|
||||
"k8s.io/kubernetes/pkg/client/unversioned/testclient"
|
||||
@ -1011,7 +1012,6 @@ func TestUpdateExistingReplicationController(t *testing.T) {
|
||||
|
||||
func TestUpdateWithRetries(t *testing.T) {
|
||||
codec := testapi.Default.Codec()
|
||||
grace := int64(30)
|
||||
rc := &api.ReplicationController{
|
||||
ObjectMeta: api.ObjectMeta{Name: "rc",
|
||||
Labels: map[string]string{
|
||||
@ -1028,11 +1028,7 @@ func TestUpdateWithRetries(t *testing.T) {
|
||||
"foo": "bar",
|
||||
},
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ func TestDecodeSinglePod(t *testing.T) {
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
json, err := testapi.Default.Codec().Encode(pod)
|
||||
@ -115,6 +116,7 @@ func TestDecodePodList(t *testing.T) {
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
podList := &api.PodList{
|
||||
|
@ -90,7 +90,8 @@ func TestReadPodsFromFile(t *testing.T) {
|
||||
Namespace: "mynamespace",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
Containers: []api.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||
Containers: []api.Container{{Name: "image", Image: "test/image", SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
},
|
||||
expected: CreatePodUpdate(kubelet.SET, kubelet.FileSource, &api.Pod{
|
||||
@ -111,6 +112,7 @@ func TestReadPodsFromFile(t *testing.T) {
|
||||
TerminationMessagePath: "/dev/termination-log",
|
||||
ImagePullPolicy: "IfNotPresent",
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults()}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}),
|
||||
},
|
||||
|
@ -143,8 +143,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
Namespace: "mynamespace",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
},
|
||||
expected: CreatePodUpdate(kubelet.SET,
|
||||
@ -161,6 +162,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
NodeName: hostname,
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
|
||||
Containers: []api.Container{{
|
||||
@ -186,8 +188,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
UID: "111",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "1", Image: "foo", ImagePullPolicy: api.PullAlways}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
},
|
||||
{
|
||||
@ -196,8 +199,9 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
UID: "222",
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "2", Image: "bar", ImagePullPolicy: ""}},
|
||||
NodeName: hostname,
|
||||
Containers: []api.Container{{Name: "2", Image: "bar", ImagePullPolicy: ""}},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -217,6 +221,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
|
||||
Containers: []api.Container{{
|
||||
Name: "1",
|
||||
@ -239,6 +244,7 @@ func TestExtractPodsFromHTTP(t *testing.T) {
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
|
||||
Containers: []api.Container{{
|
||||
Name: "2",
|
||||
|
@ -942,9 +942,9 @@ func (dm *DockerManager) podInfraContainerChanged(pod *api.Pod, podInfraContaine
|
||||
if dockerPodInfraContainer.HostConfig != nil {
|
||||
networkMode = dockerPodInfraContainer.HostConfig.NetworkMode
|
||||
}
|
||||
if pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {
|
||||
if networkMode != "host" {
|
||||
glog.V(4).Infof("host: %v, %v", pod.Spec.HostNetwork, networkMode)
|
||||
glog.V(4).Infof("host: %v, %v", pod.Spec.SecurityContext.HostNetwork, networkMode)
|
||||
return true, nil
|
||||
}
|
||||
} else {
|
||||
@ -1468,7 +1468,7 @@ func (dm *DockerManager) runContainerInPod(pod *api.Pod, container *api.Containe
|
||||
}
|
||||
|
||||
utsMode := ""
|
||||
if pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {
|
||||
utsMode = "host"
|
||||
}
|
||||
id, err := dm.runContainer(pod, container, opts, ref, netMode, ipcMode, utsMode, pidMode)
|
||||
@ -1585,7 +1585,7 @@ func (dm *DockerManager) createPodInfraContainer(pod *api.Pod) (kubeletTypes.Doc
|
||||
netNamespace = "none"
|
||||
}
|
||||
|
||||
if pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {
|
||||
netNamespace = "host"
|
||||
} else {
|
||||
// Docker only exports ports from the pod infra container. Let's
|
||||
@ -1985,7 +1985,7 @@ func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podSt
|
||||
// getPidMode returns the pid mode to use on the docker container based on pod.Spec.HostPID.
|
||||
func getPidMode(pod *api.Pod) string {
|
||||
pidMode := ""
|
||||
if pod.Spec.HostPID {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID {
|
||||
pidMode = "host"
|
||||
}
|
||||
return pidMode
|
||||
@ -1994,7 +1994,7 @@ func getPidMode(pod *api.Pod) string {
|
||||
// getIPCMode returns the ipc mode to use on the docker container based on pod.Spec.HostIPC.
|
||||
func getIPCMode(pod *api.Pod) string {
|
||||
ipcMode := ""
|
||||
if pod.Spec.HostIPC {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC {
|
||||
ipcMode = "host"
|
||||
}
|
||||
return ipcMode
|
||||
|
@ -517,7 +517,7 @@ func TestIsAExitError(t *testing.T) {
|
||||
|
||||
func generatePodInfraContainerHash(pod *api.Pod) uint64 {
|
||||
var ports []api.ContainerPort
|
||||
if !pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext == nil || !pod.Spec.SecurityContext.HostNetwork {
|
||||
for _, container := range pod.Spec.Containers {
|
||||
ports = append(ports, container.Ports...)
|
||||
}
|
||||
@ -1819,7 +1819,9 @@ func TestSyncPodWithHostNetwork(t *testing.T) {
|
||||
Containers: []api.Container{
|
||||
{Name: "bar"},
|
||||
},
|
||||
HostNetwork: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -2041,7 +2043,8 @@ func TestGetPidMode(t *testing.T) {
|
||||
}
|
||||
|
||||
// test true
|
||||
pod.Spec.HostPID = true
|
||||
pod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
pod.Spec.SecurityContext.HostPID = true
|
||||
pidMode = getPidMode(pod)
|
||||
if pidMode != "host" {
|
||||
t.Errorf("expected host pid mode for pod but got %v", pidMode)
|
||||
@ -2058,7 +2061,8 @@ func TestGetIPCMode(t *testing.T) {
|
||||
}
|
||||
|
||||
// test true
|
||||
pod.Spec.HostIPC = true
|
||||
pod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
pod.Spec.SecurityContext.HostIPC = true
|
||||
ipcMode = getIPCMode(pod)
|
||||
if ipcMode != "host" {
|
||||
t.Errorf("expected host ipc mode for pod but got %v", ipcMode)
|
||||
|
@ -1352,7 +1352,7 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont
|
||||
return err
|
||||
}
|
||||
if egress != nil || ingress != nil {
|
||||
if pod.Spec.HostNetwork {
|
||||
if podUsesHostNetwork(pod) {
|
||||
kl.recorder.Event(pod, "HostNetworkNotSupported", "Bandwidth shaping is not currently supported on the host network")
|
||||
} else if kl.shaper != nil {
|
||||
status, found := kl.statusManager.GetPodStatus(pod.UID)
|
||||
@ -1391,6 +1391,10 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont
|
||||
return nil
|
||||
}
|
||||
|
||||
func podUsesHostNetwork(pod *api.Pod) bool {
|
||||
return pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork
|
||||
}
|
||||
|
||||
// getPullSecretsForPod inspects the Pod and retrieves the referenced pull secrets
|
||||
// TODO duplicate secrets are being retrieved multiple times and there is no cache. Creating and using a secret manager interface will make this easier to address.
|
||||
func (kl *Kubelet) getPullSecretsForPod(pod *api.Pod) ([]api.Secret, error) {
|
||||
@ -2632,7 +2636,7 @@ func (kl *Kubelet) generatePodStatus(pod *api.Pod) (api.PodStatus, error) {
|
||||
glog.V(4).Infof("Cannot get host IP: %v", err)
|
||||
} else {
|
||||
podStatus.HostIP = hostIP.String()
|
||||
if pod.Spec.HostNetwork && podStatus.PodIP == "" {
|
||||
if podUsesHostNetwork(pod) && podStatus.PodIP == "" {
|
||||
podStatus.PodIP = hostIP.String()
|
||||
}
|
||||
}
|
||||
|
@ -2920,7 +2920,9 @@ func TestHostNetworkAllowed(t *testing.T) {
|
||||
Containers: []api.Container{
|
||||
{Name: "foo"},
|
||||
},
|
||||
HostNetwork: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
kubelet.podManager.SetPods([]*api.Pod{pod})
|
||||
@ -2952,7 +2954,9 @@ func TestHostNetworkDisallowed(t *testing.T) {
|
||||
Containers: []api.Container{
|
||||
{Name: "foo"},
|
||||
},
|
||||
HostNetwork: true,
|
||||
SecurityContext: &api.PodSecurityContext{
|
||||
HostNetwork: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
err := kubelet.syncPod(pod, nil, container.Pod{}, SyncPodUpdate)
|
||||
|
@ -585,7 +585,7 @@ func (r *Runtime) preparePod(pod *api.Pod, pullSecrets []api.Secret) (string, *k
|
||||
}
|
||||
|
||||
var runPrepared string
|
||||
if pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {
|
||||
runPrepared = fmt.Sprintf("%s run-prepared --mds-register=false %s", r.rktBinAbsPath, uuid)
|
||||
} else {
|
||||
runPrepared = fmt.Sprintf("%s run-prepared --mds-register=false --private-net %s", r.rktBinAbsPath, uuid)
|
||||
|
@ -40,7 +40,7 @@ func CapacityFromMachineInfo(info *cadvisorApi.MachineInfo) api.ResourceList {
|
||||
|
||||
// Check whether we have the capabilities to run the specified pod.
|
||||
func canRunPod(pod *api.Pod) error {
|
||||
if pod.Spec.HostNetwork {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostNetwork {
|
||||
allowed, err := allowHostNetwork(pod)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -50,7 +50,7 @@ func canRunPod(pod *api.Pod) error {
|
||||
}
|
||||
}
|
||||
|
||||
if pod.Spec.HostPID {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID {
|
||||
allowed, err := allowHostPID(pod)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -60,7 +60,7 @@ func canRunPod(pod *api.Pod) error {
|
||||
}
|
||||
}
|
||||
|
||||
if pod.Spec.HostIPC {
|
||||
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC {
|
||||
allowed, err := allowHostIPC(pod)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -64,6 +64,7 @@ func validNewPod() *api.Pod {
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
}
|
||||
@ -617,6 +618,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}), 1)
|
||||
|
||||
@ -631,19 +633,18 @@ func TestEtcdUpdateScheduled(t *testing.T) {
|
||||
},
|
||||
Spec: api.PodSpec{
|
||||
NodeName: "machine",
|
||||
Containers: []api.Container{
|
||||
{
|
||||
Name: "foobar",
|
||||
Image: "foo:v2",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
TerminationMessagePath: api.TerminationMessagePathDefault,
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
},
|
||||
},
|
||||
Containers: []api.Container{{
|
||||
Name: "foobar",
|
||||
Image: "foo:v2",
|
||||
ImagePullPolicy: api.PullIfNotPresent,
|
||||
TerminationMessagePath: api.TerminationMessagePathDefault,
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
}},
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
_, _, err := storage.Update(ctx, &podIn)
|
||||
@ -682,6 +683,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
|
||||
SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
}
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &podStart), 0)
|
||||
@ -703,6 +705,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
|
||||
TerminationMessagePath: api.TerminationMessagePathDefault,
|
||||
},
|
||||
},
|
||||
SecurityContext: &api.PodSecurityContext{},
|
||||
},
|
||||
Status: api.PodStatus{
|
||||
Phase: api.PodRunning,
|
||||
|
@ -27,6 +27,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/meta"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -56,14 +57,9 @@ func newTestCacher(client tools.EtcdClient) *storage.Cacher {
|
||||
}
|
||||
|
||||
func makeTestPod(name string) *api.Pod {
|
||||
gracePeriod := int64(30)
|
||||
return &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Namespace: "ns", Name: name},
|
||||
Spec: api.PodSpec{
|
||||
TerminationGracePeriodSeconds: &gracePeriod,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||
"k8s.io/kubernetes/pkg/conversion"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -124,33 +125,20 @@ func TestList(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
grace := int64(30)
|
||||
expect := api.PodList{
|
||||
ListMeta: unversioned.ListMeta{ResourceVersion: "10"},
|
||||
Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -197,17 +185,12 @@ func TestListFiltered(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
grace := int64(30)
|
||||
expect := api.PodList{
|
||||
ListMeta: unversioned.ListMeta{ResourceVersion: "10"},
|
||||
Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -273,34 +256,21 @@ func TestListAcrossDirectories(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
grace := int64(30)
|
||||
expect := api.PodList{
|
||||
ListMeta: unversioned.ListMeta{ResourceVersion: "10"},
|
||||
Items: []api.Pod{
|
||||
// We expect list to be sorted by directory (e.g. namespace) first, then by name.
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -349,33 +319,20 @@ func TestListExcludesDirectories(t *testing.T) {
|
||||
},
|
||||
},
|
||||
}
|
||||
grace := int64(30)
|
||||
expect := api.PodList{
|
||||
ListMeta: unversioned.ListMeta{ResourceVersion: "10"},
|
||||
Items: []api.Pod{
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "2"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "baz", ResourceVersion: "3"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", ResourceVersion: "1"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -394,14 +351,9 @@ func TestGet(t *testing.T) {
|
||||
fakeClient := tools.NewFakeEtcdClient(t)
|
||||
helper := newEtcdHelper(fakeClient, testapi.Default.Codec(), etcdtest.PathPrefix())
|
||||
key := etcdtest.AddPrefix("/some/key")
|
||||
grace := int64(30)
|
||||
expect := api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
}
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Default.Codec(), &expect), 0)
|
||||
var got api.Pod
|
||||
|
@ -90,11 +90,11 @@ func (d *denyExec) Admit(a admission.Attributes) (err error) {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
|
||||
if d.hostPID && pod.Spec.HostPID {
|
||||
if d.hostPID && pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostPID {
|
||||
return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a container using host pid"))
|
||||
}
|
||||
|
||||
if d.hostIPC && pod.Spec.HostIPC {
|
||||
if d.hostIPC && pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.HostIPC {
|
||||
return admission.NewForbidden(a, fmt.Errorf("Cannot exec into or attach to a container using host ipc"))
|
||||
}
|
||||
|
||||
|
@ -34,10 +34,12 @@ func TestAdmission(t *testing.T) {
|
||||
}
|
||||
|
||||
hostPIDPod := validPod("hostPID")
|
||||
hostPIDPod.Spec.HostPID = true
|
||||
hostPIDPod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
hostPIDPod.Spec.SecurityContext.HostPID = true
|
||||
|
||||
hostIPCPod := validPod("hostIPC")
|
||||
hostIPCPod.Spec.HostIPC = true
|
||||
hostIPCPod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
hostIPCPod.Spec.SecurityContext.HostIPC = true
|
||||
|
||||
testCases := map[string]struct {
|
||||
pod *api.Pod
|
||||
@ -130,10 +132,12 @@ func TestDenyExecOnPrivileged(t *testing.T) {
|
||||
}
|
||||
|
||||
hostPIDPod := validPod("hostPID")
|
||||
hostPIDPod.Spec.HostPID = true
|
||||
hostPIDPod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
hostPIDPod.Spec.SecurityContext.HostPID = true
|
||||
|
||||
hostIPCPod := validPod("hostIPC")
|
||||
hostIPCPod.Spec.HostIPC = true
|
||||
hostIPCPod.Spec.SecurityContext = &api.PodSecurityContext{}
|
||||
hostIPCPod.Spec.SecurityContext.HostIPC = true
|
||||
|
||||
testCases := map[string]struct {
|
||||
pod *api.Pod
|
||||
|
@ -25,6 +25,7 @@ import (
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
"k8s.io/kubernetes/pkg/client/cache"
|
||||
client "k8s.io/kubernetes/pkg/client/unversioned"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
@ -132,14 +133,9 @@ func PriorityTwo(pod *api.Pod, podLister algorithm.PodLister, nodeLister algorit
|
||||
}
|
||||
|
||||
func TestDefaultErrorFunc(t *testing.T) {
|
||||
grace := int64(30)
|
||||
testPod := &api.Pod{
|
||||
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "bar"},
|
||||
Spec: api.PodSpec{
|
||||
RestartPolicy: api.RestartPolicyAlways,
|
||||
DNSPolicy: api.DNSClusterFirst,
|
||||
TerminationGracePeriodSeconds: &grace,
|
||||
},
|
||||
Spec: apitesting.DeepEqualSafePodSpec(),
|
||||
}
|
||||
handler := util.FakeHandler{
|
||||
StatusCode: 200,
|
||||
|
Loading…
Reference in New Issue
Block a user