mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Merge pull request #123952 from kinvolk/rata/userns-add-tests-namespacesForPod
pkg/kubelet/kuberuntime: Add userns tests for NamespacesForPod
This commit is contained in:
		@@ -18,10 +18,13 @@ package testing
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"context"
 | 
						"context"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v1 "k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
	kubetypes "k8s.io/apimachinery/pkg/types"
 | 
						kubetypes "k8s.io/apimachinery/pkg/types"
 | 
				
			||||||
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
 | 
						runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
 | 
				
			||||||
 | 
						"k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
						kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -33,6 +36,7 @@ type FakeRuntimeHelper struct {
 | 
				
			|||||||
	HostName        string
 | 
						HostName        string
 | 
				
			||||||
	HostDomain      string
 | 
						HostDomain      string
 | 
				
			||||||
	PodContainerDir string
 | 
						PodContainerDir string
 | 
				
			||||||
 | 
						RuntimeHandlers map[string]kubecontainer.RuntimeHandler
 | 
				
			||||||
	Err             error
 | 
						Err             error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -69,7 +73,38 @@ func (f *FakeRuntimeHelper) GetExtraSupplementalGroupsForPod(pod *v1.Pod) []int6
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *FakeRuntimeHelper) GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) {
 | 
					func (f *FakeRuntimeHelper) GetOrCreateUserNamespaceMappings(pod *v1.Pod, runtimeHandler string) (*runtimeapi.UserNamespace, error) {
 | 
				
			||||||
	return nil, nil
 | 
						featureEnabled := utilfeature.DefaultFeatureGate.Enabled(features.UserNamespacesSupport)
 | 
				
			||||||
 | 
						if pod == nil || pod.Spec.HostUsers == nil {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// pod.Spec.HostUsers is set to true/false
 | 
				
			||||||
 | 
						if !featureEnabled {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("the feature gate %q is disabled: can't set spec.HostUsers", features.UserNamespacesSupport)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if *pod.Spec.HostUsers {
 | 
				
			||||||
 | 
							return nil, nil
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// From here onwards, hostUsers=false and the feature gate is enabled.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// if the pod requested a user namespace and the runtime doesn't support user namespaces then return an error.
 | 
				
			||||||
 | 
						if h, ok := f.RuntimeHandlers[runtimeHandler]; !ok {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("RuntimeClass handler %q not found", runtimeHandler)
 | 
				
			||||||
 | 
						} else if !h.SupportsUserNamespaces {
 | 
				
			||||||
 | 
							return nil, fmt.Errorf("RuntimeClass handler %q does not support user namespaces", runtimeHandler)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ids := &runtimeapi.IDMapping{
 | 
				
			||||||
 | 
							HostId:      65536,
 | 
				
			||||||
 | 
							ContainerId: 0,
 | 
				
			||||||
 | 
							Length:      65536,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &runtimeapi.UserNamespace{
 | 
				
			||||||
 | 
							Mode: runtimeapi.NamespaceMode_POD,
 | 
				
			||||||
 | 
							Uids: []*runtimeapi.IDMapping{ids},
 | 
				
			||||||
 | 
							Gids: []*runtimeapi.IDMapping{ids},
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (f *FakeRuntimeHelper) PrepareDynamicResources(pod *v1.Pod) error {
 | 
					func (f *FakeRuntimeHelper) PrepareDynamicResources(pod *v1.Pod) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -22,7 +22,10 @@ import (
 | 
				
			|||||||
	"github.com/stretchr/testify/require"
 | 
						"github.com/stretchr/testify/require"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	v1 "k8s.io/api/core/v1"
 | 
						v1 "k8s.io/api/core/v1"
 | 
				
			||||||
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
 | 
						featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
				
			||||||
	runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
 | 
						runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1"
 | 
				
			||||||
 | 
						pkgfeatures "k8s.io/kubernetes/pkg/features"
 | 
				
			||||||
	kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
						kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
 | 
				
			||||||
	kubecontainertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
 | 
						kubecontainertest "k8s.io/kubernetes/pkg/kubelet/container/testing"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
@@ -162,10 +165,25 @@ func TestPodSandboxChanged(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type fakeRuntimeHandlerResolver struct{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (*fakeRuntimeHandlerResolver) LookupRuntimeHandler(s *string) (string, error) {
 | 
				
			||||||
 | 
						return "", nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestNamespacesForPod(t *testing.T) {
 | 
					func TestNamespacesForPod(t *testing.T) {
 | 
				
			||||||
 | 
						usernsIDs := &runtimeapi.IDMapping{
 | 
				
			||||||
 | 
							HostId:      65536,
 | 
				
			||||||
 | 
							ContainerId: 0,
 | 
				
			||||||
 | 
							Length:      65536,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for desc, test := range map[string]struct {
 | 
						for desc, test := range map[string]struct {
 | 
				
			||||||
		input    *v1.Pod
 | 
							input           *v1.Pod
 | 
				
			||||||
		expected *runtimeapi.NamespaceOption
 | 
							runtimeHandlers map[string]kubecontainer.RuntimeHandler
 | 
				
			||||||
 | 
							usernsEnabled   bool
 | 
				
			||||||
 | 
							expected        *runtimeapi.NamespaceOption
 | 
				
			||||||
 | 
							expErr          bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		"nil pod -> default v1 namespaces": {
 | 
							"nil pod -> default v1 namespaces": {
 | 
				
			||||||
			input: nil,
 | 
								input: nil,
 | 
				
			||||||
@@ -221,11 +239,84 @@ func TestNamespacesForPod(t *testing.T) {
 | 
				
			|||||||
				Pid:     runtimeapi.NamespaceMode_CONTAINER,
 | 
									Pid:     runtimeapi.NamespaceMode_CONTAINER,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							"hostUsers: false and feature enabled": {
 | 
				
			||||||
 | 
								input: &v1.Pod{
 | 
				
			||||||
 | 
									Spec: v1.PodSpec{
 | 
				
			||||||
 | 
										HostUsers: &[]bool{false}[0],
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								usernsEnabled: true,
 | 
				
			||||||
 | 
								runtimeHandlers: map[string]kubecontainer.RuntimeHandler{
 | 
				
			||||||
 | 
									"": {
 | 
				
			||||||
 | 
										SupportsUserNamespaces: true,
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expected: &runtimeapi.NamespaceOption{
 | 
				
			||||||
 | 
									Ipc:     runtimeapi.NamespaceMode_POD,
 | 
				
			||||||
 | 
									Network: runtimeapi.NamespaceMode_POD,
 | 
				
			||||||
 | 
									Pid:     runtimeapi.NamespaceMode_CONTAINER,
 | 
				
			||||||
 | 
									UsernsOptions: &runtimeapi.UserNamespace{
 | 
				
			||||||
 | 
										Mode: runtimeapi.NamespaceMode_POD,
 | 
				
			||||||
 | 
										Uids: []*runtimeapi.IDMapping{usernsIDs},
 | 
				
			||||||
 | 
										Gids: []*runtimeapi.IDMapping{usernsIDs},
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							// The hostUsers field can't be set to any value if the feature is disabled.
 | 
				
			||||||
 | 
							"hostUsers: false and feature disabled --> error": {
 | 
				
			||||||
 | 
								input: &v1.Pod{
 | 
				
			||||||
 | 
									Spec: v1.PodSpec{
 | 
				
			||||||
 | 
										HostUsers: &[]bool{false}[0],
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								usernsEnabled: false,
 | 
				
			||||||
 | 
								expErr:        true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							// The hostUsers field can't be set to any value if the feature is disabled.
 | 
				
			||||||
 | 
							"hostUsers: true and feature disabled --> error": {
 | 
				
			||||||
 | 
								input: &v1.Pod{
 | 
				
			||||||
 | 
									Spec: v1.PodSpec{
 | 
				
			||||||
 | 
										HostUsers: &[]bool{true}[0],
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								usernsEnabled: false,
 | 
				
			||||||
 | 
								expErr:        true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"error if runtime handler not found": {
 | 
				
			||||||
 | 
								input: &v1.Pod{
 | 
				
			||||||
 | 
									Spec: v1.PodSpec{
 | 
				
			||||||
 | 
										HostUsers: &[]bool{false}[0],
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								usernsEnabled: true,
 | 
				
			||||||
 | 
								runtimeHandlers: map[string]kubecontainer.RuntimeHandler{
 | 
				
			||||||
 | 
									"other": {},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								expErr: true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"error if runtime handler does not support userns": {
 | 
				
			||||||
 | 
								input: &v1.Pod{
 | 
				
			||||||
 | 
									Spec: v1.PodSpec{
 | 
				
			||||||
 | 
										HostUsers: &[]bool{false}[0],
 | 
				
			||||||
 | 
									},
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								usernsEnabled: true,
 | 
				
			||||||
 | 
								expErr:        true,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
	} {
 | 
						} {
 | 
				
			||||||
		t.Run(desc, func(t *testing.T) {
 | 
							t.Run(desc, func(t *testing.T) {
 | 
				
			||||||
			actual, err := NamespacesForPod(test.input, &kubecontainertest.FakeRuntimeHelper{}, nil)
 | 
								featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, pkgfeatures.UserNamespacesSupport, test.usernsEnabled)
 | 
				
			||||||
			require.NoError(t, err)
 | 
					
 | 
				
			||||||
			require.Equal(t, test.expected, actual)
 | 
								fakeRuntimeHelper := kubecontainertest.FakeRuntimeHelper{
 | 
				
			||||||
 | 
									RuntimeHandlers: test.runtimeHandlers,
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								actual, err := NamespacesForPod(test.input, &fakeRuntimeHelper, &fakeRuntimeHandlerResolver{})
 | 
				
			||||||
 | 
								if test.expErr {
 | 
				
			||||||
 | 
									require.Error(t, err)
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									require.NoError(t, err)
 | 
				
			||||||
 | 
									require.Equal(t, test.expected, actual)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user