diff --git a/pkg/k8s/pod_info.go b/pkg/k8s/pod_info.go index b7fea6ce0..bfe67ba10 100644 --- a/pkg/k8s/pod_info.go +++ b/pkg/k8s/pod_info.go @@ -2,6 +2,7 @@ package k8s import ( "encoding/json" + "github.com/pkg/errors" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -97,6 +98,12 @@ func buildPodInfo(pod *corev1.Pod) PodInfo { for _, podContainer := range pod.Spec.Containers { containerPorts = append(containerPorts, podContainer.Ports...) } + // also support sidecar container (initContainer with restartPolicy=Always) + for _, podContainer := range pod.Spec.InitContainers { + if podContainer.RestartPolicy != nil && *podContainer.RestartPolicy == corev1.ContainerRestartPolicyAlways { + containerPorts = append(containerPorts, podContainer.Ports...) + } + } return PodInfo{ Key: podKey, UID: pod.UID, diff --git a/pkg/k8s/pod_info_test.go b/pkg/k8s/pod_info_test.go index 61c8b2305..1d960ccfc 100644 --- a/pkg/k8s/pod_info_test.go +++ b/pkg/k8s/pod_info_test.go @@ -2,13 +2,14 @@ package k8s import ( "errors" + "testing" + "time" + "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" - "testing" - "time" ) func TestPodInfo_HasAnyOfReadinessGates(t *testing.T) { @@ -317,6 +318,8 @@ func Test_buildPodInfo(t *testing.T) { timeNow := time.Now() + initContainerRestartPolicyAlways := corev1.ContainerRestartPolicyAlways + tests := []struct { name string args args @@ -358,6 +361,29 @@ func Test_buildPodInfo(t *testing.T) { }, }, }, + InitContainers: []corev1.Container{ + { + RestartPolicy: &initContainerRestartPolicyAlways, + Ports: []corev1.ContainerPort{ + { + Name: "dns", + ContainerPort: 53, + }, + { + Name: "ftp", + ContainerPort: 21, + }, + }, + }, + { + Ports: []corev1.ContainerPort{ + { + Name: "smtp", + ContainerPort: 25, + }, + }, + }, + }, ReadinessGates: []corev1.PodReadinessGate{ { ConditionType: "ingress.k8s.aws/cond-1", @@ -398,6 +424,14 @@ func Test_buildPodInfo(t *testing.T) { Name: "https", ContainerPort: 8443, }, + { + Name: "dns", + ContainerPort: 53, + }, + { + Name: "ftp", + ContainerPort: 21, + }, }, ReadinessGates: []corev1.PodReadinessGate{ { @@ -461,6 +495,29 @@ func Test_buildPodInfo(t *testing.T) { }, }, }, + InitContainers: []corev1.Container{ + { + RestartPolicy: &initContainerRestartPolicyAlways, + Ports: []corev1.ContainerPort{ + { + Name: "dns", + ContainerPort: 53, + }, + { + Name: "ftp", + ContainerPort: 21, + }, + }, + }, + { + Ports: []corev1.ContainerPort{ + { + Name: "smtp", + ContainerPort: 25, + }, + }, + }, + }, ReadinessGates: []corev1.PodReadinessGate{ { ConditionType: "ingress.k8s.aws/cond-1", @@ -501,6 +558,14 @@ func Test_buildPodInfo(t *testing.T) { Name: "https", ContainerPort: 8443, }, + { + Name: "dns", + ContainerPort: 53, + }, + { + Name: "ftp", + ContainerPort: 21, + }, }, ReadinessGates: []corev1.PodReadinessGate{ { diff --git a/pkg/k8s/pod_utils.go b/pkg/k8s/pod_utils.go index da611f39c..80a79d6cd 100644 --- a/pkg/k8s/pod_utils.go +++ b/pkg/k8s/pod_utils.go @@ -53,6 +53,16 @@ func LookupContainerPort(pod *corev1.Pod, port intstr.IntOrString) (int64, error } } } + // also support sidecar container (initContainer with restartPolicy=Always) + for _, podContainer := range pod.Spec.InitContainers { + if podContainer.RestartPolicy != nil && *podContainer.RestartPolicy == corev1.ContainerRestartPolicyAlways { + for _, podPort := range podContainer.Ports { + if podPort.Name == port.StrVal { + return int64(podPort.ContainerPort), nil + } + } + } + } case intstr.Int: return int64(port.IntVal), nil } diff --git a/pkg/k8s/pod_utils_test.go b/pkg/k8s/pod_utils_test.go index 9ec5f5b09..dba51a770 100644 --- a/pkg/k8s/pod_utils_test.go +++ b/pkg/k8s/pod_utils_test.go @@ -1,12 +1,13 @@ package k8s import ( + "testing" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" - "testing" ) func TestIsPodHasReadinessGate(t *testing.T) { @@ -178,6 +179,7 @@ func TestGetPodCondition(t *testing.T) { } func TestLookupContainerPort(t *testing.T) { + initContainerRestartPolicyAlways := corev1.ContainerRestartPolicyAlways pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Namespace: "ns", @@ -205,6 +207,28 @@ func TestLookupContainerPort(t *testing.T) { }, }, }, + InitContainers: []corev1.Container{ + { + RestartPolicy: &initContainerRestartPolicyAlways, + Ports: []corev1.ContainerPort{ + { + ContainerPort: 53, + }, + { + Name: "ftp", + ContainerPort: 21, + }, + }, + }, + { + Ports: []corev1.ContainerPort{ + { + Name: "smtp", + ContainerPort: 25, + }, + }, + }, + }, }, } type args struct { @@ -233,6 +257,14 @@ func TestLookupContainerPort(t *testing.T) { }, want: 80, }, + { + name: "named pod within pod spec (as an initContainer (sidecar)) can be found", + args: args{ + pod: pod, + port: intstr.FromString("ftp"), + }, + want: 21, + }, { name: "named pod within pod spec cannot be found", args: args{ @@ -241,6 +273,14 @@ func TestLookupContainerPort(t *testing.T) { }, wantErr: errors.New("unable to find port https on pod ns/default"), }, + { + name: "named pod within initContainer that is not a sidecar cannot be found", + args: args{ + pod: pod, + port: intstr.FromString("smtp"), + }, + wantErr: errors.New("unable to find port smtp on pod ns/default"), + }, { name: "numerical pod within pod spec can be found", args: args{ @@ -249,6 +289,14 @@ func TestLookupContainerPort(t *testing.T) { }, want: 9999, }, + { + name: "numerical pod within pod spec (as an initContainer (sidecar)) can be found", + args: args{ + pod: pod, + port: intstr.FromInt(53), + }, + want: 53, + }, { name: "numerical pod not within pod spec should still be found", args: args{