Skip to content

Commit

Permalink
Connectivity test factory component.
Browse files Browse the repository at this point in the history
Signed-off-by: viktor-kurchenko <[email protected]>
  • Loading branch information
viktor-kurchenko committed Feb 21, 2024
1 parent bd9ac69 commit 1e7938f
Show file tree
Hide file tree
Showing 139 changed files with 2,780 additions and 1,255 deletions.
41 changes: 6 additions & 35 deletions connectivity/check/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
package check

import (
"bytes"
"context"
"errors"
"fmt"
Expand All @@ -22,7 +21,6 @@ import (
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
corev1 "k8s.io/api/core/v1"
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/cilium/cilium/api/v1/observer"
Expand Down Expand Up @@ -231,41 +229,14 @@ func NewConnectivityTest(client *k8s.Client, p Parameters, version string) (*Con
return k, nil
}

// NewTest creates a new test scope within the ConnectivityTest and returns
// a new Test. This object can be used to set up the environment to execute
// different Scenarios within.
func (ct *ConnectivityTest) NewTest(name string) *Test {
var member struct{}

if name == "" {
panic("empty test name")
}

if _, ok := ct.testNames[name]; ok {
ct.Fatalf("test %s exists in suite", name)
}

t := &Test{
ctx: ct,
name: name,
scenarios: make(map[Scenario][]*Action),
cnps: make(map[string]*ciliumv2.CiliumNetworkPolicy),
knps: make(map[string]*networkingv1.NetworkPolicy),
cegps: make(map[string]*ciliumv2.CiliumEgressGatewayPolicy),
verbose: ct.verbose(),
logBuf: &bytes.Buffer{}, // maintain internal buffer by default
warnBuf: &bytes.Buffer{},
// AddTest adds a new test scope within the ConnectivityTest.
func (ct *ConnectivityTest) AddTest(t *Test) *Test {
if _, ok := ct.testNames[t.name]; ok {
ct.Fatalf("test %s exists in suite", t.name)
}

// Setting the internal buffer to nil causes the logger to
// write directly to stdout in verbose or debug mode.
if ct.verbose() || ct.debug() {
t.logBuf = nil
}

t.ctx = ct
ct.tests = append(ct.tests, t)
ct.testNames[name] = member

ct.testNames[t.name] = struct{}{}
return t
}

Expand Down
19 changes: 19 additions & 0 deletions connectivity/check/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,25 @@ var (
egressGatewayPolicyYAML string
)

func NewTest(name string, verbose bool, debug bool) *Test {
logBuf := &bytes.Buffer{}
// Setting the internal buffer to nil causes the logger to
// write directly to stdout in verbose or debug mode.
if verbose || debug {
logBuf = nil
}
return &Test{
name: name,
scenarios: make(map[Scenario][]*Action),
cnps: make(map[string]*ciliumv2.CiliumNetworkPolicy),
knps: make(map[string]*networkingv1.NetworkPolicy),
cegps: make(map[string]*ciliumv2.CiliumEgressGatewayPolicy),
verbose: verbose,
logBuf: logBuf, // maintain internal buffer by default
warnBuf: &bytes.Buffer{},
}
}

type Test struct {
// Reference to the enclosing test suite for logging etc.
ctx *ConnectivityTest
Expand Down
34 changes: 34 additions & 0 deletions connectivity/factory/all_egress_deny.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
_ "embed"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
)

var (
//go:embed manifests/deny-all-egress.yaml
denyAllEgressPolicyYAML string

allEgressDeny = factory{
name: "all-egress-deny",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy denies all egresses by default
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithCiliumPolicy(denyAllEgressPolicyYAML).
WithScenarios(
tests.PodToPod(),
tests.PodToPodWithEndpoints(),
).
WithExpectations(func(_ *check.Action) (egress, ingress check.Result) {
return check.ResultDefaultDenyEgressDrop, check.ResultNone
})
},
condition: runAlways,
}
)
34 changes: 34 additions & 0 deletions connectivity/factory/all_egress_deny_knp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
_ "embed"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
)

var (
//go:embed manifests/deny-all-egress-knp.yaml
denyAllEgressPolicyKNPYAML string

allEgressDenyKnp = factory{
name: "all-egress-deny-knp",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy denies all egresses by default using KNP.
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithK8SPolicy(denyAllEgressPolicyKNPYAML).
WithScenarios(
tests.PodToPod(),
tests.PodToPodWithEndpoints(),
).
WithExpectations(func(_ *check.Action) (egress, ingress check.Result) {
return check.ResultDefaultDenyEgressDrop, check.ResultNone
})
},
condition: runAlways,
}
)
34 changes: 34 additions & 0 deletions connectivity/factory/all_entities_deny.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
_ "embed"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
)

var (
//go:embed manifests/deny-all-entities.yaml
denyAllEntitiesPolicyYAML string

allEntitiesDeny = factory{
name: "all-entities-deny",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy denies all entities by default
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithCiliumPolicy(denyAllEntitiesPolicyYAML).
WithScenarios(
tests.PodToPod(),
tests.PodToCIDR(),
).
WithExpectations(func(_ *check.Action) (egress, ingress check.Result) {
return check.ResultPolicyDenyEgressDrop, check.ResultNone
})
},
condition: runAlways,
}
)
35 changes: 35 additions & 0 deletions connectivity/factory/all_ingress_deny.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
"github.com/cilium/cilium-cli/utils/features"
)

