Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 65 additions & 17 deletions tests/system-tests/rdscore/internal/rdscorecommon/egress-ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -1020,23 +1020,48 @@ func VerifyEgressIPForPodWithWrongLabel() {
fmt.Sprintf("Failed to retrieve configured EgressIP addresses list from the egressIP %s: %v",
RDSCoreConfig.EgressIPName, err))

podObjectsPodObjects, err := pod.List(APIClient, RDSCoreConfig.EgressIPNamespaceOne, egressIPPodSelector)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Failed to retrieve pods list from namespace %s with label %s: %v",
RDSCoreConfig.EgressIPNamespaceOne, RDSCoreConfig.EgressIPPodLabel, err))
type ipFamilyEntry struct {
name string
isIPv6 bool
}

err = sendTrafficCheckIP(podObjectsPodObjects, false, expectedIPs)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Server response was note received: %v", err))
var ipFamilies []ipFamilyEntry

podObjectsPodObjects, err = pod.List(APIClient, RDSCoreConfig.EgressIPNamespaceOne, nonEgressIPPodSelector)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Failed to retrieve pods list from namespace %s with label %v: %v",
RDSCoreConfig.EgressIPNamespaceOne, nonEgressIPPodSelector, err))
if RDSCoreConfig.EgressIPRemoteIPv4 != "" {
ipFamilies = append(ipFamilies, ipFamilyEntry{name: "IPv4", isIPv6: false})
}

if RDSCoreConfig.EgressIPRemoteIPv6 != "" {
ipFamilies = append(ipFamilies, ipFamilyEntry{name: "IPv6", isIPv6: true})
}

Expect(len(ipFamilies)).ToNot(Equal(0),
"Neither EgressIPRemoteIPv4 nor EgressIPRemoteIPv6 is configured")

err = sendTrafficCheckIP(podObjectsPodObjects, false, expectedIPs)
Expect(err).To(HaveOccurred(),
fmt.Sprintf("Server response was received with the not correct egressIP address: %v", err))
for _, family := range ipFamilies {
By(fmt.Sprintf("Positive check: verifying EgressIP is used for correctly-labeled pods (%s)", family.name))

correctLabelPods, err := pod.List(APIClient, RDSCoreConfig.EgressIPNamespaceOne, egressIPPodSelector)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Failed to retrieve pods list from namespace %s with label %s: %v",
RDSCoreConfig.EgressIPNamespaceOne, RDSCoreConfig.EgressIPPodLabel, err))

err = sendTrafficCheckIP(correctLabelPods, family.isIPv6, expectedIPs)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("%s: server response was not received from correctly-labeled pods: %v", family.name, err))

By(fmt.Sprintf("Negative check: verifying EgressIP is NOT used for wrong-labeled pods (%s)", family.name))

wrongLabelPods, err := pod.List(APIClient, RDSCoreConfig.EgressIPNamespaceOne, nonEgressIPPodSelector)
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Failed to retrieve pods list from namespace %s with label %v: %v",
RDSCoreConfig.EgressIPNamespaceOne, nonEgressIPPodSelector, err))

err = sendTrafficCheckIP(wrongLabelPods, family.isIPv6, expectedIPs)
Expect(err).To(HaveOccurred(),
fmt.Sprintf("%s: server response was received with egressIP from wrong-labeled pods: %v",
family.name, err))
}
}

// VerifyEgressIPForNamespaceWithWrongLabel verifies egress traffic applies only for the pods
Expand Down Expand Up @@ -1074,9 +1099,32 @@ func VerifyEgressIPForNamespaceWithWrongLabel() {
fmt.Sprintf("Failed to retrieve pods list from namespace %s with label %s: %v",
nonEgressIPNamespace, RDSCoreConfig.EgressIPPodLabel, err))

err = sendTrafficCheckIP(podObjects, false, expectedIPs)
Expect(err).To(HaveOccurred(),
fmt.Sprintf("Server response was received with the not correct egressIP address: %v", err))
type ipFamilyEntry struct {
name string
isIPv6 bool
}

var ipFamilies []ipFamilyEntry

if RDSCoreConfig.EgressIPRemoteIPv4 != "" {
ipFamilies = append(ipFamilies, ipFamilyEntry{name: "IPv4", isIPv6: false})
}

if RDSCoreConfig.EgressIPRemoteIPv6 != "" {
ipFamilies = append(ipFamilies, ipFamilyEntry{name: "IPv6", isIPv6: true})
}

Expect(len(ipFamilies)).ToNot(Equal(0),
"Neither EgressIPRemoteIPv4 nor EgressIPRemoteIPv6 is configured")

for _, family := range ipFamilies {
By(fmt.Sprintf("Verifying EgressIP is NOT used for pods in wrong namespace (%s)", family.name))

err = sendTrafficCheckIP(podObjects, family.isIPv6, expectedIPs)
Expect(err).To(HaveOccurred(),
fmt.Sprintf("%s: server response was received with egressIP from wrong namespace: %v",
family.name, err))
}
}

// VerifyEgressIPOneNamespaceThreeNodesBalancedEIPTrafficIPv4 verifies egress traffic works with egressIP
Expand Down
183 changes: 136 additions & 47 deletions tests/system-tests/rdscore/internal/rdscorecommon/egress-service.go
Original file line number Diff line number Diff line change
Expand Up @@ -382,12 +382,35 @@ func VerifyEgressServiceETPClusterWrapper(
svcBuilder = svcBuilder.WithAnnotation(map[string]string{
"metallb.universe.tf/address-pool": ipAddrPoolName})

By("Setting ipFamilyPolicy to 'RequireDualStack'")
hasIPv4 := remoteTargetIP != ""
hasIPv6 := remoteTargetIPv6 != ""

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Setting ipFamilyPolicy to 'RequireDualStack'")
Expect(hasIPv4 || hasIPv6).To(BeTrue(),
"At least one remote target IP (IPv4 or IPv6) must be configured")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{"IPv4", "IPv6"},
corev1.IPFamilyPolicyRequireDualStack)
switch {
case hasIPv4 && hasIPv6:
By("Setting ipFamilyPolicy to 'RequireDualStack'")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Dual-stack: setting ipFamilyPolicy to RequireDualStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv4Protocol, corev1.IPv6Protocol},
corev1.IPFamilyPolicyRequireDualStack)
case hasIPv6:
By("Setting ipFamilyPolicy to 'SingleStack' (IPv6)")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("IPv6 only: setting ipFamilyPolicy to SingleStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv6Protocol},
corev1.IPFamilyPolicySingleStack)
default:
By("Setting ipFamilyPolicy to 'SingleStack' (IPv4)")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("IPv4 only: setting ipFamilyPolicy to SingleStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv4Protocol},
corev1.IPFamilyPolicySingleStack)
}

By("Creating a service")

Expand Down Expand Up @@ -675,10 +698,32 @@ func VerifyEgressServiceWithLocalETPWrapper(
svcBuilder = svcBuilder.WithAnnotation(map[string]string{
"metallb.universe.tf/address-pool": ipAddrPoolName})

By("Setting ipFamilyPolicy to 'RequireDualStack'")
hasIPv4 := remoteTargetIP != ""
hasIPv6 := remoteTargetIPv6 != ""

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{"IPv4", "IPv6"},
corev1.IPFamilyPolicyRequireDualStack)
switch {
case hasIPv4 && hasIPv6:
By("Setting ipFamilyPolicy to 'RequireDualStack'")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Dual-stack: setting ipFamilyPolicy to RequireDualStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv4Protocol, corev1.IPv6Protocol},
corev1.IPFamilyPolicyRequireDualStack)
case hasIPv6:
By("Setting ipFamilyPolicy to 'SingleStack' (IPv6)")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("IPv6 only: setting ipFamilyPolicy to SingleStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv6Protocol},
corev1.IPFamilyPolicySingleStack)
default:
By("Setting ipFamilyPolicy to 'SingleStack' (IPv4)")

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("IPv4 only: setting ipFamilyPolicy to SingleStack")

svcBuilder = svcBuilder.WithIPFamily([]corev1.IPFamily{corev1.IPv4Protocol},
corev1.IPFamilyPolicySingleStack)
}

By("Creating a service")
klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Creating Service object")
Expand Down Expand Up @@ -953,73 +998,117 @@ func verifySourceIP(svcName, svcNS, podLabels string, cmdToRun []string, useIPv6
// VerifyEgressServiceConnectivityETPCluster verifies source IP address when external traffic policy
// is set to Cluster.
func VerifyEgressServiceConnectivityETPCluster() {
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}
Expect(RDSCoreConfig.EgressServiceRemoteIP != "" || RDSCoreConfig.EgressServiceRemoteIPv6 != "").To(BeTrue(),
"Neither EgressServiceRemoteIP nor EgressServiceRemoteIPv6 is configured")

if RDSCoreConfig.EgressServiceRemoteIP != "" {
By("Verifying EgressService ETP=Cluster connectivity (IPv4)")

verifySourceIP(egressSVC1Name, RDSCoreConfig.EgressServiceNS, egressSVC1Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}

cmdToRun = []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}
verifySourceIP(egressSVC1Name, RDSCoreConfig.EgressServiceNS, egressSVC1Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}

if RDSCoreConfig.EgressServiceRemoteIPv6 != "" {
By("Verifying EgressService ETP=Cluster connectivity (IPv6)")

cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC1Name, RDSCoreConfig.EgressServiceNS, egressSVC1Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
verifySourceIP(egressSVC1Name, RDSCoreConfig.EgressServiceNS, egressSVC1Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}
}

// VerifyEgressServiceConnectivityETPClusterSourceIPByNetwork verifies source IP address when external traffic policy
// is set to Cluster.
func VerifyEgressServiceConnectivityETPClusterSourceIPByNetwork() {
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}
Expect(RDSCoreConfig.EgressServiceRemoteIP != "" || RDSCoreConfig.EgressServiceRemoteIPv6 != "").To(BeTrue(),
"Neither EgressServiceRemoteIP nor EgressServiceRemoteIPv6 is configured")

if RDSCoreConfig.EgressServiceRemoteIP != "" {
By("Verifying EgressService ETP=Cluster sourceIPBy=Network connectivity (IPv4)")

verifySourceIP(egressSVC3Name, RDSCoreConfig.EgressServiceNS, egressSVC3Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}

cmdToRun = []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}
verifySourceIP(egressSVC3Name, RDSCoreConfig.EgressServiceNS, egressSVC3Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}

if RDSCoreConfig.EgressServiceRemoteIPv6 != "" {
By("Verifying EgressService ETP=Cluster sourceIPBy=Network connectivity (IPv6)")

cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC3Name, RDSCoreConfig.EgressServiceNS, egressSVC3Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
verifySourceIP(egressSVC3Name, RDSCoreConfig.EgressServiceNS, egressSVC3Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}
}

// VerifyEgressServiceConnectivityETPLocal verifies source IP address when external traffic policy
// is set to Local.
func VerifyEgressServiceConnectivityETPLocal() {
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}
Expect(RDSCoreConfig.EgressServiceRemoteIP != "" || RDSCoreConfig.EgressServiceRemoteIPv6 != "").To(BeTrue(),
"Neither EgressServiceRemoteIP nor EgressServiceRemoteIPv6 is configured")

verifySourceIP(egressSVC2Name, RDSCoreConfig.EgressServiceNS, egressSVC2Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
if RDSCoreConfig.EgressServiceRemoteIP != "" {
By("Verifying EgressService ETP=Local connectivity (IPv4)")

cmdToRun = []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC2Name, RDSCoreConfig.EgressServiceNS, egressSVC2Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
verifySourceIP(egressSVC2Name, RDSCoreConfig.EgressServiceNS, egressSVC2Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}

if RDSCoreConfig.EgressServiceRemoteIPv6 != "" {
By("Verifying EgressService ETP=Local connectivity (IPv6)")

cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC2Name, RDSCoreConfig.EgressServiceNS, egressSVC2Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}
}

// VerifyEgressServiceConnectivityETPLocalSourceIPByNetwork verifies source IP address when external traffic policy
// is set to Local and sourceIPBy=Network.
func VerifyEgressServiceConnectivityETPLocalSourceIPByNetwork() {
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}
Expect(RDSCoreConfig.EgressServiceRemoteIP != "" || RDSCoreConfig.EgressServiceRemoteIPv6 != "").To(BeTrue(),
"Neither EgressServiceRemoteIP nor EgressServiceRemoteIPv6 is configured")

verifySourceIP(egressSVC4Name, RDSCoreConfig.EgressServiceNS, egressSVC4Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
if RDSCoreConfig.EgressServiceRemoteIP != "" {
By("Verifying EgressService ETP=Local sourceIPBy=Network connectivity (IPv4)")

cmdToRun = []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}
cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://%s:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIP, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC4Name, RDSCoreConfig.EgressServiceNS, egressSVC4Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
verifySourceIP(egressSVC4Name, RDSCoreConfig.EgressServiceNS, egressSVC4Labels, cmdToRun, false,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}

if RDSCoreConfig.EgressServiceRemoteIPv6 != "" {
By("Verifying EgressService ETP=Local sourceIPBy=Network connectivity (IPv6)")

cmdToRun := []string{"/bin/bash", "-c",
fmt.Sprintf("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip",
RDSCoreConfig.EgressServiceRemoteIPv6, RDSCoreConfig.EgressServiceRemotePort)}

verifySourceIP(egressSVC4Name, RDSCoreConfig.EgressServiceNS, egressSVC4Labels, cmdToRun, true,
RDSCoreConfig.EgressServiceNetworkExpectedIPs)
}
}

// VerifyEgressServiceETPLocalIngressConnectivity verifies ingress IP address while accessing backend pods
Expand Down
32 changes: 7 additions & 25 deletions tests/system-tests/rdscore/internal/rdscorecommon/hard-reboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ func WaitAllDeploymentsAreAvailable(ctx SpecContext) {

// VerifySoftReboot performs graceful reboot of a cluster with cordoning and draining of individual nodes.
//
//nolint:gocognit,funlen
//nolint:funlen
func VerifySoftReboot(ctx SpecContext) {
klog.V(rdscoreparams.RDSCoreLogLevel).Infof("\t*** Starting Soft Reboot Test Suite ***")

Expand All @@ -203,6 +203,11 @@ func VerifySoftReboot(ctx SpecContext) {
for _, _node := range allNodes {
klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Processing node %q", _node.Definition.Name)

bootIDBefore := _node.Object.Status.NodeInfo.BootID

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Node %q boot ID before reboot: %s",
_node.Definition.Name, bootIDBefore)

klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Cordoning node %q", _node.Definition.Name)
err := _node.Cordon()
Expect(err).ToNot(HaveOccurred(),
Expand Down Expand Up @@ -253,30 +258,7 @@ func VerifySoftReboot(ctx SpecContext) {
Expect(err).ToNot(HaveOccurred(),
fmt.Sprintf("Failed to reboot node %s", _node.Definition.Name))

By(fmt.Sprintf("Checking node %q got into NotReady", _node.Definition.Name))

Eventually(func(ctx SpecContext) bool {
currentNode, err := nodes.Pull(APIClient, _node.Definition.Name)
if err != nil {
klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Failed to pull node: %v", err)

return false
}

for _, condition := range currentNode.Object.Status.Conditions {
if condition.Type == rdscoreparams.ConditionTypeReadyString {
if condition.Status != rdscoreparams.ConstantTrueString {
klog.V(rdscoreparams.RDSCoreLogLevel).Infof("Node %q is notReady", currentNode.Definition.Name)
klog.V(rdscoreparams.RDSCoreLogLevel).Infof(" Reason: %s", condition.Reason)

return true
}
}
}

return false
}).WithTimeout(25*time.Minute).WithPolling(15*time.Second).WithContext(ctx).Should(BeTrue(),
"Node hasn't reached notReady state")
waitForBootIDChange(ctx, _node.Definition.Name, bootIDBefore, 25*time.Minute)

By(fmt.Sprintf("Checking node %q got into Ready", _node.Definition.Name))

Expand Down
Loading