diff --git a/conformance/tests/admin-network-policy-core-egress-sctp-rules_base.yaml b/conformance/base/admin_network_policy/core-egress-sctp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-egress-sctp-rules_base.yaml rename to conformance/base/admin_network_policy/core-egress-sctp-rules.yaml diff --git a/conformance/tests/admin-network-policy-core-egress-tcp-rules_base.yaml b/conformance/base/admin_network_policy/core-egress-tcp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-egress-tcp-rules_base.yaml rename to conformance/base/admin_network_policy/core-egress-tcp-rules.yaml diff --git a/conformance/tests/admin-network-policy-core-egress-udp-rules_base.yaml b/conformance/base/admin_network_policy/core-egress-udp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-egress-udp-rules_base.yaml rename to conformance/base/admin_network_policy/core-egress-udp-rules.yaml diff --git a/conformance/tests/admin-network-policy-core-ingress-sctp-rules_base.yaml b/conformance/base/admin_network_policy/core-ingress-sctp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-ingress-sctp-rules_base.yaml rename to conformance/base/admin_network_policy/core-ingress-sctp-rules.yaml diff --git a/conformance/tests/admin-network-policy-core-ingress-tcp-rules_base.yaml b/conformance/base/admin_network_policy/core-ingress-tcp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-ingress-tcp-rules_base.yaml rename to conformance/base/admin_network_policy/core-ingress-tcp-rules.yaml diff --git a/conformance/tests/admin-network-policy-core-ingress-udp-rules_base.yaml b/conformance/base/admin_network_policy/core-ingress-udp-rules.yaml similarity index 100% rename from conformance/tests/admin-network-policy-core-ingress-udp-rules_base.yaml rename to conformance/base/admin_network_policy/core-ingress-udp-rules.yaml diff --git a/conformance/base/baseline_admin_network_policy/core-egress-sctp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-egress-sctp-rules.yaml new file mode 100644 index 00000000..a7024c1a --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-egress-sctp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + egress: + - name: "allow-to-gryffindor-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-gryffindor-everything" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-to-slytherin-at-port-9003" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "allow-to-hufflepuff-at-port-9003" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "deny-to-hufflepuff-everything-else" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/conformance/base/baseline_admin_network_policy/core-egress-tcp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-egress-tcp-rules.yaml new file mode 100644 index 00000000..c5a4e401 --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-egress-tcp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + egress: + - name: "allow-to-ravenclaw-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-to-ravenclaw-everything" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-to-slytherin-at-port-80" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: TCP + port: 80 + - name: "allow-to-hufflepuff-at-port-8080" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: TCP + port: 8080 + - name: "deny-to-hufflepuff-everything-else" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/conformance/base/baseline_admin_network_policy/core-egress-udp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-egress-udp-rules.yaml new file mode 100644 index 00000000..d8f1580c --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-egress-udp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + egress: + - name: "allow-to-ravenclaw-everything" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-to-ravenclaw-everything" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-to-slytherin-at-port-5353" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: UDP + port: 5353 + - name: "allow-to-gryffindor-at-port-53" + action: "Allow" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + ports: + - portNumber: + protocol: UDP + port: 53 + - name: "deny-to-gryffindor-everything-else" + action: "Deny" + to: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor diff --git a/conformance/base/baseline_admin_network_policy/core-ingress-sctp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-ingress-sctp-rules.yaml new file mode 100644 index 00000000..91448f3e --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-ingress-sctp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + ingress: + - name: "allow-from-gryffindor-everything" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-from-gryffindor-everything" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + - name: "deny-from-slytherin-at-port-9003" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "allow-from-hufflepuff-at-port-9003" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: SCTP + port: 9003 + - name: "deny-from-hufflepuff-everything-else" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/conformance/base/baseline_admin_network_policy/core-ingress-tcp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-ingress-tcp-rules.yaml new file mode 100644 index 00000000..9931c58e --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-ingress-tcp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + ingress: + - name: "allow-from-ravenclaw-everything" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-from-ravenclaw-everything" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-from-slytherin-at-port-80" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: TCP + port: 80 + - name: "allow-from-hufflepuff-at-port-80" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ports: + - portNumber: + protocol: TCP + port: 80 + - name: "deny-from-hufflepuff-everything-else" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff diff --git a/conformance/base/baseline_admin_network_policy/core-ingress-udp-rules.yaml b/conformance/base/baseline_admin_network_policy/core-ingress-udp-rules.yaml new file mode 100644 index 00000000..9b07fd8f --- /dev/null +++ b/conformance/base/baseline_admin_network_policy/core-ingress-udp-rules.yaml @@ -0,0 +1,53 @@ +apiVersion: policy.networking.k8s.io/v1alpha1 +kind: BaselineAdminNetworkPolicy +metadata: + name: default +spec: + subject: + namespaces: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-hufflepuff + ingress: + - name: "allow-from-ravenclaw-everything" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-from-ravenclaw-everything" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-ravenclaw + - name: "deny-from-slytherin-at-port-5353" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-slytherin + ports: + - portNumber: + protocol: UDP + port: 5353 + - name: "allow-from-gryffindor-at-port-53" + action: "Allow" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor + ports: + - portNumber: + protocol: UDP + port: 53 + - name: "deny-from-gryffindor-everything-else" + action: "Deny" + from: + - namespaces: + namespaceSelector: + matchLabels: + kubernetes.io/metadata.name: network-policy-conformance-gryffindor diff --git a/conformance/tests/admin-network-policy-core-egress-sctp-rules.go b/conformance/tests/admin-network-policy-core-egress-sctp-rules.go index fe8c97d2..3d4f5380 100644 --- a/conformance/tests/admin-network-policy-core-egress-sctp-rules.go +++ b/conformance/tests/admin-network-policy-core-egress-sctp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyEgressSCTP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-egress-sctp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-egress-sctp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-egress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/admin-network-policy-core-egress-tcp-rules.go b/conformance/tests/admin-network-policy-core-egress-tcp-rules.go index 05ff7474..b2d7fda6 100644 --- a/conformance/tests/admin-network-policy-core-egress-tcp-rules.go +++ b/conformance/tests/admin-network-policy-core-egress-tcp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyEgressTCP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-egress-tcp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-egress-tcp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-egress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/admin-network-policy-core-egress-udp-rules.go b/conformance/tests/admin-network-policy-core-egress-udp-rules.go index 894be352..c634a1ba 100644 --- a/conformance/tests/admin-network-policy-core-egress-udp-rules.go +++ b/conformance/tests/admin-network-policy-core-egress-udp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyEgressUDP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-egress-udp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-egress-udp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-egress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/admin-network-policy-core-ingress-sctp-rules.go b/conformance/tests/admin-network-policy-core-ingress-sctp-rules.go index da15aa3c..4de4e1e1 100644 --- a/conformance/tests/admin-network-policy-core-ingress-sctp-rules.go +++ b/conformance/tests/admin-network-policy-core-ingress-sctp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyIngressSCTP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-ingress-sctp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-ingress-sctp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-ingress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/admin-network-policy-core-ingress-tcp-rules.go b/conformance/tests/admin-network-policy-core-ingress-tcp-rules.go index 88a0e44d..6b43f56f 100644 --- a/conformance/tests/admin-network-policy-core-ingress-tcp-rules.go +++ b/conformance/tests/admin-network-policy-core-ingress-tcp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyIngressTCP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-ingress-tcp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-ingress-tcp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-ingress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/admin-network-policy-core-ingress-udp-rules.go b/conformance/tests/admin-network-policy-core-ingress-udp-rules.go index ac710107..f8f2c2f6 100644 --- a/conformance/tests/admin-network-policy-core-ingress-udp-rules.go +++ b/conformance/tests/admin-network-policy-core-ingress-udp-rules.go @@ -42,7 +42,7 @@ var AdminNetworkPolicyIngressUDP = suite.ConformanceTest{ Features: []suite.SupportedFeature{ suite.SupportAdminNetworkPolicy, }, - Manifests: []string{"tests/admin-network-policy-core-ingress-udp-rules_base.yaml"}, + Manifests: []string{"base/admin_network_policy/core-ingress-udp-rules.yaml"}, Test: func(t *testing.T, s *suite.ConformanceTestSuite) { t.Run("Should support an 'allow-ingress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { diff --git a/conformance/tests/baseline-admin-network-policy-core-egress-sctp-rules.go b/conformance/tests/baseline-admin-network-policy-core-egress-sctp-rules.go new file mode 100644 index 00000000..b0ee1f11 --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-egress-sctp-rules.go @@ -0,0 +1,151 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyEgressSCTP, + ) +} + +var BaselineAdminNetworkPolicyEgressSCTP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyEgressSCTP", + Description: "Tests support for egress traffic (SCTP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-egress-sctp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-egress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-0 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure egress is ALLOWED to gryffindor from ravenclaw + // egressRule at index0 will take precedence over egressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-egress' policy for SCTP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-1 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure egress is ALLOWED to hufflepuff from ravenclaw at port 9003; egressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + // ensure egress is DENIED to hufflepuff from ravenclaw for rest of the traffic; egressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-egress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-0 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the baseline admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Egress[0] + banp.Spec.Egress[0] = banp.DeepCopy().Spec.Egress[1] + banp.Spec.Egress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the baseline admin network policy") + // luna-lovegood-0 is our client pod in gryffindor namespace + // ensure egress is DENIED to gryffindor from ravenclaw + // egressRule at index0 will take precedence over egressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-egress' policy for SCTP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // draco-malfoy-0 is our server pod in slytherin namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-slytherin", + Name: "draco-malfoy-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure egress to slytherin is DENIED from ravenclaw at port 9003; egressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + // ensure egress to slytherin is ALLOWED from ravenclaw for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +} diff --git a/conformance/tests/baseline-admin-network-policy-core-egress-tcp-rules.go b/conformance/tests/baseline-admin-network-policy-core-egress-tcp-rules.go new file mode 100644 index 00000000..3afa9503 --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-egress-tcp-rules.go @@ -0,0 +1,150 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyEgressTCP, + ) +} + +var BaselineAdminNetworkPolicyEgressTCP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyEgressTCP", + Description: "Tests support for egress traffic (TCP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-egress-tcp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-egress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-0 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure egress is ALLOWED to ravenclaw from gryffindor + // egressRule at index0 will take precedence over egressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-egress' policy for TCP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-1 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure egress is ALLOWED to hufflepuff from gryffindor at port 80; egressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // harry-potter-1 is our client pod in gryffindor namespace + // ensure egress is DENIED to hufflepuff from gryffindor for rest of the traffic; egressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-egress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-1 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the baseline admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Egress[0] + banp.Spec.Egress[0] = banp.DeepCopy().Spec.Egress[1] + banp.Spec.Egress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the baseline admin network policy") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure egress is DENIED to ravenclaw from gryffindor + // egressRule at index0 will take precedence over egressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // harry-potter-1 is our client pod in gryffindor namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-egress' policy for TCP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // draco-malfoy-0 is our server pod in slytherin namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-slytherin", + Name: "draco-malfoy-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure egress to slytherin is DENIED from gryffindor at port 80; egressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // harry-potter-1 is our client pod in gryffindor namespace + // ensure egress to slytherin is ALLOWED from gryffindor for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +} diff --git a/conformance/tests/baseline-admin-network-policy-core-egress-udp-rules.go b/conformance/tests/baseline-admin-network-policy-core-egress-udp-rules.go new file mode 100644 index 00000000..e3c034fa --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-egress-udp-rules.go @@ -0,0 +1,151 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyEgressUDP, + ) +} + +var BaselineAdminNetworkPolicyEgressUDP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyEgressUDP", + Description: "Tests support for egress traffic (UDP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-egress-udp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-egress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-0 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure egress is ALLOWED to ravenclaw from hufflepuff + // egressRule at index0 will take precedence over egressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // cedric-diggory-1 is our client pod in hufflepuff namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-egress' policy for UDP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-1 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure egress is ALLOWED to gryffindor from hufflepuff at port 53; egressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // cedric-diggory-1 is our client pod in hufflepuff namespace + // ensure egress is DENIED to gryffindor from hufflepuff for rest of the traffic; egressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-egress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-1 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the baseline admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Egress[0] + banp.Spec.Egress[0] = banp.DeepCopy().Spec.Egress[1] + banp.Spec.Egress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the baseline admin network policy") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure egress is DENIED to ravenclaw to hufflepuff + // egressRule at index0 will take precedence over egressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // cedric-diggory-1 is our client pod in hufflepuff namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-egress' policy for UDP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // draco-malfoy-0 is our server pod in slytherin namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-slytherin", + Name: "draco-malfoy-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure egress to slytherin is DENIED from hufflepuff at port 80; egressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure egress to slytherin is ALLOWED from hufflepuff for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +} diff --git a/conformance/tests/baseline-admin-network-policy-core-ingress-sctp-rules.go b/conformance/tests/baseline-admin-network-policy-core-ingress-sctp-rules.go new file mode 100644 index 00000000..69eafb1d --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-ingress-sctp-rules.go @@ -0,0 +1,150 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyIngressSCTP, + ) +} + +var BaselineAdminNetworkPolicyIngressSCTP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyIngressSCTP", + Description: "Tests support for ingress traffic (SCTP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-ingress-sctp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-ingress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-0 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure ingress is ALLOWED from gryffindor to ravenclaw + // ingressRule at index0 will take precedence over ingressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-ingress' policy for SCTP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-1 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure ingress is ALLOWED from hufflepuff to ravenclaw at port 9003; ingressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // cedric-diggory-1 is our client pod in hufflepuff namespace + // ensure ingress is DENIED from hufflepuff to ravenclaw for rest of the traffic; ingressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-ingress' policy for SCTP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-1 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the baseline admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Ingress[0] + banp.Spec.Ingress[0] = banp.DeepCopy().Spec.Ingress[1] + banp.Spec.Ingress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the baseline admin network policy") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure ingress is DENIED from gryffindor to ravenclaw + // ingressRule at index0 will take precedence over ingressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // harry-potter-1 is our client pod in gryffindor namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-ingress' policy for SCTP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // luna-lovegood-0 is our server pod in ravenclaw namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-ravenclaw", + Name: "luna-lovegood-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // draco-malfoy-0 is our client pod in slytherin namespace + // ensure ingress from slytherin is DENIED to ravenclaw at port 9003; ingressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-0", "sctp", + clientPod.Status.PodIP, int32(9003), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // draco-malfoy-1 is our client pod in slytherin namespace + // ensure ingress from slytherin is ALLOWED to ravenclaw for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-1", "sctp", + clientPod.Status.PodIP, int32(9005), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +} diff --git a/conformance/tests/baseline-admin-network-policy-core-ingress-tcp-rules.go b/conformance/tests/baseline-admin-network-policy-core-ingress-tcp-rules.go new file mode 100644 index 00000000..f4cc5d2b --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-ingress-tcp-rules.go @@ -0,0 +1,150 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyIngressTCP, + ) +} + +var BaselineAdminNetworkPolicyIngressTCP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyIngressTCP", + Description: "Tests support for ingress traffic (TCP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-ingress-tcp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-ingress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-0 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure ingress is ALLOWED from ravenclaw to gryffindor + // ingressRule at index0 will take precedence over ingressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-ingress' policy for TCP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-1 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // cedric-diggory-0 is our client pod in hufflepuff namespace + // ensure ingress is ALLOWED from hufflepuff to gryffindor at port 80; ingressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // cedric-diggory-1 is our client pod in hufflepuff namespace + // ensure ingress is DENIED from hufflepuff to gryffindor for rest of the traffic; ingressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-hufflepuff", "cedric-diggory-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-ingress' policy for TCP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-1 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the baseline admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Ingress[0] + banp.Spec.Ingress[0] = banp.DeepCopy().Spec.Ingress[1] + banp.Spec.Ingress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the baseline admin network policy") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure ingress is DENIED from ravenclaw to gryffindor + // ingressRule at index0 will take precedence over ingressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-ingress' policy for TCP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // harry-potter-0 is our server pod in gryffindor namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-gryffindor", + Name: "harry-potter-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // draco-malfoy-0 is our client pod in slytherin namespace + // ensure ingress from slytherin is DENIED to gryffindor at port 80; ingressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-0", "tcp", + clientPod.Status.PodIP, int32(80), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // draco-malfoy-1 is our client pod in slytherin namespace + // ensure ingress from slytherin is ALLOWED to gryffindor for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-1", "tcp", + clientPod.Status.PodIP, int32(8080), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +} diff --git a/conformance/tests/baseline-admin-network-policy-core-ingress-udp-rules.go b/conformance/tests/baseline-admin-network-policy-core-ingress-udp-rules.go new file mode 100644 index 00000000..6b7cb083 --- /dev/null +++ b/conformance/tests/baseline-admin-network-policy-core-ingress-udp-rules.go @@ -0,0 +1,150 @@ +/* +Copyright 2022 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package tests + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + "k8s.io/kubernetes/test/e2e/framework" + "sigs.k8s.io/controller-runtime/pkg/client" + + "sigs.k8s.io/network-policy-api/apis/v1alpha1" + "sigs.k8s.io/network-policy-api/conformance/utils/kubernetes" + "sigs.k8s.io/network-policy-api/conformance/utils/suite" +) + +func init() { + ConformanceTests = append(ConformanceTests, + BaselineAdminNetworkPolicyIngressUDP, + ) +} + +var BaselineAdminNetworkPolicyIngressUDP = suite.ConformanceTest{ + ShortName: "BaselineAdminNetworkPolicyIngressUDP", + Description: "Tests support for ingress traffic (UDP protocol) using baseline admin network policy API based on a server and client model", + Features: []suite.SupportedFeature{ + suite.SupportBaselineAdminNetworkPolicy, + }, + Manifests: []string{"base/baseline_admin_network_policy/core-ingress-udp-rules.yaml"}, + Test: func(t *testing.T, s *suite.ConformanceTestSuite) { + + t.Run("Should support an 'allow-ingress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-0 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure ingress is ALLOWED from ravenclaw to hufflepuff + // ingressRule at index0 will take precedence over ingressRule at index1; thus ALLOW takes precedence over DENY since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'allow-ingress' policy for UDP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-1 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // harry-potter-0 is our client pod in gryffindor namespace + // ensure ingress is ALLOWED from gryffindor to hufflepuff at port 53; ingressRule at index5 + success := kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + // harry-potter-1 is our client pod in gryfindor namespace + // ensure ingress is DENIED from gryffindor to hufflepuff for rest of the traffic; ingressRule at index6 + success = kubernetes.PokeServer(t, "network-policy-conformance-gryffindor", "harry-potter-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support an 'deny-ingress' policy for UDP protocol; ensure rule ordering is respected", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-1 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-1", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + banp := &v1alpha1.BaselineAdminNetworkPolicy{} + err = s.Client.Get(ctx, client.ObjectKey{ + Name: "default", + }, banp) + framework.ExpectNoError(err, "unable to fetch the admin network policy") + // swap rules at index0 and index1 + allowRule := banp.DeepCopy().Spec.Ingress[0] + banp.Spec.Ingress[0] = banp.DeepCopy().Spec.Ingress[1] + banp.Spec.Ingress[1] = allowRule + err = s.Client.Update(ctx, banp) + framework.ExpectNoError(err, "unable to update the admin network policy") + // luna-lovegood-0 is our client pod in ravenclaw namespace + // ensure ingress is DENIED from ravenclaw to hufflepuff + // ingressRule at index0 will take precedence over ingressRule at index1; thus DENY takes precedence over ALLOW since rules are ordered + success := kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-0", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // luna-lovegood-1 is our client pod in ravenclaw namespace + success = kubernetes.PokeServer(t, "network-policy-conformance-ravenclaw", "luna-lovegood-1", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + }) + + t.Run("Should support a 'deny-ingress' policy for UDP protocol at the specified port", func(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), s.TimeoutConfig.GetTimeout) + defer cancel() + // This test uses `default` BANP + // cedric-diggory-0 is our server pod in hufflepuff namespace + clientPod := &v1.Pod{} + err := s.Client.Get(ctx, client.ObjectKey{ + Namespace: "network-policy-conformance-hufflepuff", + Name: "cedric-diggory-0", + }, clientPod) + framework.ExpectNoError(err, "unable to fetch the server pod") + // draco-malfoy-0 is our client pod in slytherin namespace + // ensure ingress from slytherin is DENIED to hufflepuff at port 80; ingressRule at index3 + success := kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-0", "udp", + clientPod.Status.PodIP, int32(5353), s.TimeoutConfig.RequestTimeout, false) + assert.Equal(t, true, success) + // draco-malfoy-1 is our client pod in slytherin namespace + // ensure ingress from slytherin is ALLOWED to hufflepuff for rest of the traffic; matches no rules hence allowed + success = kubernetes.PokeServer(t, "network-policy-conformance-slytherin", "draco-malfoy-1", "udp", + clientPod.Status.PodIP, int32(53), s.TimeoutConfig.RequestTimeout, true) + assert.Equal(t, true, success) + }) + }, +}