From 6302e3a94f8edddda5c4edc68bbde4ec1cca2d11 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Thu, 19 Feb 2026 11:45:21 -0500 Subject: [PATCH 1/4] Inline a Service jig helper into a test jig.GetEndpointNodesWithIP was only used by one test, and that test didn't even want the data in the form jig.GetEndpointNodesWithIP provided it in. So just inline the code and generate the data correctly the first time, and remove GetEndpointNodesWithIP (along with GetEndpointNodes, which was already unused). --- test/e2e/framework/service/jig.go | 20 -------------------- test/e2e/network/service.go | 11 ++++++----- 2 files changed, 6 insertions(+), 25 deletions(-) diff --git a/test/e2e/framework/service/jig.go b/test/e2e/framework/service/jig.go index 78cd28d1a05..9a4e9ad12fa 100644 --- a/test/e2e/framework/service/jig.go +++ b/test/e2e/framework/service/jig.go @@ -361,26 +361,6 @@ func (j *TestJig) CreateLoadBalancerService(ctx context.Context, timeout time.Du return j.WaitForLoadBalancer(ctx, timeout) } -// GetEndpointNodes returns a map of nodenames:external-ip on which the -// endpoints of the Service are running. -func (j *TestJig) GetEndpointNodes(ctx context.Context) (map[string][]string, error) { - return j.GetEndpointNodesWithIP(ctx, v1.NodeExternalIP) -} - -// GetEndpointNodesWithIP returns a map of nodenames: on which the -// endpoints of the Service are running. -func (j *TestJig) GetEndpointNodesWithIP(ctx context.Context, addressType v1.NodeAddressType) (map[string][]string, error) { - nodes, err := j.ListNodesWithEndpoint(ctx) - if err != nil { - return nil, err - } - nodeMap := map[string][]string{} - for _, node := range nodes { - nodeMap[node.Name] = e2enode.GetAddresses(&node, addressType) - } - return nodeMap, nil -} - // ListNodesWithEndpoint returns a list of nodes on which the // endpoints of the given Service are running. func (j *TestJig) ListNodesWithEndpoint(ctx context.Context) ([]v1.Node, error) { diff --git a/test/e2e/network/service.go b/test/e2e/network/service.go index f1cd06b3e7d..49cedd0c855 100644 --- a/test/e2e/network/service.go +++ b/test/e2e/network/service.go @@ -698,16 +698,17 @@ func waitForAPIServerUp(ctx context.Context, c clientset.Interface) error { // getEndpointNodesWithInternalIP returns a map of nodenames:internal-ip on which the // endpoints of the Service are running. func getEndpointNodesWithInternalIP(ctx context.Context, jig *e2eservice.TestJig) (map[string]string, error) { - nodesWithIPs, err := jig.GetEndpointNodesWithIP(ctx, v1.NodeInternalIP) + nodes, err := jig.ListNodesWithEndpoint(ctx) if err != nil { return nil, err } - endpointsNodeMap := make(map[string]string, len(nodesWithIPs)) - for nodeName, internalIPs := range nodesWithIPs { + endpointsNodeMap := make(map[string]string, len(nodes)) + for _, node := range nodes { + internalIPs := e2enode.GetAddresses(&node, v1.NodeInternalIP) if len(internalIPs) < 1 { - return nil, fmt.Errorf("no internal ip found for node %s", nodeName) + return nil, fmt.Errorf("no internal ip found for node %s", node.Name) } - endpointsNodeMap[nodeName] = internalIPs[0] + endpointsNodeMap[node.Name] = internalIPs[0] } return endpointsNodeMap, nil } From b68e2ac8a5b97a4dc609c5361b83409cb55aedda Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sat, 21 Feb 2026 08:14:41 -0500 Subject: [PATCH 2/4] Drop e2enode.PickIP(), fix its one caller This returned a randomly-selected IP from across all nodes, preferring ExternalIP but falling back to an InternalIP. But it was only called from one place, which was connecting from inside the cluster and thus wanted an InternalIP anyway. --- test/e2e/framework/node/resource.go | 13 ------------- test/e2e/windows/service.go | 7 +++++-- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/test/e2e/framework/node/resource.go b/test/e2e/framework/node/resource.go index a3a50628840..e75e16bd1c4 100644 --- a/test/e2e/framework/node/resource.go +++ b/test/e2e/framework/node/resource.go @@ -294,19 +294,6 @@ func CollectAddresses(nodes *v1.NodeList, addressType v1.NodeAddressType) []stri return ips } -// PickIP picks one public node IP -func PickIP(ctx context.Context, c clientset.Interface) (string, error) { - publicIps, err := GetPublicIps(ctx, c) - if err != nil { - return "", fmt.Errorf("get node public IPs error: %w", err) - } - if len(publicIps) == 0 { - return "", fmt.Errorf("got unexpected number (%d) of public IPs", len(publicIps)) - } - ip := publicIps[0] - return ip, nil -} - // GetPublicIps returns a public IP list of nodes. func GetPublicIps(ctx context.Context, c clientset.Interface) ([]string, error) { nodes, err := GetReadySchedulableNodes(ctx, c) diff --git a/test/e2e/windows/service.go b/test/e2e/windows/service.go index 9cc0d349a89..a88f52b099d 100644 --- a/test/e2e/windows/service.go +++ b/test/e2e/windows/service.go @@ -54,8 +54,6 @@ var _ = sigDescribe("Services", skipUnlessWindows(func() { ns := f.Namespace.Name jig := e2eservice.NewTestJig(cs, ns, serviceName) - nodeIP, err := e2enode.PickIP(ctx, jig.Client) - framework.ExpectNoError(err) ginkgo.By("creating service " + serviceName + " with type=NodePort in namespace " + ns) svc, err := jig.CreateTCPService(ctx, func(svc *v1.Service) { @@ -63,6 +61,11 @@ var _ = sigDescribe("Services", skipUnlessWindows(func() { }) framework.ExpectNoError(err) + node, err := e2enode.GetRandomReadySchedulableNode(ctx, jig.Client) + framework.ExpectNoError(err) + ips := e2enode.GetAddressesByTypeAndFamily(node, v1.NodeInternalIP, svc.Spec.IPFamilies[0]) + gomega.Expect(ips).NotTo(gomega.BeEmpty()) + nodeIP := ips[0] nodePort := int(svc.Spec.Ports[0].NodePort) ginkgo.By("creating Pod to be part of service " + serviceName) From 0ffb81575035cc7ce0681d8856a314361122922c Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Sat, 21 Feb 2026 07:22:41 -0500 Subject: [PATCH 3/4] Drop e2enode.FirstAddress which was no longer used anyway --- test/e2e/framework/node/resource.go | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/e2e/framework/node/resource.go b/test/e2e/framework/node/resource.go index e75e16bd1c4..d6359a2d807 100644 --- a/test/e2e/framework/node/resource.go +++ b/test/e2e/framework/node/resource.go @@ -89,18 +89,6 @@ type PodNode struct { Node string } -// FirstAddress returns the first address of the given type of each node. -func FirstAddress(nodelist *v1.NodeList, addrType v1.NodeAddressType) string { - for _, n := range nodelist.Items { - for _, addr := range n.Status.Addresses { - if addr.Type == addrType && addr.Address != "" { - return addr.Address - } - } - } - return "" -} - func isNodeConditionSetAsExpected(node *v1.Node, conditionType v1.NodeConditionType, wantTrue, silent bool) bool { // Check the node readiness condition (logging all). for _, cond := range node.Status.Conditions { From 6ebabf319899cc0aaad39a252135bcf19b62948d Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 2 Mar 2026 12:08:56 -0500 Subject: [PATCH 4/4] Fix the semantics of e2essh.NodeSSHHosts on error If it failed to find an IP for every node, it returned a partial list along with an error. However, (a) this should never happen since every scheduleable node should have at least one usable IP, and (b) it didn't matter since all of its callers just treat any error as being fatal anyway. So just remove the special case. --- test/e2e/framework/ssh/ssh.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/test/e2e/framework/ssh/ssh.go b/test/e2e/framework/ssh/ssh.go index d60cec3c225..c9a136d8d7f 100644 --- a/test/e2e/framework/ssh/ssh.go +++ b/test/e2e/framework/ssh/ssh.go @@ -125,8 +125,7 @@ func makePrivateKeySignerFromFile(key string) (ssh.Signer, error) { // NodeSSHHosts returns SSH-able host names for all schedulable nodes. // If it can't find any external IPs, it falls back to // looking for internal IPs. If it can't find an internal IP for every node it -// returns an error, though it still returns all hosts that it found in that -// case. +// returns an error. func NodeSSHHosts(ctx context.Context, c clientset.Interface) ([]string, error) { nodelist := waitListSchedulableNodesOrDie(ctx, c) @@ -136,10 +135,9 @@ func NodeSSHHosts(ctx context.Context, c clientset.Interface) ([]string, error) framework.Logf("No external IP address on nodes, falling back to internal IPs") hosts = nodeAddresses(nodelist, v1.NodeInternalIP) } - - // Error if neither External nor Internal IPs weren't available for all nodes. if len(hosts) != len(nodelist.Items) { - return hosts, fmt.Errorf( + // Something is wrong; all schedulable nodes should have at least one IP. + return nil, fmt.Errorf( "only found %d IPs on nodes, but found %d nodes. Nodelist: %v", len(hosts), len(nodelist.Items), nodelist) }