Skip to content

Commit

Permalink
connectivity: add full egress gateway test suite
Browse files Browse the repository at this point in the history
This commit reimplement the Ginkgo test suite for egress gateway as a
connectivity test for the CLI.

The changes are split in 2 test suites:

* egress-gateway, which tests connectivity for pods matched by an egress
  gateway policy: pod to host, pod to service, pod to external IP, reply
  traffic for services and pods
* egress-gateway-excluded-cidrs, which tests the excludedCIDRs property
  and ensure traffic matching an excluded CIDR does not get masqueraded
  with the egress IP

Signed-off-by: Gilberto Bertin <jibi@cilium.io>
  • Loading branch information
jibi committed May 30, 2023
1 parent c0c2d33 commit 0cca1c7
Show file tree
Hide file tree
Showing 7 changed files with 400 additions and 106 deletions.
7 changes: 7 additions & 0 deletions connectivity/check/context.go
Expand Up @@ -818,6 +818,13 @@ func (ct *ConnectivityTest) PingCommand(peer TestPeer, ipFam IPFamily) []string
return cmd
}

func (ct *ConnectivityTest) DigCommand(peer TestPeer, ipFam IPFamily) []string {
cmd := []string{"dig", "+time=2", "kubernetes"}

cmd = append(cmd, fmt.Sprintf("@%s", peer.Address(ipFam)))
return cmd
}

func (ct *ConnectivityTest) RandomClientPod() *Pod {
for _, p := range ct.clientPods {
return &p
Expand Down
46 changes: 44 additions & 2 deletions connectivity/check/test.go
Expand Up @@ -23,6 +23,7 @@ import (

corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/cloudflare/cfssl/cli/genkey"
Expand Down Expand Up @@ -419,12 +420,24 @@ func (t *Test) WithK8SPolicy(policy string) *Test {
return t
}

const (
NoExcludedCIDRs = iota
ExternalNodeExcludedCIDRs
)

// CiliumEgressGatewayPolicyParams is used to configure how a CiliumEgressGatewayPolicy template should be configured
// before being applied.
type CiliumEgressGatewayPolicyParams struct {
// ExcludedCIDRs controls how the ExcludedCIDRs property should be configured
ExcludedCIDRs int
}

// WithCiliumEgressGatewayPolicy takes a string containing a YAML policy
// document and adds the cilium egress gateway polic(y)(ies) to the scope of the
// Test, to be applied when the test starts running. When calling this method,
// note that the egress gateway enabled feature requirement is applied directly
// here.
func (t *Test) WithCiliumEgressGatewayPolicy(policy string) *Test {
func (t *Test) WithCiliumEgressGatewayPolicy(policy string, params CiliumEgressGatewayPolicyParams) *Test {
pl, err := parseCiliumEgressGatewayPolicyYAML(policy)
if err != nil {
t.Fatalf("Parsing policy YAML: %s", err)
Expand All @@ -445,13 +458,42 @@ func (t *Test) WithCiliumEgressGatewayPolicy(policy string) *Test {
}
}

// Set the egress gateway node
egressGatewayNode := t.EgressGatewayNode()
if egressGatewayNode == "" {
t.Fatalf("Cannot find egress gateway node")
}

// Set the egress gateway node
pl[i].Spec.EgressGateway.NodeSelector.MatchLabels["kubernetes.io/hostname"] = egressGatewayNode

// Set the excluded CIDRs
pl[i].Spec.ExcludedCIDRs = []v2.IPv4CIDR{}

switch params.ExcludedCIDRs {
case ExternalNodeExcludedCIDRs:
for _, nodeWithoutCilium := range t.NodesWithoutCilium() {
var node *corev1.Node

for _, client := range t.Context().Clients() {
n, err := client.GetNode(context.Background(), nodeWithoutCilium, metav1.GetOptions{})
if err == nil {
node = n
break
} else if k8sErrors.IsNotFound(err) {
continue
}

t.Fatalf("Failed to get node object for %s node: %w", nodeWithoutCilium, err)
}

if node == nil {
t.Fatalf("Can't get node object for %s node", nodeWithoutCilium)
}

cidr := v2.IPv4CIDR(fmt.Sprintf("%s/32", node.Status.Addresses[0].Address))
pl[i].Spec.ExcludedCIDRs = append(pl[i].Spec.ExcludedCIDRs, cidr)
}
}
}

if err := t.addCEGPs(pl...); err != nil {
Expand Down
18 changes: 18 additions & 0 deletions connectivity/manifests/egress-gateway-policy-excluded-cidrs.yaml
@@ -0,0 +1,18 @@
apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
name: cegp-sample-excluded-cidrs
spec:
selectors:
- podSelector:
matchLabels:
io.kubernetes.pod.namespace: cilium-test
kind: client
destinationCIDRs:
- 0.0.0.0/0
excludedCIDRs:
- NODE_WITHOUT_CILIUM_PLACEHOLDER/32
egressGateway:
nodeSelector:
matchLabels:
kubernetes.io/hostname: NODE_NAME_PLACEHOLDER
16 changes: 16 additions & 0 deletions connectivity/manifests/egress-gateway-policy.yaml
Expand Up @@ -14,3 +14,19 @@ spec:
nodeSelector:
matchLabels:
kubernetes.io/hostname: NODE_NAME_PLACEHOLDER
---
apiVersion: cilium.io/v2
kind: CiliumEgressGatewayPolicy
metadata:
name: cegp-sample-echo-service
spec:
selectors:
- podSelector:
matchLabels:
kind: echo
destinationCIDRs:
- 0.0.0.0/0
egressGateway:
nodeSelector:
matchLabels:
kubernetes.io/hostname: NODE_NAME_PLACEHOLDER
18 changes: 17 additions & 1 deletion connectivity/suite.go
Expand Up @@ -11,6 +11,8 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/cilium/cilium/pkg/versioncheck"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/manifests/template"
"github.com/cilium/cilium-cli/connectivity/tests"
Expand Down Expand Up @@ -157,6 +159,9 @@ var (

//go:embed manifests/egress-gateway-policy.yaml
egressGatewayPolicyYAML string

//go:embed manifests/egress-gateway-policy-excluded-cidrs.yaml
egressGatewayPolicyExcludedCIDRsYAML string
)

var (
Expand Down Expand Up @@ -727,13 +732,24 @@ func Run(ctx context.Context, ct *check.ConnectivityTest, addExtraTests func(*ch
)

ct.NewTest("egress-gateway").
WithCiliumEgressGatewayPolicy(egressGatewayPolicyYAML).
WithCiliumEgressGatewayPolicy(egressGatewayPolicyYAML, check.CiliumEgressGatewayPolicyParams{}).
WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureEgressGateway),
check.RequireFeatureEnabled(check.FeatureNodeWithoutCilium)).
WithScenarios(
tests.EgressGateway(),
)

if versioncheck.MustCompile(">=1.14.0")(ct.CiliumVersion) {
ct.NewTest("egress-gateway-excluded-cidrs").
WithCiliumEgressGatewayPolicy(egressGatewayPolicyExcludedCIDRsYAML,
check.CiliumEgressGatewayPolicyParams{ExcludedCIDRs: check.ExternalNodeExcludedCIDRs}).
WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureEgressGateway),
check.RequireFeatureEnabled(check.FeatureNodeWithoutCilium)).
WithScenarios(
tests.EgressGatewayExcludedCIDRs(),
)
}

// The following tests have DNS redirect policies. They should be executed last.

ct.NewTest("north-south-loadbalancing-with-l7-policy").
Expand Down

0 comments on commit 0cca1c7

Please sign in to comment.