var allIngressDeny = factory{
name: "all-ingress-deny",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy denies all ingresses by default.
//
// 1. Pod to Pod fails because there is no egress policy (so egress traffic originating from a pod is allowed),
// but then at the destination there is ingress policy that denies the traffic.
// 2. Egress to world works because there is no egress policy (so egress traffic originating from a pod is allowed),
// then when replies come back, they are considered as "replies" to the outbound connection.
// so they are not subject to ingress policy.
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithCiliumPolicy(denyAllIngressPolicyYAML).
WithScenarios(tests.PodToPod(), tests.PodToCIDR(tests.WithRetryAll())).
WithExpectations(func(a *check.Action) (egress, ingress check.Result) {
if a.Destination().Address(features.GetIPFamily(ct.Params().ExternalOtherIP)) == ct.Params().ExternalOtherIP ||
a.Destination().Address(features.GetIPFamily(ct.Params().ExternalIP)) == ct.Params().ExternalIP {
return check.ResultOK, check.ResultNone
}
return check.ResultDrop, check.ResultDefaultDenyIngressDrop
})
},
condition: runAlways,
}
32 changes: 32 additions & 0 deletions connectivity/factory/all_ingress_deny_from_outside.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
"github.com/blang/semver/v4"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
"github.com/cilium/cilium-cli/utils/features"
)

var allIngressDenyFromOutside = factory{
name: "all-ingress-deny-from-outside",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithCiliumPolicy(denyAllIngressPolicyYAML).
WithFeatureRequirements(features.RequireEnabled(features.NodeWithoutCilium)).
WithIPRoutesFromOutsideToPodCIDRs().
WithScenarios(tests.FromCIDRToPod()).
WithExpectations(func(a *check.Action) (egress, ingress check.Result) {
if a.Destination().Address(features.GetIPFamily(ct.Params().ExternalOtherIP)) == ct.Params().ExternalOtherIP ||
a.Destination().Address(features.GetIPFamily(ct.Params().ExternalIP)) == ct.Params().ExternalIP {
return check.ResultOK, check.ResultNone
}
return check.ResultDrop, check.ResultDefaultDenyIngressDrop
})
},
condition: func(_ semver.Version, params check.Parameters) bool { return params.IncludeUnsafeTests },
}
44 changes: 44 additions & 0 deletions connectivity/factory/all_ingress_deny_knp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
_ "embed"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
"github.com/cilium/cilium-cli/utils/features"
)

var (
//go:embed manifests/deny-all-ingress-knp.yaml
denyAllIngressPolicyKNPYAML string

allIngressDenyKnp = factory{
name: "all-ingress-deny-knp",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy denies all ingresses by default
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithK8SPolicy(denyAllIngressPolicyKNPYAML).
WithScenarios(
// Pod to Pod fails because there is no egress policy (so egress traffic originating from a pod is allowed),
// but then at the destination there is ingress policy that denies the traffic.
tests.PodToPod(),
// Egress to world works because there is no egress policy (so egress traffic originating from a pod is allowed),
// then when replies come back, they are considered as "replies" to the outbound connection.
// so they are not subject to ingress policy.
tests.PodToCIDR(tests.WithRetryAll()),
).
WithExpectations(func(a *check.Action) (egress, ingress check.Result) {
if a.Destination().Address(features.GetIPFamily(ct.Params().ExternalOtherIP)) == ct.Params().ExternalOtherIP ||
a.Destination().Address(features.GetIPFamily(ct.Params().ExternalIP)) == ct.Params().ExternalIP {
return check.ResultOK, check.ResultNone
}
return check.ResultDrop, check.ResultDefaultDenyIngressDrop
})
},
condition: runAlways,
}
)
39 changes: 39 additions & 0 deletions connectivity/factory/allow_all_except_world.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
_ "embed"

"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
)

var (
//go:embed manifests/allow-all-except-world.yaml
allowAllExceptWorldPolicyYAML string

allowAllExceptWorld = factory{
name: "allow-all-except-world",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// Test with an allow-all-except-world (and unmanaged) policy.
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithCiliumPolicy(allowAllExceptWorldPolicyYAML).
WithScenarios(
tests.PodToPod(),
tests.ClientToClient(),
tests.PodToService(),
// We are skipping the following checks because NodePort is
// intended to be used for N-S traffic, which conflicts with
// policies. See GH-17144.
// tests.PodToRemoteNodePort(),
// tests.PodToLocalNodePort(),
tests.PodToHost(),
tests.PodToExternalWorkload(),
)
},
condition: runAlways,
}
)
24 changes: 24 additions & 0 deletions connectivity/factory/allow_all_with_metrics_check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: Apache-2.0
// Copyright Authors of Cilium

package factory

import (
"github.com/cilium/cilium-cli/connectivity/check"
"github.com/cilium/cilium-cli/connectivity/tests"
)

var allowAllWithMetricsCheck = factory{
name: "allow-all-with-metrics-check",
build: func(name string, ct *check.ConnectivityTest, _ map[string]string) {
// This policy allows traffic pod to pod and checks if the metric cilium_forward_count_total increases on cilium agent.
test := check.NewTest(name, ct.Params().Verbose, ct.Params().Debug)
ct.AddTest(test).
WithScenarios(tests.PodToPod()).
WithExpectations(func(_ *check.Action) (egress, ingress check.Result) {
return check.ResultOK.ExpectMetricsIncrease(ct.CiliumAgentMetrics(), "cilium_forward_count_total"),
check.ResultOK.ExpectMetricsIncrease(ct.CiliumAgentMetrics(), "cilium_forward_count_total")
})
},
condition: runAlways,
}
Loading

0 comments on commit 1e7938f

Please sign in to comment.