Skip to content

Commit

Permalink
add unit test on fixed ingress PE
Browse files Browse the repository at this point in the history
  • Loading branch information
haouc committed Dec 6, 2023
1 parent 42d3991 commit 3a31ba1
Show file tree
Hide file tree
Showing 2 changed files with 230 additions and 16 deletions.
23 changes: 8 additions & 15 deletions pkg/resolvers/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,6 @@ type EndpointsResolver interface {
[]policyinfo.PodEndpoint, error)
}

type RuleType string

const (
Ingress RuleType = "ingress"
Egress RuleType = "egress"
)

// NewEndpointsResolver constructs a new defaultEndpointsResolver
func NewEndpointsResolver(k8sClient client.Client, logger logr.Logger) *defaultEndpointsResolver {
return &defaultEndpointsResolver{
Expand Down Expand Up @@ -71,7 +64,7 @@ func (r *defaultEndpointsResolver) computeIngressEndpoints(ctx context.Context,
ingressEndpoints = append(ingressEndpoints, r.getAllowAllNetworkPeers(rule.Ports)...)
continue
}
resolvedPeers, err := r.resolveNetworkPeers(ctx, policy, rule.From, rule.Ports, Ingress)
resolvedPeers, err := r.resolveNetworkPeers(ctx, policy, rule.From, rule.Ports, networking.PolicyTypeIngress)
if err != nil {
return nil, errors.Wrap(err, "unable to resolve ingress network peers")
}
Expand All @@ -89,7 +82,7 @@ func (r *defaultEndpointsResolver) computeEgressEndpoints(ctx context.Context, p
egressEndpoints = append(egressEndpoints, r.getAllowAllNetworkPeers(rule.Ports)...)
continue
}
resolvedPeers, err := r.resolveNetworkPeers(ctx, policy, rule.To, rule.Ports, Egress)
resolvedPeers, err := r.resolveNetworkPeers(ctx, policy, rule.To, rule.Ports, networking.PolicyTypeEgress)
if err != nil {
return nil, errors.Wrap(err, "unable to resolve egress network peers")
}
Expand Down Expand Up @@ -156,7 +149,7 @@ func (r *defaultEndpointsResolver) getAllowAllNetworkPeers(ports []networking.Ne
}

func (r *defaultEndpointsResolver) resolveNetworkPeers(ctx context.Context, policy *networking.NetworkPolicy,
peers []networking.NetworkPolicyPeer, ports []networking.NetworkPolicyPort, ruleType RuleType) ([]policyinfo.EndpointInfo, error) {
peers []networking.NetworkPolicyPeer, ports []networking.NetworkPolicyPort, policyType networking.PolicyType) ([]policyinfo.EndpointInfo, error) {
var networkPeers []policyinfo.EndpointInfo
for _, peer := range peers {
if peer.IPBlock != nil {
Expand Down Expand Up @@ -195,12 +188,12 @@ func (r *defaultEndpointsResolver) resolveNetworkPeers(ctx context.Context, poli

var portsToApply []policyinfo.Port
// populate the policy applied targets' ports
if ruleType == Ingress {
if policyType == networking.PolicyTypeIngress {
portsToApply = r.getIngressRulesPorts(ctx, policy.Namespace, &policy.Spec.PodSelector, ports)
}

for _, ns := range namespaces {
networkPeers = append(networkPeers, r.getMatchingPodAddresses(ctx, peer.PodSelector, ns, portsToApply, ports, ruleType)...)
networkPeers = append(networkPeers, r.getMatchingPodAddresses(ctx, peer.PodSelector, ns, portsToApply, ports, policyType)...)
}

}
Expand Down Expand Up @@ -314,7 +307,7 @@ func (r *defaultEndpointsResolver) resolveNamespaces(ctx context.Context, ls *me
}

func (r *defaultEndpointsResolver) getMatchingPodAddresses(ctx context.Context, ls *metav1.LabelSelector, namespace string,
policyPorts []policyinfo.Port, ports []networking.NetworkPolicyPort, rule RuleType) []policyinfo.EndpointInfo {
policyPorts []policyinfo.Port, ports []networking.NetworkPolicyPort, rule networking.PolicyType) []policyinfo.EndpointInfo {
var addresses []policyinfo.EndpointInfo

podList := &corev1.PodList{}
Expand All @@ -338,8 +331,8 @@ func (r *defaultEndpointsResolver) getMatchingPodAddresses(ctx context.Context,
}
addresses = append(addresses, policyinfo.EndpointInfo{
CIDR: policyinfo.NetworkAddress(podIP),
Ports: func(ruleType RuleType) []policyinfo.Port {
if ruleType == Ingress {
Ports: func(policyType networking.PolicyType) []policyinfo.Port {
if policyType == networking.PolicyTypeIngress {
return policyPorts
}
return portList
Expand Down
223 changes: 222 additions & 1 deletion pkg/resolvers/endpoints_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package resolvers

import (
"context"
"fmt"
"sort"
"testing"

Expand Down Expand Up @@ -197,7 +198,7 @@ func TestEndpointsResolver_Resolve(t *testing.T) {
serviceListCalls []serviceListCall
}
protocolTCP := corev1.ProtocolTCP
protocolUDP := corev1.ProtocolTCP
protocolUDP := corev1.ProtocolUDP
port80 := int32(80)
intOrStrPort80 := intstr.FromInt(int(port80))
intOrStrPortName := intstr.FromString("port-name")
Expand Down Expand Up @@ -631,10 +632,230 @@ func TestEndpointsResolver_Resolve(t *testing.T) {
})
}

fmt.Println(ingressEndpoints)

assert.Equal(t, tt.wantIngressEndpoints, ingressEndpoints)
assert.Equal(t, tt.wantEgressEndpoints, egressEndpoints)
assert.Equal(t, tt.wantPodEndpoints, podEndpoints)
}
})
}
}

func TestEndpointsResolver_ResolveNetworkPeers(t *testing.T) {
protocolTCP := corev1.ProtocolTCP
port80 := int32(80)
port8080 := int32(8080)
port9090 := int32(9090)

srcPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod1",
Namespace: "src",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "pod1",
Ports: []corev1.ContainerPort{
{
ContainerPort: port80,
Protocol: corev1.ProtocolTCP,
Name: "test-port",
},
},
},
},
},
Status: corev1.PodStatus{
PodIP: "1.0.0.1",
},
}
dstPod := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "pod2",
Namespace: "dst",
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "pod2",
Ports: []corev1.ContainerPort{
{
ContainerPort: port8080,
Protocol: corev1.ProtocolTCP,
Name: "test-port",
},
},
},
},
},
Status: corev1.PodStatus{
PodIP: "1.0.0.2",
},
}

