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> Kubernetes-commit: 21e8d2958190e9813fe1122d1e7a91e8143a5193
This commit is contained in:
parent
060672725b
commit
bfae4f6bfd
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue