@@ -84,6 +84,52 @@ func defineService(svcName, svcNSName string,
8484 return service .NewBuilder (APIClient , svcName , svcNSName , svcSelector , svcPort )
8585}
8686
87+ // applyIPFamilyPolicy sets Service ipFamilies and ipFamilyPolicy from configured remote target IPs.
88+ func applyIPFamilyPolicy (svcBuilder * service.Builder , remoteTargetIP , remoteTargetIPv6 string ) * service.Builder {
89+ hasIPv4 := remoteTargetIP != ""
90+ hasIPv6 := remoteTargetIPv6 != ""
91+
92+ Expect (hasIPv4 || hasIPv6 ).To (BeTrue (),
93+ "At least one remote target IP (IPv4 or IPv6) must be configured" )
94+
95+ switch {
96+ case hasIPv4 && hasIPv6 :
97+ By ("Setting ipFamilyPolicy to 'RequireDualStack'" )
98+
99+ klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Dual-stack: setting ipFamilyPolicy to RequireDualStack" )
100+
101+ return svcBuilder .WithIPFamily ([]corev1.IPFamily {corev1 .IPv4Protocol , corev1 .IPv6Protocol },
102+ corev1 .IPFamilyPolicyRequireDualStack )
103+ case hasIPv6 :
104+ By ("Setting ipFamilyPolicy to 'SingleStack' (IPv6)" )
105+
106+ klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("IPv6 only: setting ipFamilyPolicy to SingleStack" )
107+
108+ return svcBuilder .WithIPFamily ([]corev1.IPFamily {corev1 .IPv6Protocol },
109+ corev1 .IPFamilyPolicySingleStack )
110+ default :
111+ By ("Setting ipFamilyPolicy to 'SingleStack' (IPv4)" )
112+
113+ klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("IPv4 only: setting ipFamilyPolicy to SingleStack" )
114+
115+ return svcBuilder .WithIPFamily ([]corev1.IPFamily {corev1 .IPv4Protocol },
116+ corev1 .IPFamilyPolicySingleStack )
117+ }
118+ }
119+
120+ // buildEgressClientIPCurlCmd returns a curl command that hits the remote /clientip endpoint.
121+ // hostIsIPv6 selects URL form (IPv6 literals must appear in brackets).
122+ func buildEgressClientIPCurlCmd (host , port string , hostIsIPv6 bool ) []string {
123+ var url string
124+ if hostIsIPv6 {
125+ url = fmt .Sprintf ("http://[%s]:%s/clientip" , host , port )
126+ } else {
127+ url = fmt .Sprintf ("http://%s:%s/clientip" , host , port )
128+ }
129+
130+ return []string {"/bin/bash" , "-c" , fmt .Sprintf ("curl --connect-timeout 3 -Ls %s" , url )}
131+ }
132+
87133func deleteService (svcName , svcNSName string ) {
88134 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Deleting service %q in %q ns" , svcName , svcNSName )
89135
@@ -382,12 +428,7 @@ func VerifyEgressServiceETPClusterWrapper(
382428 svcBuilder = svcBuilder .WithAnnotation (map [string ]string {
383429 "metallb.universe.tf/address-pool" : ipAddrPoolName })
384430
385- By ("Setting ipFamilyPolicy to 'RequireDualStack'" )
386-
387- klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Setting ipFamilyPolicy to 'RequireDualStack'" )
388-
389- svcBuilder = svcBuilder .WithIPFamily ([]corev1.IPFamily {"IPv4" , "IPv6" },
390- corev1 .IPFamilyPolicyRequireDualStack )
431+ svcBuilder = applyIPFamilyPolicy (svcBuilder , remoteTargetIP , remoteTargetIPv6 )
391432
392433 By ("Creating a service" )
393434
@@ -506,15 +547,11 @@ func VerifyEgressServiceETPClusterWrapper(
506547 if myIP .Is4 () {
507548 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Processing IPv4 address" )
508549
509- cmdToRun = []string {"/bin/bash" , "-c" ,
510- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
511- remoteTargetIP , remoteTargetPort )}
550+ cmdToRun = buildEgressClientIPCurlCmd (remoteTargetIP , remoteTargetPort , false )
512551 } else {
513552 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Processing IPv6 address" )
514553
515- cmdToRun = []string {"/bin/bash" , "-c" ,
516- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
517- remoteTargetIPv6 , remoteTargetPort )}
554+ cmdToRun = buildEgressClientIPCurlCmd (remoteTargetIPv6 , remoteTargetPort , true )
518555 }
519556
520557 if strings .EqualFold (strings .TrimSpace (string (egrSVCBuilder .Object .Spec .SourceIPBy )), "Network" ) {
@@ -675,10 +712,7 @@ func VerifyEgressServiceWithLocalETPWrapper(
675712 svcBuilder = svcBuilder .WithAnnotation (map [string ]string {
676713 "metallb.universe.tf/address-pool" : ipAddrPoolName })
677714
678- By ("Setting ipFamilyPolicy to 'RequireDualStack'" )
679-
680- svcBuilder = svcBuilder .WithIPFamily ([]corev1.IPFamily {"IPv4" , "IPv6" },
681- corev1 .IPFamilyPolicyRequireDualStack )
715+ svcBuilder = applyIPFamilyPolicy (svcBuilder , remoteTargetIP , remoteTargetIPv6 )
682716
683717 By ("Creating a service" )
684718 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Creating Service object" )
@@ -795,17 +829,13 @@ func VerifyEgressServiceWithLocalETPWrapper(
795829 if myIP .Is4 () {
796830 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Processing IPv4 address" )
797831
798- cmdToRun = []string {"/bin/bash" , "-c" ,
799- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
800- remoteTargetIP , remoteTargetPort )}
832+ cmdToRun = buildEgressClientIPCurlCmd (remoteTargetIP , remoteTargetPort , false )
801833
802834 expectedIP = remoteTargetIP
803835 } else {
804836 klog .V (rdscoreparams .RDSCoreLogLevel ).Infof ("Processing IPv6 address" )
805837
806- cmdToRun = []string {"/bin/bash" , "-c" ,
807- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
808- remoteTargetIPv6 , remoteTargetPort )}
838+ cmdToRun = buildEgressClientIPCurlCmd (remoteTargetIPv6 , remoteTargetPort , true )
809839
810840 expectedIP = remoteTargetIPv6
811841 }
@@ -950,76 +980,58 @@ func verifySourceIP(svcName, svcNS, podLabels string, cmdToRun []string, useIPv6
950980 }
951981}
952982
953- // VerifyEgressServiceConnectivityETPCluster verifies source IP address when external traffic policy
954- // is set to Cluster.
955- func VerifyEgressServiceConnectivityETPCluster () {
956- cmdToRun := []string {"/bin/bash" , "-c" ,
957- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
958- RDSCoreConfig .EgressServiceRemoteIP , RDSCoreConfig .EgressServiceRemotePort )}
983+ // verifyEgressServiceConnectivity is the shared egress connectivity check; byPrefix labels Ginkgo By steps.
984+ func verifyEgressServiceConnectivity (svcName , svcNS , svcLabels , byPrefix string ) {
985+ Expect (RDSCoreConfig .EgressServiceRemoteIP != "" || RDSCoreConfig .EgressServiceRemoteIPv6 != "" ).To (BeTrue (),
986+ "Neither EgressServiceRemoteIP nor EgressServiceRemoteIPv6 is configured" )
987+
988+ if RDSCoreConfig .EgressServiceRemoteIP != "" {
989+ By (fmt .Sprintf ("Verifying EgressService %s connectivity (IPv4)" , byPrefix ))
990+
991+ cmdToRun := buildEgressClientIPCurlCmd (RDSCoreConfig .EgressServiceRemoteIP ,
992+ RDSCoreConfig .EgressServiceRemotePort , false )
993+
994+ verifySourceIP (svcName , svcNS , svcLabels , cmdToRun , false ,
995+ RDSCoreConfig .EgressServiceNetworkExpectedIPs )
996+ }
959997
960- verifySourceIP ( egressSVC1Name , RDSCoreConfig .EgressServiceNS , egressSVC1Labels , cmdToRun , false ,
961- RDSCoreConfig . EgressServiceNetworkExpectedIPs )
998+ if RDSCoreConfig .EgressServiceRemoteIPv6 != "" {
999+ By ( fmt . Sprintf ( "Verifying EgressService %s connectivity (IPv6)" , byPrefix ) )
9621000
963- cmdToRun = []string {"/bin/bash" , "-c" ,
964- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
965- RDSCoreConfig .EgressServiceRemoteIPv6 , RDSCoreConfig .EgressServiceRemotePort )}
1001+ cmdToRun := buildEgressClientIPCurlCmd (RDSCoreConfig .EgressServiceRemoteIPv6 ,
1002+ RDSCoreConfig .EgressServiceRemotePort , true )
9661003
967- verifySourceIP (egressSVC1Name , RDSCoreConfig .EgressServiceNS , egressSVC1Labels , cmdToRun , true ,
968- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1004+ verifySourceIP (svcName , svcNS , svcLabels , cmdToRun , true ,
1005+ RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1006+ }
1007+ }
1008+
1009+ // VerifyEgressServiceConnectivityETPCluster verifies source IP address when external traffic policy
1010+ // is set to Cluster.
1011+ func VerifyEgressServiceConnectivityETPCluster () {
1012+ verifyEgressServiceConnectivity (egressSVC1Name , RDSCoreConfig .EgressServiceNS , egressSVC1Labels ,
1013+ "ETP=Cluster" )
9691014}
9701015
9711016// VerifyEgressServiceConnectivityETPClusterSourceIPByNetwork verifies source IP address when external traffic policy
9721017// is set to Cluster.
9731018func VerifyEgressServiceConnectivityETPClusterSourceIPByNetwork () {
974- cmdToRun := []string {"/bin/bash" , "-c" ,
975- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
976- RDSCoreConfig .EgressServiceRemoteIP , RDSCoreConfig .EgressServiceRemotePort )}
977-
978- verifySourceIP (egressSVC3Name , RDSCoreConfig .EgressServiceNS , egressSVC3Labels , cmdToRun , false ,
979- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
980-
981- cmdToRun = []string {"/bin/bash" , "-c" ,
982- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
983- RDSCoreConfig .EgressServiceRemoteIPv6 , RDSCoreConfig .EgressServiceRemotePort )}
984-
985- verifySourceIP (egressSVC3Name , RDSCoreConfig .EgressServiceNS , egressSVC3Labels , cmdToRun , true ,
986- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1019+ verifyEgressServiceConnectivity (egressSVC3Name , RDSCoreConfig .EgressServiceNS , egressSVC3Labels ,
1020+ "ETP=Cluster sourceIPBy=Network" )
9871021}
9881022
9891023// VerifyEgressServiceConnectivityETPLocal verifies source IP address when external traffic policy
9901024// is set to Local.
9911025func VerifyEgressServiceConnectivityETPLocal () {
992- cmdToRun := []string {"/bin/bash" , "-c" ,
993- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
994- RDSCoreConfig .EgressServiceRemoteIP , RDSCoreConfig .EgressServiceRemotePort )}
995-
996- verifySourceIP (egressSVC2Name , RDSCoreConfig .EgressServiceNS , egressSVC2Labels , cmdToRun , false ,
997- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
998-
999- cmdToRun = []string {"/bin/bash" , "-c" ,
1000- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
1001- RDSCoreConfig .EgressServiceRemoteIPv6 , RDSCoreConfig .EgressServiceRemotePort )}
1002-
1003- verifySourceIP (egressSVC2Name , RDSCoreConfig .EgressServiceNS , egressSVC2Labels , cmdToRun , true ,
1004- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1026+ verifyEgressServiceConnectivity (egressSVC2Name , RDSCoreConfig .EgressServiceNS , egressSVC2Labels ,
1027+ "ETP=Local" )
10051028}
10061029
10071030// VerifyEgressServiceConnectivityETPLocalSourceIPByNetwork verifies source IP address when external traffic policy
10081031// is set to Local and sourceIPBy=Network.
10091032func VerifyEgressServiceConnectivityETPLocalSourceIPByNetwork () {
1010- cmdToRun := []string {"/bin/bash" , "-c" ,
1011- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://%s:%s/clientip" ,
1012- RDSCoreConfig .EgressServiceRemoteIP , RDSCoreConfig .EgressServiceRemotePort )}
1013-
1014- verifySourceIP (egressSVC4Name , RDSCoreConfig .EgressServiceNS , egressSVC4Labels , cmdToRun , false ,
1015- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1016-
1017- cmdToRun = []string {"/bin/bash" , "-c" ,
1018- fmt .Sprintf ("curl --connect-timeout 3 -Ls http://[%s]:%s/clientip" ,
1019- RDSCoreConfig .EgressServiceRemoteIPv6 , RDSCoreConfig .EgressServiceRemotePort )}
1020-
1021- verifySourceIP (egressSVC4Name , RDSCoreConfig .EgressServiceNS , egressSVC4Labels , cmdToRun , true ,
1022- RDSCoreConfig .EgressServiceNetworkExpectedIPs )
1033+ verifyEgressServiceConnectivity (egressSVC4Name , RDSCoreConfig .EgressServiceNS , egressSVC4Labels ,
1034+ "ETP=Local sourceIPBy=Network" )
10231035}
10241036
10251037// VerifyEgressServiceETPLocalIngressConnectivity verifies ingress IP address while accessing backend pods
0 commit comments