policy := &networking.NetworkPolicy{
ObjectMeta: metav1.ObjectMeta{
Name: "netpol",
Namespace: "dst",
},
Spec: networking.NetworkPolicySpec{
PodSelector: metav1.LabelSelector{},
PolicyTypes: []networking.PolicyType{networking.PolicyTypeIngress, networking.PolicyTypeEgress},
Ingress: []networking.NetworkPolicyIngressRule{
{
From: []networking.NetworkPolicyPeer{
{
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"kubernetes.io/metadata.name": "src",
},
},
},
},
Ports: []networking.NetworkPolicyPort{
{
Protocol: &protocolTCP,
Port: &intstr.IntOrString{Type: intstr.String, StrVal: "test-port"},
},
},
},
},
Egress: []networking.NetworkPolicyEgressRule{
{
To: []networking.NetworkPolicyPeer{
{
NamespaceSelector: &metav1.LabelSelector{
MatchLabels: map[string]string{
"kubernetes.io/metadata.name": "src",
},
},
},
},
Ports: []networking.NetworkPolicyPort{
{
Protocol: &protocolTCP,
Port: &intstr.IntOrString{Type: intstr.Int, IntVal: port8080},
EndPort: &port9090,
},
},
},
},
},
}

ctrl := gomock.NewController(t)
defer ctrl.Finish()

mockClient := mock_client.NewMockClient(ctrl)
resolver := NewEndpointsResolver(mockClient, logr.New(&log.NullLogSink{}))

