Aaron U'Ren d90c753286 fact(NPC): refactor isPodUpdateNetPolRelevant
Refactor this logic so that it can be more easily tested and expanded
without cluttering the pod.go file. Additionally, add some safe guards
around the pod cast to ensure that we're working with pods before we
pass them.
2021-06-01 10:42:42 -05:00

163 lines
5.5 KiB
Go

package netpol
import (
"testing"
"github.com/stretchr/testify/assert"
api "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
var (
fakePod = api.Pod{
TypeMeta: metav1.TypeMeta{
Kind: "Pod",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "testpod",
Namespace: "testnamespace",
Labels: map[string]string{"foo": "bar"}},
Spec: api.PodSpec{
Containers: []api.Container{
{
Image: "k8s.gcr.io/busybox",
},
},
},
Status: api.PodStatus{
PodIP: "172.16.0.1",
PodIPs: []api.PodIP{
{
IP: "172.16.0.1",
},
},
HostIP: "10.0.0.1",
Phase: api.PodRunning,
},
}
)
func Test_isPodUpdateNetPolRelevant(t *testing.T) {
t.Run("Pod phase change should be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.Status.Phase = api.PodFailed
assert.True(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod IP change should be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.Status.PodIP = "172.16.0.2"
assert.True(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod IPs change should be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.Status.PodIPs = []api.PodIP{{IP: "172.16.0.2"}}
assert.True(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod Label change should be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.ObjectMeta.Labels = map[string]string{"bar": "foo"}
assert.True(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod Host IP change should be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.Status.HostIP = "10.0.0.2"
assert.True(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod Image change should NOT be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.Spec.Containers[0].Image = "k8s.gcr.io/otherimage"
assert.False(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
t.Run("Pod Name change should NOT be detected as NetworkPolicy relevant", func(t *testing.T) {
newPod := fakePod.DeepCopy()
newPod.ObjectMeta.Name = "otherpod"
assert.False(t, isPodUpdateNetPolRelevant(&fakePod, newPod))
})
}
func Test_isPodFinished(t *testing.T) {
t.Run("Failed pod should be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = api.PodFailed
assert.True(t, isFinished(&fakePod))
})
t.Run("Succeeded pod should be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = api.PodSucceeded
assert.True(t, isFinished(&fakePod))
})
t.Run("Completed pod should be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = PodCompleted
assert.True(t, isFinished(&fakePod))
})
t.Run("Running pod should NOT be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = api.PodRunning
assert.False(t, isFinished(&fakePod))
})
t.Run("Pending pod should NOT be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = api.PodPending
assert.False(t, isFinished(&fakePod))
})
t.Run("Unknown pod should NOT be detected as finished", func(t *testing.T) {
fakePod.Status.Phase = api.PodUnknown
assert.False(t, isFinished(&fakePod))
})
}
func Test_isNetPolActionable(t *testing.T) {
t.Run("Normal pod should be actionable", func(t *testing.T) {
assert.True(t, isNetPolActionable(&fakePod))
})
t.Run("Pod without Pod IP should not be actionable", func(t *testing.T) {
fakePod.Status.PodIP = ""
assert.False(t, isNetPolActionable(&fakePod))
})
t.Run("Finished Pod should not be actionable", func(t *testing.T) {
fakePod.Status.Phase = api.PodFailed
assert.False(t, isNetPolActionable(&fakePod))
fakePod.Status.Phase = api.PodSucceeded
assert.False(t, isNetPolActionable(&fakePod))
fakePod.Status.Phase = PodCompleted
assert.False(t, isNetPolActionable(&fakePod))
})
t.Run("Host Networked Pod should not be actionable", func(t *testing.T) {
fakePod.Spec.HostNetwork = true
assert.False(t, isNetPolActionable(&fakePod))
})
}
func Test_NewNetworkPolicyController(t *testing.T) {
t.Run("Node Port range specified with a hyphen should pass validation", func(t *testing.T) {
portRange, err := validateNodePortRange("1000-2000")
assert.Nil(t, err)
assert.NotEmpty(t, portRange)
})
t.Run("Node Port range specified with a colon should pass validation", func(t *testing.T) {
portRange, err := validateNodePortRange("1000:2000")
assert.Nil(t, err)
assert.NotEmpty(t, portRange)
})
t.Run("Node Port range specified with a high port range should work", func(t *testing.T) {
portRange, err := validateNodePortRange("40000:42767")
assert.Nil(t, err)
assert.NotEmpty(t, portRange)
portRange, err = validateNodePortRange("50000:65535")
assert.Nil(t, err)
assert.NotEmpty(t, portRange)
})
t.Run("Node Port range specified with a higher start number should fail validation", func(t *testing.T) {
portRange, err := validateNodePortRange("2000:1000")
assert.Error(t, err)
assert.Empty(t, portRange)
})
t.Run("Node Port range specified with same start and end port should fail validation", func(t *testing.T) {
portRange, err := validateNodePortRange("2000:2000")
assert.Error(t, err)
assert.Empty(t, portRange)
})
t.Run("Node Port range specified with a port number higher than 16-bits unsigned should fail validation", func(t *testing.T) {
portRange, err := validateNodePortRange("65535:65537")
assert.Error(t, err)
assert.Empty(t, portRange)
})
}