|
|
|
@@ -119,21 +119,22 @@ and what is happening in practice:
|
|
|
|
|
|
|
|
|
|
var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
f := framework.NewDefaultFramework("netpol")
|
|
|
|
|
var model *Model
|
|
|
|
|
|
|
|
|
|
ginkgo.Context("NetworkPolicy between server and client", func() {
|
|
|
|
|
ginkgo.BeforeEach(func() {
|
|
|
|
|
initializeResourcesByFixedNS(f)
|
|
|
|
|
model = initializeResourcesByFixedNS(f)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.AfterEach(func() {
|
|
|
|
|
if !useFixedNamespaces {
|
|
|
|
|
_, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
framework.ExpectNoError(k8s.deleteNamespaces(model.NamespaceNames), "unable to clean up netpol namespaces")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should support a 'default-deny-ingress' policy [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-ingress", metav1.LabelSelector{}, SetSpecIngressRules())
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
@@ -148,7 +149,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
egressRule.Ports = append(egressRule.Ports, networkingv1.NetworkPolicyPort{Protocol: &protocolUDP, Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53}})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-all-tcp-allow-dns", metav1.LabelSelector{}, SetSpecIngressRules(), SetSpecEgressRules(egressRule))
|
|
|
|
|
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachability := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -168,7 +169,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ingressRule.From = append(ingressRule.From, networkingv1.NetworkPolicyPeer{PodSelector: &allowedPods})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("x-a-allows-x-b", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
|
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachability := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -179,8 +180,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow ingress traffic for a target [Feature:NetworkPolicy] ", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
ginkgo.By("having a deny all ingress policy", func() {
|
|
|
|
|
// Deny all Ingress traffic policy to pods on namespace nsX
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-all", metav1.LabelSelector{}, SetSpecIngressRules())
|
|
|
|
@@ -202,8 +202,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow ingress traffic from pods in all namespaces [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
ingressRule.From = append(ingressRule.From, networkingv1.NetworkPolicyPeer{NamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-from-another-ns", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
@@ -214,7 +213,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow traffic only from a different namespace, based on NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
ingressRule.From = append(ingressRule.From, networkingv1.NetworkPolicyPeer{NamespaceSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"ns": nsY}}})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-client-a-via-ns-selector", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
@@ -240,7 +239,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ingressRule.From = append(ingressRule.From, networkingv1.NetworkPolicyPeer{PodSelector: &allowedPods})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("x-a-allows-x-b", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
|
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachability := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -251,7 +250,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on NamespaceSelector with MatchExpressions[Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
|
|
|
|
Key: "ns",
|
|
|
|
@@ -273,7 +272,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on PodSelector or NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
|
|
|
|
Key: "ns",
|
|
|
|
@@ -299,7 +298,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on PodSelector and NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
|
|
|
|
Key: "ns",
|
|
|
|
@@ -326,7 +325,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on Multiple PodSelectors and NamespaceSelectors [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
|
|
|
|
Key: "ns",
|
|
|
|
@@ -356,8 +355,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on any PodSelectors [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
for _, label := range []map[string]string{{"pod": "b"}, {"pod": "c"}} {
|
|
|
|
|
ingressRule.From = append(ingressRule.From, networkingv1.NetworkPolicyPeer{PodSelector: &metav1.LabelSelector{MatchLabels: label}})
|
|
|
|
@@ -376,7 +374,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -401,7 +399,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on Ports [Feature:NetworkPolicy]", func() {
|
|
|
|
|
ginkgo.By("Creating a network allowPort81Policy which only allows allow listed namespaces (y) to connect on exactly one port (81)")
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -423,7 +421,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce multiple, stacked policies with overlapping podSelectors [Feature:NetworkPolicy]", func() {
|
|
|
|
|
ginkgo.By("Creating a network allowPort81Policy which only allows allow listed namespaces (y) to connect on exactly one port (81)")
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -463,7 +461,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ginkgo.It("should support allow-all policy [Feature:NetworkPolicy]", func() {
|
|
|
|
|
ginkgo.By("Creating a network policy which allows all traffic.")
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-all", map[string]string{}, SetSpecIngressRules(networkingv1.NetworkPolicyIngressRule{}))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Testing pods can connect to both ports when an 'allow-all' policy is present.")
|
|
|
|
@@ -476,7 +474,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
IngressRules := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
IngressRules.Ports = append(IngressRules.Ports, networkingv1.NetworkPolicyPort{Port: &intstr.IntOrString{Type: intstr.String, StrVal: "serve-81-tcp"}})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-all", map[string]string{}, SetSpecIngressRules(IngressRules))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Blocking all ports other then 81 in the entire namespace")
|
|
|
|
@@ -491,7 +489,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should allow ingress access from namespace on one named port [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -524,7 +522,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
egressRule.Ports = append(egressRule.Ports, networkingv1.NetworkPolicyPort{Protocol: &protocolUDP, Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53}})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-egress", map[string]string{}, SetSpecEgressRules(egressRule))
|
|
|
|
|
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachabilityPort80 := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -540,7 +538,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ginkgo.By("Using the simplest possible mutation: start with allow all, then switch to deny all")
|
|
|
|
|
// part 1) allow all
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-all-mutate-to-deny-all", map[string]string{}, SetSpecIngressRules(networkingv1.NetworkPolicyIngressRule{}))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachability := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -556,7 +554,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should allow ingress access from updated namespace [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
defer ResetNamespaceLabels(k8s, nsY)
|
|
|
|
|
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
@@ -588,7 +586,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should allow ingress access from updated pod [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
podXB, err := model.FindPod(nsX, "b")
|
|
|
|
|
framework.ExpectNoError(err, "find pod x/b")
|
|
|
|
|
defer ResetPodLabels(k8s, podXB)
|
|
|
|
@@ -617,7 +615,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should deny ingress from pods on other namespaces [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
|
|
|
|
|
IngressRules := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
IngressRules.From = append(IngressRules.From, networkingv1.NetworkPolicyPeer{PodSelector: &metav1.LabelSelector{MatchLabels: map[string]string{}}})
|
|
|
|
@@ -632,7 +630,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should deny ingress access to updated pod [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
podXA, err := model.FindPod(nsX, "a")
|
|
|
|
|
framework.ExpectNoError(err, "find pod x/a")
|
|
|
|
|
defer ResetPodLabels(k8s, podXA)
|
|
|
|
@@ -653,7 +651,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should deny egress from pods based on PodSelector [Feature:NetworkPolicy] ", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-egress-pod-a", metav1.LabelSelector{MatchLabels: map[string]string{"pod": "a"}}, SetSpecEgressRules())
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
@@ -664,7 +662,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should deny egress from all pods in a namespace [Feature:NetworkPolicy] ", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-egress-ns-x", metav1.LabelSelector{}, SetSpecEgressRules())
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
@@ -696,7 +694,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
policy.Spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress, networkingv1.PolicyTypeIngress}
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
reachabilityPort80 := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -719,7 +717,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
// Ingress on y/a and y/b allow traffic from x/a
|
|
|
|
|
// Expectation: traffic from x/a to y/a allowed only, traffic from x/a to y/b denied by egress policy
|
|
|
|
|
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
|
|
|
|
|
// Building egress policy for x/a to y/a only
|
|
|
|
|
allowedEgressNamespaces := &metav1.LabelSelector{
|
|
|
|
@@ -809,7 +807,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce egress policy allowing traffic to a server in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -834,8 +832,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce ingress policy allowing any port traffic to a server on a specific protocol [Feature:NetworkPolicy] [Feature:UDP]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
ingressRule.Ports = append(ingressRule.Ports, networkingv1.NetworkPolicyPort{Protocol: &protocolTCP})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-ingress-by-proto", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
@@ -850,7 +847,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce multiple ingress policies with ingress allow-all policy taking precedence [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
IngressRules := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
IngressRules.Ports = append(IngressRules.Ports, networkingv1.NetworkPolicyPort{Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 80}})
|
|
|
|
|
policyAllowOnlyPort80 := GenNetworkPolicyWithNameAndPodMatchLabel("allow-ingress-port-80", map[string]string{}, SetSpecIngressRules(IngressRules))
|
|
|
|
@@ -876,7 +873,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
egressRule.Ports = append(egressRule.Ports, networkingv1.NetworkPolicyPort{Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 80}})
|
|
|
|
|
egressRule.Ports = append(egressRule.Ports, networkingv1.NetworkPolicyPort{Protocol: &protocolUDP, Port: &intstr.IntOrString{Type: intstr.Int, IntVal: 53}})
|
|
|
|
|
policyAllowPort80 := GenNetworkPolicyWithNameAndPodMatchLabel("allow-egress-port-80", map[string]string{}, SetSpecEgressRules(egressRule))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policyAllowPort80, nsX)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Making sure ingress doesn't work other than port 80")
|
|
|
|
@@ -899,7 +896,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
// Deny all traffic into and out of "x".
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-all", metav1.LabelSelector{}, SetSpecIngressRules(), SetSpecEgressRules())
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
reachability := NewReachability(model.AllPods(), true)
|
|
|
|
|
|
|
|
|
@@ -921,7 +918,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should allow egress access to server in CIDR block [Feature:NetworkPolicy]", func() {
|
|
|
|
|
// Getting podServer's status to get podServer's IP, to create the CIDR
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
podList, err := f.ClientSet.CoreV1().Pods(nsY).List(context.TODO(), metav1.ListOptions{LabelSelector: "pod=b"})
|
|
|
|
|
framework.ExpectNoError(err, "Failing to list pods in namespace y")
|
|
|
|
|
pod := podList.Items[0]
|
|
|
|
@@ -947,7 +944,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce except clause while egress access to server in CIDR block [Feature:NetworkPolicy]", func() {
|
|
|
|
|
// Getting podServer's status to get podServer's IP, to create the CIDR with except clause
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
podList, err := f.ClientSet.CoreV1().Pods(nsX).List(context.TODO(), metav1.ListOptions{LabelSelector: "pod=a"})
|
|
|
|
|
framework.ExpectNoError(err, "Failing to find pod x/a")
|
|
|
|
|
podA := podList.Items[0]
|
|
|
|
@@ -980,7 +977,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should ensure an IP overlapping both IPBlock.CIDR and IPBlock.Except is allowed [Feature:NetworkPolicy]", func() {
|
|
|
|
|
// Getting podServer's status to get podServer's IP, to create the CIDR with except clause
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
podList, err := f.ClientSet.CoreV1().Pods(nsX).List(context.TODO(), metav1.ListOptions{LabelSelector: "pod=a"})
|
|
|
|
|
framework.ExpectNoError(err, "Failing to find pod x/a")
|
|
|
|
|
podA := podList.Items[0]
|
|
|
|
@@ -1043,7 +1040,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
allowEgressPolicy := GenNetworkPolicyWithNameAndPodSelector("allow-egress-for-target",
|
|
|
|
|
metav1.LabelSelector{MatchLabels: targetLabels}, SetSpecEgressRules(networkingv1.NetworkPolicyEgressRule{}))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, allowEgressPolicy, nsX)
|
|
|
|
|
|
|
|
|
|
allowEgressReachability := NewReachability(model.AllPods(), true)
|
|
|
|
@@ -1063,7 +1060,8 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
// security hole if you fail this test, because you are allowing TCP
|
|
|
|
|
// traffic that is supposed to be blocked.
|
|
|
|
|
ginkgo.It("should not mistakenly treat 'protocol: SCTP' as 'protocol: TCP', even if the plugin doesn't support SCTP [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Creating a default-deny ingress policy.")
|
|
|
|
|
// Empty podSelector blocks the entire namespace
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-ingress", metav1.LabelSelector{}, SetSpecIngressRules())
|
|
|
|
@@ -1089,7 +1087,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
ingressRule.Ports = append(ingressRule.Ports, networkingv1.NetworkPolicyPort{Port: &intstr.IntOrString{IntVal: 80}, Protocol: &protocolSCTP})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-only-sctp-ingress-on-port-80", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Trying to connect to TCP port 81, which should be blocked by implicit isolation.")
|
|
|
|
@@ -1102,7 +1100,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ingressRule := networkingv1.NetworkPolicyIngressRule{}
|
|
|
|
|
ingressRule.Ports = append(ingressRule.Ports, networkingv1.NetworkPolicyPort{Port: &intstr.IntOrString{IntVal: 81}, Protocol: &protocolUDP})
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodMatchLabel("allow-only-udp-ingress-on-port-81", map[string]string{"pod": "a"}, SetSpecIngressRules(ingressRule))
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
|
ginkgo.By("Creating a network policy for the server which allows traffic only via UDP on port 81.")
|
|
|
|
@@ -1113,8 +1111,9 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ValidateOrFail(k8s, model, &TestCase{ToPort: 81, Protocol: v1.ProtocolTCP, Reachability: reachability})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Note that this default ns functionality is maintained by the APIMachinery group, but we test it here anyways because its an important feature.
|
|
|
|
|
ginkgo.It("should enforce policy to allow traffic based on NamespaceSelector with MatchLabels using default ns label [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
v1.LabelMetadataName: nsY,
|
|
|
|
@@ -1132,8 +1131,9 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
ValidateOrFail(k8s, model, &TestCase{ToPort: 80, Protocol: v1.ProtocolTCP, Reachability: reachability})
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// Note that this default ns functionality is maintained by the APIMachinery group, but we test it here anyways because its an important feature.
|
|
|
|
|
ginkgo.It("should enforce policy based on NamespaceSelector with MatchExpressions using default ns label [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchExpressions: []metav1.LabelSelectorRequirement{{
|
|
|
|
|
Key: v1.LabelMetadataName,
|
|
|
|
@@ -1155,7 +1155,7 @@ var _ = common.SIGDescribe("Netpol", func() {
|
|
|
|
|
|
|
|
|
|
var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() {
|
|
|
|
|
f := framework.NewDefaultFramework("udp-network-policy")
|
|
|
|
|
|
|
|
|
|
var model *Model
|
|
|
|
|
ginkgo.BeforeEach(func() {
|
|
|
|
|
// Windows does not support UDP testing via agnhost.
|
|
|
|
|
e2eskipper.SkipIfNodeOSDistroIs("windows")
|
|
|
|
@@ -1163,18 +1163,18 @@ var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.Context("NetworkPolicy between server and client using UDP", func() {
|
|
|
|
|
ginkgo.BeforeEach(func() {
|
|
|
|
|
initializeResourcesByFixedNS(f)
|
|
|
|
|
model = initializeResourcesByFixedNS(f)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.AfterEach(func() {
|
|
|
|
|
if !useFixedNamespaces {
|
|
|
|
|
_, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
framework.ExpectNoError(k8s.deleteNamespaces(model.NamespaceNames), "unable to clean up UDP netpol namespaces")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should support a 'default-deny-ingress' policy [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-all", metav1.LabelSelector{}, SetSpecIngressRules())
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
@@ -1186,7 +1186,7 @@ var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() {
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on Ports [Feature:NetworkPolicy]", func() {
|
|
|
|
|
ginkgo.By("Creating a network policy allowPort81Policy which only allows allow listed namespaces (y) to connect on exactly one port (81)")
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -1207,7 +1207,7 @@ var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() {
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -1234,7 +1234,7 @@ var _ = common.SIGDescribe("Netpol [LinuxOnly]", func() {
|
|
|
|
|
|
|
|
|
|
var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly][Disruptive]", func() {
|
|
|
|
|
f := framework.NewDefaultFramework("sctp-network-policy")
|
|
|
|
|
|
|
|
|
|
var model *Model
|
|
|
|
|
ginkgo.BeforeEach(func() {
|
|
|
|
|
// Windows does not support network policies.
|
|
|
|
|
e2eskipper.SkipIfNodeOSDistroIs("windows")
|
|
|
|
@@ -1243,18 +1243,18 @@ var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly][Disrupt
|
|
|
|
|
ginkgo.Context("NetworkPolicy between server and client using SCTP", func() {
|
|
|
|
|
ginkgo.BeforeEach(func() {
|
|
|
|
|
addSCTPContainers = true
|
|
|
|
|
initializeResourcesByFixedNS(f)
|
|
|
|
|
model = initializeResourcesByFixedNS(f)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.AfterEach(func() {
|
|
|
|
|
if !useFixedNamespaces {
|
|
|
|
|
_, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
framework.ExpectNoError(k8s.deleteNamespaces(model.NamespaceNames), "unable to clean up SCTP netpol namespaces")
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should support a 'default-deny-ingress' policy [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, _, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
policy := GenNetworkPolicyWithNameAndPodSelector("deny-all", metav1.LabelSelector{}, SetSpecIngressRules())
|
|
|
|
|
CreatePolicy(k8s, policy, nsX)
|
|
|
|
|
|
|
|
|
@@ -1266,7 +1266,7 @@ var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly][Disrupt
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy based on Ports [Feature:NetworkPolicy]", func() {
|
|
|
|
|
ginkgo.By("Creating a network allowPort81Policy which only allows allow listed namespaces (y) to connect on exactly one port (81)")
|
|
|
|
|
nsX, nsY, nsZ, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, nsZ, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedLabels := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -1286,7 +1286,7 @@ var _ = common.SIGDescribe("Netpol [Feature:SCTPConnectivity][LinuxOnly][Disrupt
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
ginkgo.It("should enforce policy to allow traffic only from a pod in a different namespace based on PodSelector and NamespaceSelector [Feature:NetworkPolicy]", func() {
|
|
|
|
|
nsX, nsY, _, model, k8s := getK8SModel(f)
|
|
|
|
|
nsX, nsY, _, k8s := getK8sNamespaces(f)
|
|
|
|
|
allowedNamespaces := &metav1.LabelSelector{
|
|
|
|
|
MatchLabels: map[string]string{
|
|
|
|
|
"ns": nsY,
|
|
|
|
@@ -1338,24 +1338,18 @@ func defaultModel(namespaces []string, dnsDomain string) *Model {
|
|
|
|
|
return NewModel(namespaces, []string{"a", "b", "c"}, []int32{80, 81}, protocols, dnsDomain)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getK8sModel generates a network policy model using the framework's root namespace and cluster DNS domain.
|
|
|
|
|
// This function is deterministic and has no side effects, so may be safely called multiple times.
|
|
|
|
|
func getK8SModel(f *framework.Framework) (string, string, string, *Model, *kubeManager) {
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
rootNs := f.Namespace.GetName()
|
|
|
|
|
nsX, nsY, nsZ, namespaces := getNamespaces(rootNs)
|
|
|
|
|
|
|
|
|
|
model := defaultModel(namespaces, framework.TestContext.ClusterDNSDomain)
|
|
|
|
|
|
|
|
|
|
return nsX, nsY, nsZ, model, k8s
|
|
|
|
|
// getK8sNamespaces returns the canonical set of namespaces using the framework's root namespace
|
|
|
|
|
func getK8sNamespaces(f *framework.Framework) (string, string, string, *kubeManager) {
|
|
|
|
|
nsX, nsY, nsZ, _ := getNamespaces(f.Namespace.GetName())
|
|
|
|
|
return nsX, nsY, nsZ, newKubeManager(f)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// initializeResourcesByFixedNS uses the e2e framework to create all necessary namespace resources, cleaning up
|
|
|
|
|
// network policies from the namespace if useFixedNamespace is set true, avoiding policies overlap of new tests.
|
|
|
|
|
func initializeResourcesByFixedNS(f *framework.Framework) {
|
|
|
|
|
func initializeResourcesByFixedNS(f *framework.Framework) *Model {
|
|
|
|
|
if useFixedNamespaces {
|
|
|
|
|
_ = initializeResources(f)
|
|
|
|
|
_, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
model, _ := initializeResources(f)
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
framework.ExpectNoError(k8s.cleanNetworkPolicies(model.NamespaceNames), "unable to clean network policies")
|
|
|
|
|
err := wait.Poll(waitInterval, waitTimeout, func() (done bool, err error) {
|
|
|
|
|
for _, ns := range model.NamespaceNames {
|
|
|
|
@@ -1368,26 +1362,37 @@ func initializeResourcesByFixedNS(f *framework.Framework) {
|
|
|
|
|
return true, nil
|
|
|
|
|
})
|
|
|
|
|
framework.ExpectNoError(err, "unable to wait for network policy deletion")
|
|
|
|
|
return model
|
|
|
|
|
} else {
|
|
|
|
|
framework.Logf("Using %v as the default dns domain for this cluster... ", framework.TestContext.ClusterDNSDomain)
|
|
|
|
|
framework.ExpectNoError(initializeResources(f), "unable to initialize resources")
|
|
|
|
|
model, err := initializeResources(f)
|
|
|
|
|
framework.ExpectNoError(err, "unable to initialize resources")
|
|
|
|
|
return model
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// initializeResources uses the e2e framework to create all necessary namespace resources, based on the network policy
|
|
|
|
|
// model derived from the framework. It then waits for the resources described by the model to be up and running
|
|
|
|
|
// (i.e. all pods are ready and running in their namespaces).
|
|
|
|
|
func initializeResources(f *framework.Framework) error {
|
|
|
|
|
_, _, _, model, k8s := getK8SModel(f)
|
|
|
|
|
func initializeResources(f *framework.Framework) (*Model, error) {
|
|
|
|
|
k8s := newKubeManager(f)
|
|
|
|
|
rootNs := f.Namespace.GetName()
|
|
|
|
|
_, _, _, namespaces := getNamespaces(rootNs)
|
|
|
|
|
|
|
|
|
|
model := defaultModel(namespaces, framework.TestContext.ClusterDNSDomain)
|
|
|
|
|
|
|
|
|
|
framework.Logf("initializing cluster: ensuring namespaces, deployments, and pods exist and are ready")
|
|
|
|
|
|
|
|
|
|
err := k8s.initializeCluster(model)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return err
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
framework.Logf("finished initializing cluster state")
|
|
|
|
|
|
|
|
|
|
return k8s.waitForHTTPServers(model)
|
|
|
|
|
err = waitForHTTPServers(k8s, model)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
return model, nil
|
|
|
|
|
}
|
|
|
|
|