var ingressEndpoints []policyinfo.EndpointInfo
var egressEndpoints []policyinfo.EndpointInfo
ctx := context.TODO()
for _, rule := range policy.Spec.Ingress {
namespaces := []corev1.Namespace{
{
ObjectMeta: metav1.ObjectMeta{
Name: "src",
},
},
}

nsList := &corev1.NamespaceList{}
podList := &corev1.PodList{}

gomock.InOrder(
mockClient.EXPECT().List(gomock.Any(), nsList, gomock.Any()).DoAndReturn(
func(ctx context.Context, nsList *corev1.NamespaceList, opts ...client.ListOption) error {
for _, ns := range namespaces {
nsList.Items = append(nsList.Items, *(ns.DeepCopy()))
}
return nil
},
),
// getting ingress endpoint calls listing pods with dst NS first
mockClient.EXPECT().List(gomock.Any(), podList, gomock.Any()).DoAndReturn(
func(ctx context.Context, podList *corev1.PodList, opts ...client.ListOption) error {
podList.Items = []corev1.Pod{dstPod}
return nil
},
),
// getting ingress endpoint calls then listing pods with src NS for CIDRs
mockClient.EXPECT().List(gomock.Any(), podList, gomock.Any()).DoAndReturn(
func(ctx context.Context, podList *corev1.PodList, opts ...client.ListOption) error {
podList.Items = []corev1.Pod{srcPod}
return nil
},
),
)
if rule.From == nil {
ingressEndpoints = append(ingressEndpoints, resolver.getAllowAllNetworkPeers(rule.Ports)...)
continue
}
resolvedPeers, err := resolver.resolveNetworkPeers(ctx, policy, rule.From, rule.Ports, networking.PolicyTypeIngress)
assert.NoError(t, err)
ingressEndpoints = append(ingressEndpoints, resolvedPeers...)

dstNS := corev1.Namespace{
ObjectMeta: metav1.ObjectMeta{
Name: "dst",
},
}

svcList := &corev1.ServiceList{}
gomock.InOrder(
mockClient.EXPECT().List(gomock.Any(), nsList, gomock.Any()).DoAndReturn(
func(ctx context.Context, nsList *corev1.NamespaceList, opts ...client.ListOption) error {
nsList.Items = []corev1.Namespace{dstNS}
return nil
},
),
mockClient.EXPECT().List(gomock.Any(), podList, gomock.Any()).DoAndReturn(
func(ctx context.Context, podList *corev1.PodList, opts ...client.ListOption) error {
podList.Items = []corev1.Pod{dstPod}
return nil
},
),
mockClient.EXPECT().List(gomock.Any(), nsList, gomock.Any()).DoAndReturn(
func(ctx context.Context, nsList *corev1.NamespaceList, opts ...client.ListOption) error {
nsList.Items = []corev1.Namespace{dstNS}
return nil
},
),
mockClient.EXPECT().List(gomock.Any(), svcList, gomock.Any()).DoAndReturn(
func(ctx context.Context, svcList *corev1.ServiceList, opts ...client.ListOption) error {
svcList.Items = []corev1.Service{}
return nil
},
),
)

for _, rule := range policy.Spec.Egress {
resolver.logger.V(1).Info("computing egress addresses", "peers", rule.To)
if rule.To == nil {
egressEndpoints = append(egressEndpoints, resolver.getAllowAllNetworkPeers(rule.Ports)...)
continue
}
resolvedPeers, err := resolver.resolveNetworkPeers(ctx, policy, rule.To, rule.Ports, networking.PolicyTypeEgress)
assert.NoError(t, err)
resolvedClusterIPs, err := resolver.resolveServiceClusterIPs(ctx, rule.To, policy.Namespace, rule.Ports)
assert.NoError(t, err)
egressEndpoints = append(egressEndpoints, resolvedPeers...)
egressEndpoints = append(egressEndpoints, resolvedClusterIPs...)
}
}

for _, ingPE := range ingressEndpoints {
assert.Equal(t, srcPod.Status.PodIP, string(ingPE.CIDR))
assert.Equal(t, dstPod.Spec.Containers[0].Ports[0].ContainerPort, *ingPE.Ports[0].Port)
}

for _, egPE := range egressEndpoints {
assert.Equal(t, dstPod.Status.PodIP, string(egPE.CIDR))
assert.Equal(t, dstPod.Spec.Containers[0].Ports[0].ContainerPort, *egPE.Ports[0].Port)
assert.Equal(t, policy.Spec.Egress[0].Ports[0].Port.IntVal, *egPE.Ports[0].Port)
assert.Equal(t, *policy.Spec.Egress[0].Ports[0].EndPort, *egPE.Ports[0].EndPort)
}
}

0 comments on commit 3a31ba1

Please sign in to comment.