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 authored and tklauser committed May 31, 2023
1 parent 67b4887 commit 4cce091
Show file tree
Hide file tree
Showing 7 changed files with 395 additions and 112 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
32 changes: 30 additions & 2 deletions connectivity/check/test.go
Expand Up @@ -9,6 +9,7 @@ import (
_ "embed"
"fmt"
"io"
"net"
"sync"
"time"

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,28 @@ 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 _, nodeWithoutCiliumIP := range t.Context().params.NodesWithoutCiliumIPs {
if parsedIP := net.ParseIP(nodeWithoutCiliumIP.IP); parsedIP.To4() == nil {
continue
}

cidr := v2.IPv4CIDR(fmt.Sprintf("%s/32", nodeWithoutCiliumIP.IP))
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
33 changes: 26 additions & 7 deletions 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 @@ -726,13 +731,27 @@ func Run(ctx context.Context, ct *check.ConnectivityTest, addExtraTests func(*ch
tests.NodeToNodeEncryption(),
)

ct.NewTest("egress-gateway").
WithCiliumEgressGatewayPolicy(egressGatewayPolicyYAML).
WithFeatureRequirements(check.RequireFeatureEnabled(check.FeatureEgressGateway),
check.RequireFeatureEnabled(check.FeatureNodeWithoutCilium)).
WithScenarios(
tests.EgressGateway(),
)
if ct.Params().IncludeUnsafeTests {
ct.NewTest("egress-gateway").
WithCiliumEgressGatewayPolicy(egressGatewayPolicyYAML, check.CiliumEgressGatewayPolicyParams{}).
WithIPRoutesFromOutsideToPodCIDRs().
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.

Expand Down

0 comments on commit 4cce091

Please sign in to comment.