func APIServerEndpointNode(allNodes []nodes.Node) (nodes.Node, error) {
	if n, err := ExternalLoadBalancerNode(allNodes); err != nil {
		return nil, errors.Wrap(err, "failed to find api-server endpoint node")
	} else if n != nil {
		return n, nil
	}
	n, err := ControlPlaneNodes(allNodes)
	if err != nil {
		return nil, errors.Wrap(err, "failed to find api-server endpoint node")
	}
	if len(n) != 1 {
		return nil, errors.Errorf("expected one control plane node or a load balancer, not %d and none", len(n))
	}
	return n[0], nil
}
APIServerEndpointNode selects the node from allNodes which hosts the API Server endpoint
This should be the control plane node if there is one control plane node, or a LoadBalancer otherwise.
It returns an error if the node list is invalid (E.G. two control planes and no load balancer)
package nodeutils
import (
	"sort"
	"strings"
	"sigs.k8s.io/kind/pkg/cluster/constants"
	"sigs.k8s.io/kind/pkg/cluster/nodes"
	"sigs.k8s.io/kind/pkg/errors"
)
func SelectNodesByRole(allNodes []nodes.Node, role string) ([]nodes.Node, error) {
	out := []nodes.Node{}
	for _, node := range allNodes {
		nodeRole, err := node.Role()
		if err != nil {
			return nil, err
		}
		if nodeRole == role {
			out = append(out, node)
		}
	}
	return out, nil
}
func InternalNodes(allNodes []nodes.Node) ([]nodes.Node, error) {
	selectedNodes := []nodes.Node{}
	for _, node := range allNodes {
		nodeRole, err := node.Role()
		if err != nil {
			return nil, err
		}
		if nodeRole == constants.WorkerNodeRoleValue || nodeRole == constants.ControlPlaneNodeRoleValue {
			selectedNodes = append(selectedNodes, node)
		}
	}
	return selectedNodes, nil
}
func ExternalLoadBalancerNode(allNodes []nodes.Node) (nodes.Node, error) {
	loadBalancerNodes, err := SelectNodesByRole(
		allNodes,
		constants.ExternalLoadBalancerNodeRoleValue,
	)
	if err != nil {
		return nil, err
	}
	if len(loadBalancerNodes) < 1 {
		return nil, nil
	}
	if len(loadBalancerNodes) > 1 {
		return nil, errors.Errorf(
			"unexpected number of %s nodes %d",
			constants.ExternalLoadBalancerNodeRoleValue,
			len(loadBalancerNodes),
		)
	}
	return loadBalancerNodes[0], nil
}