kubectl: add unit tests for kubectl debug profiles

Unit test netadmin profile preserves existing capabilities.
Unit test debug profiles in TestGenerateNodeDebugPod
Unit test debug profiles in TestGeneratePodCopyWithDebugContainer
Organize Go imports in unit tests

Signed-off-by: Will Daly <widaly@microsoft.com>
This commit is contained in:
Will Daly 2023-02-16 06:38:12 -08:00 committed by Will Daly
parent 77af0be42f
commit 21e8d29581
2 changed files with 462 additions and 7 deletions

View File

@ -22,16 +22,15 @@ import (
"testing" "testing"
"time" "time"
"github.com/spf13/cobra"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts" "github.com/google/go-cmp/cmp/cmpopts"
"k8s.io/utils/pointer" "github.com/spf13/cobra"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
cmdtesting "k8s.io/kubectl/pkg/cmd/testing" cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
"k8s.io/utils/pointer"
) )
func TestGenerateDebugContainer(t *testing.T) { func TestGenerateDebugContainer(t *testing.T) {
@ -361,6 +360,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Container: "debugger", Container: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -398,6 +398,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
SameNode: true, SameNode: true,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -435,6 +436,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Container: "debugger", Container: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -481,6 +483,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Container: "debugger", Container: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -524,6 +527,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Name: "TEST", Name: "TEST",
Value: "test", Value: "test",
}}, }},
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -568,6 +572,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Args: []string{"/bin/echo", "one", "two", "three"}, Args: []string{"/bin/echo", "one", "two", "three"},
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -610,6 +615,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
ArgsOnly: true, ArgsOnly: true,
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -650,6 +656,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Container: "debugger", Container: "debugger",
Args: []string{"sleep", "1d"}, Args: []string{"sleep", "1d"},
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -690,6 +697,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
CopyTo: "debugger", CopyTo: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -728,6 +736,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
CopyTo: "debugger", CopyTo: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -766,6 +775,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
CopyTo: "debugger", CopyTo: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -820,6 +830,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
CopyTo: "debugger", CopyTo: "debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -873,6 +884,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
ShareProcesses: true, ShareProcesses: true,
shareProcessedChanged: true, shareProcessedChanged: true,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -914,6 +926,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Container: "app", Container: "app",
Image: "busybox", Image: "busybox",
TargetNames: []string{"myapp"}, TargetNames: []string{"myapp"},
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "myapp"}, ObjectMeta: metav1.ObjectMeta{Name: "myapp"},
@ -940,6 +953,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
CopyTo: "myapp-copy", CopyTo: "myapp-copy",
Container: "app", Container: "app",
SetImages: map[string]string{"app": "busybox"}, SetImages: map[string]string{"app": "busybox"},
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -969,6 +983,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
opts: &DebugOptions{ opts: &DebugOptions{
CopyTo: "myapp-copy", CopyTo: "myapp-copy",
SetImages: map[string]string{"*": "busybox"}, SetImages: map[string]string{"*": "busybox"},
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -998,6 +1013,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
opts: &DebugOptions{ opts: &DebugOptions{
CopyTo: "myapp-copy", CopyTo: "myapp-copy",
SetImages: map[string]string{"*": "busybox", "app": "app-debugger"}, SetImages: map[string]string{"*": "busybox", "app": "app-debugger"},
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -1032,6 +1048,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
Interactive: true, Interactive: true,
TargetNames: []string{"mypod"}, TargetNames: []string{"mypod"},
TTY: true, TTY: true,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "mypod"}, ObjectMeta: metav1.ObjectMeta{Name: "mypod"},
@ -1075,6 +1092,7 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
ShareProcesses: true, ShareProcesses: true,
TargetNames: []string{"mypod"}, TargetNames: []string{"mypod"},
TTY: true, TTY: true,
Profile: ProfileLegacy,
}, },
havePod: &corev1.Pod{ havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "mypod"}, ObjectMeta: metav1.ObjectMeta{Name: "mypod"},
@ -1102,12 +1120,179 @@ func TestGeneratePodCopyWithDebugContainer(t *testing.T) {
}, },
}, },
}, },
{
name: "general profile",
opts: &DebugOptions{
CopyTo: "debugger",
Container: "debugger",
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileGeneral,
},
havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "target",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
},
},
NodeName: "node-1",
},
},
wantPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "debugger",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"SYS_PTRACE"},
},
},
},
},
ShareProcessNamespace: pointer.Bool(true),
},
},
},
{
name: "baseline profile",
opts: &DebugOptions{
CopyTo: "debugger",
Container: "debugger",
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileBaseline,
},
havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "target",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
},
},
NodeName: "node-1",
},
},
wantPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "debugger",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
},
},
ShareProcessNamespace: pointer.Bool(true),
},
},
},
{
name: "restricted profile",
opts: &DebugOptions{
CopyTo: "debugger",
Container: "debugger",
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileRestricted,
},
havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "target",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
},
},
NodeName: "node-1",
},
},
wantPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "debugger",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Drop: []corev1.Capability{"ALL"},
},
RunAsNonRoot: pointer.Bool(true),
},
},
},
ShareProcessNamespace: pointer.Bool(true),
},
},
},
{
name: "netadmin profile",
opts: &DebugOptions{
CopyTo: "debugger",
Container: "debugger",
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileNetadmin,
},
havePod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "target",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
},
},
NodeName: "node-1",
},
},
wantPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "debugger",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_ADMIN"},
},
},
},
},
},
},
},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var err error var err error
tc.opts.Applier, err = NewProfileApplier(ProfileLegacy) tc.opts.Applier, err = NewProfileApplier(tc.opts.Profile)
if err != nil { if err != nil {
t.Fatalf("Fail to create legacy profile: %v", err) t.Fatalf("Fail to create profile applier: %s: %v", tc.opts.Profile, err)
} }
tc.opts.IOStreams = genericclioptions.NewTestIOStreamsDiscard() tc.opts.IOStreams = genericclioptions.NewTestIOStreamsDiscard()
suffixCounter = 0 suffixCounter = 0
@ -1147,6 +1332,7 @@ func TestGenerateNodeDebugPod(t *testing.T) {
opts: &DebugOptions{ opts: &DebugOptions{
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
expected: &corev1.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -1200,6 +1386,7 @@ func TestGenerateNodeDebugPod(t *testing.T) {
Container: "custom-debugger", Container: "custom-debugger",
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
expected: &corev1.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -1255,6 +1442,7 @@ func TestGenerateNodeDebugPod(t *testing.T) {
Args: []string{"echo", "one", "two", "three"}, Args: []string{"echo", "one", "two", "three"},
Image: "busybox", Image: "busybox",
PullPolicy: corev1.PullIfNotPresent, PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileLegacy,
}, },
expected: &corev1.Pod{ expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
@ -1297,12 +1485,190 @@ func TestGenerateNodeDebugPod(t *testing.T) {
}, },
}, },
}, },
{
name: "general profile",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-XXX",
},
},
opts: &DebugOptions{
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileGeneral,
},
expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "node-debugger-node-XXX-1",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
VolumeMounts: []corev1.VolumeMount{
{
MountPath: "/host",
Name: "host-root",
},
},
},
},
HostIPC: true,
HostNetwork: true,
HostPID: true,
NodeName: "node-XXX",
RestartPolicy: corev1.RestartPolicyNever,
Volumes: []corev1.Volume{
{
Name: "host-root",
VolumeSource: corev1.VolumeSource{
HostPath: &corev1.HostPathVolumeSource{Path: "/"},
},
},
},
Tolerations: []corev1.Toleration{
{
Operator: corev1.TolerationOpExists,
},
},
},
},
},
{
name: "baseline profile",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-XXX",
},
},
opts: &DebugOptions{
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileBaseline,
},
expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "node-debugger-node-XXX-1",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
VolumeMounts: nil,
},
},
HostIPC: false,
HostNetwork: false,
HostPID: false,
NodeName: "node-XXX",
RestartPolicy: corev1.RestartPolicyNever,
Volumes: nil,
Tolerations: []corev1.Toleration{
{
Operator: corev1.TolerationOpExists,
},
},
},
},
},
{
name: "restricted profile",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-XXX",
},
},
opts: &DebugOptions{
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileRestricted,
},
expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "node-debugger-node-XXX-1",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
VolumeMounts: nil,
},
},
HostIPC: false,
HostNetwork: false,
HostPID: false,
NodeName: "node-XXX",
RestartPolicy: corev1.RestartPolicyNever,
Volumes: nil,
Tolerations: []corev1.Toleration{
{
Operator: corev1.TolerationOpExists,
},
},
},
},
},
{
name: "netadmin profile",
node: &corev1.Node{
ObjectMeta: metav1.ObjectMeta{
Name: "node-XXX",
},
},
opts: &DebugOptions{
Image: "busybox",
PullPolicy: corev1.PullIfNotPresent,
Profile: ProfileNetadmin,
},
expected: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "node-debugger-node-XXX-1",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "debugger",
Image: "busybox",
ImagePullPolicy: corev1.PullIfNotPresent,
TerminationMessagePolicy: corev1.TerminationMessageReadFile,
VolumeMounts: nil,
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.Bool(true),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"NET_ADMIN"},
},
},
},
},
HostIPC: true,
HostNetwork: true,
HostPID: true,
NodeName: "node-XXX",
RestartPolicy: corev1.RestartPolicyNever,
Volumes: nil,
Tolerations: []corev1.Toleration{
{
Operator: corev1.TolerationOpExists,
},
},
},
},
},
} { } {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
var err error var err error
tc.opts.Applier, err = NewProfileApplier(ProfileLegacy) tc.opts.Applier, err = NewProfileApplier(tc.opts.Profile)
if err != nil { if err != nil {
t.Fatalf("Fail to create legacy profile: %v", err) t.Fatalf("Fail to create profile applier: %s: %v", tc.opts.Profile, err)
} }
tc.opts.IOStreams = genericclioptions.NewTestIOStreamsDiscard() tc.opts.IOStreams = genericclioptions.NewTestIOStreamsDiscard()
suffixCounter = 0 suffixCounter = 0

View File

@ -21,6 +21,7 @@ import (
"testing" "testing"
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime"
@ -518,6 +519,52 @@ func TestNetAdminProfile(t *testing.T) {
}, },
}, },
}, },
{
name: "debug by pod copy preserve existing capability",
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "podcopy"},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "app", Image: "appimage"},
{
Name: "dbg",
Image: "dbgimage",
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"SYS_PTRACE"},
},
},
},
},
},
},
containerName: "dbg",
target: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "podcopy"},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "app", Image: "appimage"},
},
},
},
expectPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "podcopy"},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{Name: "app", Image: "appimage"},
{
Name: "dbg",
Image: "dbgimage",
SecurityContext: &corev1.SecurityContext{
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"SYS_PTRACE", "NET_ADMIN"},
},
},
},
},
},
},
},
{ {
name: "debug by node", name: "debug by node",
pod: &corev1.Pod{ pod: &corev1.Pod{
@ -551,6 +598,48 @@ func TestNetAdminProfile(t *testing.T) {
}, },
}, },
}, },
{
name: "debug by node preserve existing capability",
pod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "dbg",
Image: "dbgimage",
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.BoolPtr(true),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"SYS_PTRACE"},
},
},
},
},
},
},
containerName: "dbg",
target: testNode,
expectPod: &corev1.Pod{
ObjectMeta: metav1.ObjectMeta{Name: "pod"},
Spec: corev1.PodSpec{
HostNetwork: true,
HostPID: true,
HostIPC: true,
Containers: []corev1.Container{
{
Name: "dbg",
Image: "dbgimage",
SecurityContext: &corev1.SecurityContext{
Privileged: pointer.BoolPtr(true),
Capabilities: &corev1.Capabilities{
Add: []corev1.Capability{"SYS_PTRACE", "NET_ADMIN"},
},
},
},
},
},
},
},
} }
for _, test := range tests { for _, test := range tests {