diff --git a/connectivity/check.go b/connectivity/check/check.go similarity index 96% rename from connectivity/check.go rename to connectivity/check/check.go index c27839f455..cf41e1b491 100644 --- a/connectivity/check.go +++ b/connectivity/check/check.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package connectivity +package check import ( "bytes" @@ -42,17 +42,14 @@ import ( ) const ( - clientDeploymentName = "client" + ClientDeploymentName = "client" + echoSameNodeDeploymentName = "echo-same-node" echoOtherNodeDeploymentName = "echo-other-node" kindEchoName = "echo" kindClientName = "client" ) -func curlCommand(target string) []string { - return []string{"curl", "-sS", "--fail", "--connect-timeout", "5", "-o", "/dev/null", target} -} - var serviceLabels = map[string]string{ "kind": kindEchoName, } @@ -176,7 +173,7 @@ type k8sConnectivityImplementation interface { type PodContext struct { // K8sClient is the Kubernetes client of the cluster this pod is // running in - k8sClient k8sConnectivityImplementation + K8sClient k8sConnectivityImplementation // Pod is the Kubernetes Pod resource Pod *corev1.Pod @@ -356,7 +353,7 @@ func (t *TestRun) settleFlows(ctx context.Context) error { // ValidateFlows retrieves the flow pods of the specified pod and validates // that all filters find a match. On failure, t.Failure() is called. -func (t *TestRun) ValidateFlows(ctx context.Context, pod, podIP string, filter []FilterPair) { +func (t *TestRun) ValidateFlows(ctx context.Context, pod, podIP string, filterPairs []filters.Pair) { hubbleClient := t.context.HubbleClient() if hubbleClient == nil { return @@ -396,7 +393,7 @@ func (t *TestRun) ValidateFlows(ctx context.Context, pod, podIP string, filter [ var goodLog []string - for _, p := range filter { + for _, p := range filterPairs { if flows.Contains(p.Filter) != p.Expect { for _, g := range goodLog { t.context.Log(g) @@ -637,14 +634,8 @@ func (f *flowsSet) Contains(filter filters.FlowFilterImplementation) bool { return false } -type FilterPair struct { - Filter filters.FlowFilterImplementation - Msg string - Expect bool -} - -func (k *K8sConnectivityCheck) Validate(pod string, f *flowsSet, filter []FilterPair) (success bool) { - for _, p := range filter { +func (k *K8sConnectivityCheck) Validate(pod string, f *flowsSet, filterPairs []filters.Pair) (success bool) { + for _, p := range filterPairs { if f.Contains(p.Filter) != p.Expect { k.Log("❌ %s in pod %s", p.Msg, pod) success = false @@ -751,7 +742,7 @@ func (k *K8sConnectivityCheck) deleteDeployments(ctx context.Context, client k8s k.Log("🔥 [%s] Deleting connectivity check deployments...", client.ClusterName()) client.DeleteDeployment(ctx, k.params.TestNamespace, echoSameNodeDeploymentName, metav1.DeleteOptions{}) client.DeleteDeployment(ctx, k.params.TestNamespace, echoOtherNodeDeploymentName, metav1.DeleteOptions{}) - client.DeleteDeployment(ctx, k.params.TestNamespace, clientDeploymentName, metav1.DeleteOptions{}) + client.DeleteDeployment(ctx, k.params.TestNamespace, ClientDeploymentName, metav1.DeleteOptions{}) client.DeleteService(ctx, k.params.TestNamespace, echoSameNodeDeploymentName, metav1.DeleteOptions{}) client.DeleteService(ctx, k.params.TestNamespace, echoOtherNodeDeploymentName, metav1.DeleteOptions{}) client.DeleteNamespace(ctx, k.params.TestNamespace, metav1.DeleteOptions{}) @@ -769,7 +760,7 @@ func (k *K8sConnectivityCheck) deleteDeployments(ctx context.Context, client k8s } func (k *K8sConnectivityCheck) deploymentList() (srcList []string, dstList []string) { - srcList = []string{clientDeploymentName, echoSameNodeDeploymentName} + srcList = []string{ClientDeploymentName, echoSameNodeDeploymentName} if k.params.MultiCluster != "" || !k.params.SingleNode { dstList = append(dstList, echoOtherNodeDeploymentName) @@ -897,7 +888,7 @@ func (k *K8sConnectivityCheck) deploy(ctx context.Context) error { { LabelSelector: &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ - {Key: "name", Operator: metav1.LabelSelectorOpIn, Values: []string{clientDeploymentName}}, + {Key: "name", Operator: metav1.LabelSelectorOpIn, Values: []string{ClientDeploymentName}}, }, }, TopologyKey: "kubernetes.io/hostname", @@ -914,10 +905,10 @@ func (k *K8sConnectivityCheck) deploy(ctx context.Context) error { } k.Log("✨ [%s] Deploying client service...", k.clients.src.ClusterName()) - clientDeployment := newDeployment(deploymentParameters{Name: clientDeploymentName, Kind: kindClientName, Port: 8080, Image: "quay.io/cilium/alpine-curl:1.0", Command: []string{"/bin/ash", "-c", "sleep 10000000"}}) + clientDeployment := newDeployment(deploymentParameters{Name: ClientDeploymentName, Kind: kindClientName, Port: 8080, Image: "quay.io/cilium/alpine-curl:1.0", Command: []string{"/bin/ash", "-c", "sleep 10000000"}}) _, err = k.clients.src.CreateDeployment(ctx, k.params.TestNamespace, clientDeployment, metav1.CreateOptions{}) if err != nil { - return fmt.Errorf("unable to create deployment %s: %s", clientDeploymentName, err) + return fmt.Errorf("unable to create deployment %s: %s", ClientDeploymentName, err) } } @@ -947,7 +938,7 @@ func (k *K8sConnectivityCheck) deploy(ctx context.Context) error { { LabelSelector: &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ - {Key: "name", Operator: metav1.LabelSelectorOpIn, Values: []string{clientDeploymentName}}, + {Key: "name", Operator: metav1.LabelSelectorOpIn, Values: []string{ClientDeploymentName}}, }, }, TopologyKey: "kubernetes.io/hostname", @@ -1020,7 +1011,7 @@ func (k *K8sConnectivityCheck) waitForService(ctx context.Context, client k8sCon } retry: - if _, _, err := client.ExecInPodWithStderr(ctx, clientPod.Pod.Namespace, clientPod.Pod.Name, clientDeploymentName, []string{"nslookup", service}); err != nil { + if _, _, err := client.ExecInPodWithStderr(ctx, clientPod.Pod.Namespace, clientPod.Pod.Name, ClientDeploymentName, []string{"nslookup", service}); err != nil { select { case <-time.After(time.Second): case <-ctx.Done(): @@ -1055,7 +1046,7 @@ func (k *K8sConnectivityCheck) validateDeployment(ctx context.Context) error { } k.clientPods[pod.Name] = PodContext{ - k8sClient: k.client, + K8sClient: k.client, Pod: pod.DeepCopy(), } } @@ -1074,7 +1065,7 @@ func (k *K8sConnectivityCheck) validateDeployment(ctx context.Context) error { } k.echoPods[echoPod.Name] = PodContext{ - k8sClient: client, + K8sClient: client, Pod: echoPod.DeepCopy(), } } @@ -1148,16 +1139,7 @@ func (k *K8sConnectivityCheck) Report(r TestResult) { k.results[r.Name] = r } -var tests = []ConnectivityTest{ - &connectivityTestPodToPod{}, - &connectivityTestPodToService{}, - &connectivityTestPodToNodePort{}, - &connectivityTestPodToLocalNodePort{}, - &connectivityTestPodToWorld{}, - &connectivityTestPodToHost{}, -} - -func (k *K8sConnectivityCheck) Run(ctx context.Context) error { +func (k *K8sConnectivityCheck) Run(ctx context.Context, tests ...ConnectivityTest) error { c, err := k.initClients(ctx) if err != nil { return err diff --git a/connectivity/filters/filters.go b/connectivity/filters/filters.go index cc93b439ca..fb6a16277c 100644 --- a/connectivity/filters/filters.go +++ b/connectivity/filters/filters.go @@ -30,6 +30,12 @@ type FlowFilterImplementation interface { String() string } +type Pair struct { + Filter FlowFilterImplementation + Msg string + Expect bool +} + type andFilter struct { filters []FlowFilterImplementation } diff --git a/connectivity/suite.go b/connectivity/suite.go new file mode 100644 index 0000000000..48888bc868 --- /dev/null +++ b/connectivity/suite.go @@ -0,0 +1,33 @@ +// Copyright 2020-2021 Authors of Cilium +// +// 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 connectivity + +import ( + "context" + + "github.com/cilium/cilium-cli/connectivity/check" + "github.com/cilium/cilium-cli/connectivity/tests" +) + +func Run(ctx context.Context, k *check.K8sConnectivityCheck) error { + return k.Run(ctx, + &tests.PodToPod{}, + &tests.PodToService{}, + &tests.PodToNodePort{}, + &tests.PodToLocalNodePort{}, + &tests.PodToWorld{}, + &tests.PodToHost{}, + ) +} diff --git a/connectivity/tests/common.go b/connectivity/tests/common.go new file mode 100644 index 0000000000..5e2f711819 --- /dev/null +++ b/connectivity/tests/common.go @@ -0,0 +1,19 @@ +// Copyright 2020-2021 Authors of Cilium +// +// 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 + +func curlCommand(target string) []string { + return []string{"curl", "--silent", "--fail", "--show-error", "--connect-timeout", "5", "--output", "/dev/null", target} +} diff --git a/connectivity/test_host.go b/connectivity/tests/host.go similarity index 80% rename from connectivity/test_host.go rename to connectivity/tests/host.go index e1dacf8d07..25b58dc56a 100644 --- a/connectivity/test_host.go +++ b/connectivity/tests/host.go @@ -12,21 +12,22 @@ // See the License for the specific language governing permissions and // limitations under the License. -package connectivity +package tests import ( "context" + "github.com/cilium/cilium-cli/connectivity/check" "github.com/cilium/cilium-cli/connectivity/filters" ) -type connectivityTestPodToHost struct{} +type PodToHost struct{} -func (p *connectivityTestPodToHost) Name() string { +func (t *PodToHost) Name() string { return "pod-to-host" } -func (p *connectivityTestPodToHost) Run(ctx context.Context, c TestContext) { +func (t *PodToHost) Run(ctx context.Context, c check.TestContext) { // Construct a map of all unique host IPs where pods are running on. // This will include: // - The local host @@ -43,14 +44,14 @@ func (p *connectivityTestPodToHost) Run(ctx context.Context, c TestContext) { for _, client := range c.ClientPods() { for hostIP := range hostIPs { cmd := []string{"ping", "-c", "3", hostIP} - run := NewTestRun(p.Name(), c, client, NetworkEndpointContext{Peer: hostIP}) + run := check.NewTestRun(t.Name(), c, client, check.NetworkEndpointContext{Peer: hostIP}) - _, err := client.k8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, clientDeploymentName, cmd) + _, err := client.K8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, check.ClientDeploymentName, cmd) if err != nil { run.Failure("ping command failed: %s", err) } - run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []FilterPair{ + run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []filters.Pair{ {Filter: filters.Drop(), Expect: false, Msg: "Found drop"}, {Filter: filters.And(filters.IP(client.Pod.Status.PodIP, hostIP), filters.ICMP(8)), Expect: true, Msg: "ICMP request"}, {Filter: filters.And(filters.IP(hostIP, client.Pod.Status.PodIP), filters.ICMP(0)), Expect: true, Msg: "ICMP response"}, diff --git a/connectivity/test_pod.go b/connectivity/tests/pod.go similarity index 82% rename from connectivity/test_pod.go rename to connectivity/tests/pod.go index df081edf10..fce1a22911 100644 --- a/connectivity/test_pod.go +++ b/connectivity/tests/pod.go @@ -12,26 +12,27 @@ // See the License for the specific language governing permissions and // limitations under the License. -package connectivity +package tests import ( "context" + "github.com/cilium/cilium-cli/connectivity/check" "github.com/cilium/cilium-cli/connectivity/filters" ) -type connectivityTestPodToPod struct{} +type PodToPod struct{} -func (p *connectivityTestPodToPod) Name() string { +func (t *PodToPod) Name() string { return "pod-to-pod" } -func (p *connectivityTestPodToPod) Run(ctx context.Context, c TestContext) { +func (t *PodToPod) Run(ctx context.Context, c check.TestContext) { for _, client := range c.ClientPods() { for _, echo := range c.EchoPods() { - run := NewTestRun(p.Name(), c, client, echo) + run := check.NewTestRun(t.Name(), c, client, echo) - _, err := client.k8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, clientDeploymentName, curlCommand(echo.Pod.Status.PodIP+":8080")) + _, err := client.K8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, check.ClientDeploymentName, curlCommand(echo.Pod.Status.PodIP+":8080")) if err != nil { run.Failure("curl connectivity check command failed: %s", err) } @@ -41,14 +42,14 @@ func (p *connectivityTestPodToPod) Run(ctx context.Context, c TestContext) { tcpRequest := filters.TCP(0, 8080) // request to port 8080 tcpResponse := filters.TCP(8080, 0) // response from port 8080 - run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []FilterPair{ + run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []filters.Pair{ {Filter: filters.Drop(), Expect: false, Msg: "Drop"}, {Filter: filters.RST(), Expect: false, Msg: "RST"}, {Filter: filters.And(echoToClient, tcpResponse, filters.SYNACK()), Expect: true, Msg: "SYN-ACK"}, {Filter: filters.And(echoToClient, tcpResponse, filters.FIN()), Expect: true, Msg: "FIN-ACK"}, }) - run.ValidateFlows(ctx, echo.Name(), echo.Pod.Status.PodIP, []FilterPair{ + run.ValidateFlows(ctx, echo.Name(), echo.Pod.Status.PodIP, []filters.Pair{ {Filter: filters.Drop(), Expect: false, Msg: "Drop"}, {Filter: filters.RST(), Expect: false, Msg: "RST"}, {Filter: filters.And(clientToEcho, tcpRequest, filters.SYN()), Expect: true, Msg: "SYN"}, diff --git a/connectivity/test_service.go b/connectivity/tests/service.go similarity index 76% rename from connectivity/test_service.go rename to connectivity/tests/service.go index 0955d25e22..eb75928f09 100644 --- a/connectivity/test_service.go +++ b/connectivity/tests/service.go @@ -12,76 +12,24 @@ // See the License for the specific language governing permissions and // limitations under the License. -package connectivity +package tests import ( "context" "net" "strconv" + "github.com/cilium/cilium-cli/connectivity/check" "github.com/cilium/cilium-cli/connectivity/filters" ) -type connectivityTestPodToService struct{} +type PodToService struct{} -func (p *connectivityTestPodToService) Name() string { +func (t *PodToService) Name() string { return "pod-to-service" } -type serviceDefinition struct { - port int - name string - dns bool -} - -type serviceDefinitionMap map[string]serviceDefinition - -func testConnetivityToServiceDefinition(ctx context.Context, c TestContext, name string, client PodContext, def serviceDefinitionMap) { - for peer, definition := range def { - destination := net.JoinHostPort(peer, strconv.Itoa(definition.port)) - run := NewTestRun(name, c, client, NetworkEndpointContext{ - CustomName: destination + " (" + definition.name + ")", - Peer: destination, - }) - - _, err := client.k8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, clientDeploymentName, curlCommand(destination)) - if err != nil { - run.Failure("curl connectivity check command failed: %s", err) - } - - clientToEcho := filters.IP(client.Pod.Status.PodIP, "") - echoToClient := filters.IP("", client.Pod.Status.PodIP) - - // Depending on whether NodePort is enabled or - // not, the port will be differnt. Ideally we - // look at Cilium to define this but this - // information is not yet available. - tcpRequest := filters.Or(filters.TCP(0, definition.port), filters.TCP(0, 8080)) // request to 8080 or NodePort - tcpResponse := filters.Or(filters.TCP(definition.port, 0), filters.TCP(8080, 0)) // response from port 8080 or NodePort - - flowRequirements := []FilterPair{ - {Filter: filters.Drop(), Expect: false, Msg: "Drop"}, - {Filter: filters.RST(), Expect: false, Msg: "RST"}, - {Filter: filters.And(clientToEcho, tcpRequest, filters.SYN()), Expect: true, Msg: "SYN"}, - {Filter: filters.And(echoToClient, tcpResponse, filters.SYNACK()), Expect: true, Msg: "SYN-ACK"}, - {Filter: filters.And(clientToEcho, tcpRequest, filters.FIN()), Expect: true, Msg: "FIN"}, - {Filter: filters.And(echoToClient, tcpResponse, filters.FIN()), Expect: true, Msg: "FIN-ACK"}, - } - - if definition.dns { - flowRequirements = append(flowRequirements, []FilterPair{ - {Filter: filters.And(filters.IP(client.Pod.Status.PodIP, ""), filters.UDP(0, 53)), Expect: true, Msg: "DNS request"}, - {Filter: filters.And(filters.IP("", client.Pod.Status.PodIP), filters.UDP(53, 0)), Expect: true, Msg: "DNS response"}, - }...) - } - - run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, flowRequirements) - - run.End() - } -} - -func (p *connectivityTestPodToService) Run(ctx context.Context, c TestContext) { +func (t *PodToService) Run(ctx context.Context, c check.TestContext) { for _, client := range c.ClientPods() { serviceDestinations := serviceDefinitionMap{} for _, echoSvc := range c.EchoServices() { @@ -92,18 +40,18 @@ func (p *connectivityTestPodToService) Run(ctx context.Context, c TestContext) { } } - testConnetivityToServiceDefinition(ctx, c, p.Name(), client, serviceDestinations) + testConnetivityToServiceDefinition(ctx, c, t.Name(), client, serviceDestinations) } } -type connectivityTestPodToNodePort struct{} +type PodToNodePort struct{} -func (p *connectivityTestPodToNodePort) Name() string { +func (t *PodToNodePort) Name() string { return "pod-to-nodeport" } -func (p *connectivityTestPodToNodePort) Run(ctx context.Context, c TestContext) { +func (t *PodToNodePort) Run(ctx context.Context, c check.TestContext) { for _, client := range c.ClientPods() { serviceDestinations := serviceDefinitionMap{} for _, echoSvc := range c.EchoServices() { @@ -117,17 +65,17 @@ func (p *connectivityTestPodToNodePort) Run(ctx context.Context, c TestContext) } } - testConnetivityToServiceDefinition(ctx, c, p.Name(), client, serviceDestinations) + testConnetivityToServiceDefinition(ctx, c, t.Name(), client, serviceDestinations) } } -type connectivityTestPodToLocalNodePort struct{} +type PodToLocalNodePort struct{} -func (p *connectivityTestPodToLocalNodePort) Name() string { +func (t *PodToLocalNodePort) Name() string { return "pod-to-local-nodeport" } -func (p *connectivityTestPodToLocalNodePort) Run(ctx context.Context, c TestContext) { +func (t *PodToLocalNodePort) Run(ctx context.Context, c check.TestContext) { for _, client := range c.ClientPods() { serviceDestinations := serviceDefinitionMap{} for _, client := range c.ClientPods() { @@ -143,6 +91,59 @@ func (p *connectivityTestPodToLocalNodePort) Run(ctx context.Context, c TestCont } } - testConnetivityToServiceDefinition(ctx, c, p.Name(), client, serviceDestinations) + testConnetivityToServiceDefinition(ctx, c, t.Name(), client, serviceDestinations) + } +} + +type serviceDefinition struct { + port int + name string + dns bool +} + +type serviceDefinitionMap map[string]serviceDefinition + +func testConnetivityToServiceDefinition(ctx context.Context, c check.TestContext, name string, client check.PodContext, def serviceDefinitionMap) { + for peer, definition := range def { + destination := net.JoinHostPort(peer, strconv.Itoa(definition.port)) + run := check.NewTestRun(name, c, client, check.NetworkEndpointContext{ + CustomName: destination + " (" + definition.name + ")", + Peer: destination, + }) + + _, err := client.K8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, check.ClientDeploymentName, curlCommand(destination)) + if err != nil { + run.Failure("curl connectivity check command failed: %s", err) + } + + clientToEcho := filters.IP(client.Pod.Status.PodIP, "") + echoToClient := filters.IP("", client.Pod.Status.PodIP) + + // Depending on whether NodePort is enabled or + // not, the port will be differnt. Ideally we + // look at Cilium to define this but this + // information is not yet available. + tcpRequest := filters.Or(filters.TCP(0, definition.port), filters.TCP(0, 8080)) // request to 8080 or NodePort + tcpResponse := filters.Or(filters.TCP(definition.port, 0), filters.TCP(8080, 0)) // response from port 8080 or NodePort + + flowRequirements := []filters.Pair{ + {Filter: filters.Drop(), Expect: false, Msg: "Drop"}, + {Filter: filters.RST(), Expect: false, Msg: "RST"}, + {Filter: filters.And(clientToEcho, tcpRequest, filters.SYN()), Expect: true, Msg: "SYN"}, + {Filter: filters.And(echoToClient, tcpResponse, filters.SYNACK()), Expect: true, Msg: "SYN-ACK"}, + {Filter: filters.And(clientToEcho, tcpRequest, filters.FIN()), Expect: true, Msg: "FIN"}, + {Filter: filters.And(echoToClient, tcpResponse, filters.FIN()), Expect: true, Msg: "FIN-ACK"}, + } + + if definition.dns { + flowRequirements = append(flowRequirements, []filters.Pair{ + {Filter: filters.And(filters.IP(client.Pod.Status.PodIP, ""), filters.UDP(0, 53)), Expect: true, Msg: "DNS request"}, + {Filter: filters.And(filters.IP("", client.Pod.Status.PodIP), filters.UDP(53, 0)), Expect: true, Msg: "DNS response"}, + }...) + } + + run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, flowRequirements) + + run.End() } } diff --git a/connectivity/test_world.go b/connectivity/tests/world.go similarity index 80% rename from connectivity/test_world.go rename to connectivity/tests/world.go index a94c78dd95..e9c1a6d199 100644 --- a/connectivity/test_world.go +++ b/connectivity/tests/world.go @@ -12,32 +12,33 @@ // See the License for the specific language governing permissions and // limitations under the License. -package connectivity +package tests import ( "context" + "github.com/cilium/cilium-cli/connectivity/check" "github.com/cilium/cilium-cli/connectivity/filters" ) -type connectivityTestPodToWorld struct{} +type PodToWorld struct{} -func (p *connectivityTestPodToWorld) Name() string { +func (t *PodToWorld) Name() string { return "pod-to-world" } -func (p *connectivityTestPodToWorld) Run(ctx context.Context, c TestContext) { +func (t *PodToWorld) Run(ctx context.Context, c check.TestContext) { fqdn := "https://google.com" for _, client := range c.ClientPods() { - run := NewTestRun(p.Name(), c, client, NetworkEndpointContext{Peer: fqdn}) + run := check.NewTestRun(t.Name(), c, client, check.NetworkEndpointContext{Peer: fqdn}) - _, err := client.k8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, clientDeploymentName, curlCommand(fqdn)) + _, err := client.K8sClient.ExecInPod(ctx, client.Pod.Namespace, client.Pod.Name, check.ClientDeploymentName, curlCommand(fqdn)) if err != nil { run.Failure("curl connectivity check command failed: %s", err) } - run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []FilterPair{ + run.ValidateFlows(ctx, client.Name(), client.Pod.Status.PodIP, []filters.Pair{ {Filter: filters.Drop(), Expect: false, Msg: "Drop"}, {Filter: filters.And(filters.IP(client.Pod.Status.PodIP, ""), filters.UDP(0, 53)), Expect: true, Msg: "DNS request"}, {Filter: filters.And(filters.IP("", client.Pod.Status.PodIP), filters.UDP(53, 0)), Expect: true, Msg: "DNS response"}, diff --git a/internal/cli/cmd/connectivity.go b/internal/cli/cmd/connectivity.go index cfe9ae3fd7..78dd0c7d31 100644 --- a/internal/cli/cmd/connectivity.go +++ b/internal/cli/cmd/connectivity.go @@ -20,6 +20,7 @@ import ( "time" "github.com/cilium/cilium-cli/connectivity" + "github.com/cilium/cilium-cli/connectivity/check" "github.com/cilium/cilium-cli/defaults" "github.com/spf13/cobra" @@ -37,7 +38,7 @@ func newCmdConnectivity() *cobra.Command { return cmd } -var params = connectivity.Parameters{ +var params = check.Parameters{ Writer: os.Stdout, } @@ -47,11 +48,11 @@ func newCmdConnectivityCheck() *cobra.Command { Short: "Validate connectivity in cluster", Long: ``, RunE: func(cmd *cobra.Command, args []string) error { - check, err := connectivity.NewK8sConnectivityCheck(k8sClient, params) + cc, err := check.NewK8sConnectivityCheck(k8sClient, params) if err != nil { return err } - if err := check.Run(context.Background()); err != nil { + if err := connectivity.Run(context.Background(), cc); err != nil { fatalf("Connectivity test failed: %s", err) } return nil @@ -70,7 +71,7 @@ func newCmdConnectivityCheck() *cobra.Command { cmd.Flags().StringVar(¶ms.MultiCluster, "multi-cluster", "", "Test across clusters to given context") cmd.Flags().StringVar(&contextName, "context", "", "Kubernetes configuration context") cmd.Flags().StringSliceVar(¶ms.Tests, "test", []string{}, "Run a particular set of tests") - cmd.Flags().StringVar(¶ms.FlowValidation, "flow-validation", connectivity.FlowValidationModeWarning, "Enable Hubble flow validation { disabled | warning | strict }") + cmd.Flags().StringVar(¶ms.FlowValidation, "flow-validation", check.FlowValidationModeWarning, "Enable Hubble flow validation { disabled | warning | strict }") return cmd }