Repository: kubernetes/kubernetes
File: test/e2e/network/dual_stack.go (Go)

Code before:
	netutils "k8s.io/utils/net"
)

// Tests for ipv4-ipv6 dual-stack feature
var _ = common.SIGDescribe(feature.IPv6DualStack, func() {
	f := framework.NewDefaultFramework("dualstack")
	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged

	var cs clientset.Interface
	var podClient *e2epod.PodClient

	ginkgo.BeforeEach(func() {
		cs = f.ClientSet
		podClient = e2epod.NewPodClient(f)
	})

	ginkgo.It("should have at least one node with an IPv4 IP and one with an IPv6 IP", func(ctx context.Context) {
		nodeList, err := e2enode.GetReadySchedulableNodes(ctx, cs)
		framework.ExpectNoError(err)

		var hasIPv4, hasIPv6 bool
		for _, node := range nodeList.Items {
			ginkgo.By(fmt.Sprintf("examining %s", node.Name))
			for _, addr := range node.Status.Addresses {
				if addr.Type != v1.NodeInternalIP && addr.Type != v1.NodeExternalIP {
					continue
				}
				ip := netutils.ParseIPSloppy(addr.Address)
				if ip == nil {
					framework.Failf("Could not parse node %q %s %q", node.Name, addr.Type, addr.Address)
				}

				hasIPv4 = hasIPv4 || netutils.IsIPv4(ip)
				hasIPv6 = hasIPv6 || netutils.IsIPv6(ip)
			}
		}

		switch {
		case !hasIPv4 && !hasIPv6:
			framework.Failf("Could not find either IPv4 or IPv6 node IPs")
		case !hasIPv4:
			framework.Failf("Could not find any node with an IPv4 IP")
		case !hasIPv6:
			framework.Failf("Could not find any node with an IPv6 IP")
		}
	})

	ginkgo.It("should create pod, add ipv6 and ipv4 ip to pod ips", func(ctx context.Context) {
		podName := "pod-dualstack-ips"

		pod := &v1.Pod{

Review comment (suggestion):
I think the test should still be checking for the node itself, so one node has both IPv4 and IPv6.

We discussed this in several places, and despite is perfectly possible to have a mix of single IPv4 or IPv6 or dual stack nodes, application portability does not work out of the box on that environments without admins handholding, at the network level it works but not as a platform ... that is why I always push back on supporting that scenario from Kubernetes POV, but not saying it can not be done ... 



Code after:
	netutils "k8s.io/utils/net"
)

// Tests for ipv4-ipv6 dual-stack feature
var _ = common.SIGDescribe(feature.IPv6DualStack, func() {
	f := framework.NewDefaultFramework("dualstack")
	f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged

	var cs clientset.Interface
	var podClient *e2epod.PodClient

	ginkgo.BeforeEach(func() {
		cs = f.ClientSet
		podClient = e2epod.NewPodClient(f)
	})

	// A dual-stack cluster should have at least one dual-stack node (though it may
	// also have some single-stack IPv4 or single-stack IPv6 nodes for some use
	// cases).
	ginkgo.It("should have at least one dual-stack node", func(ctx context.Context) {
		nodeList, err := e2enode.GetReadySchedulableNodes(ctx, cs)
		framework.ExpectNoError(err)

		var found bool
		for _, node := range nodeList.Items {
			ginkgo.By(fmt.Sprintf("examining %s", node.Name))
			var hasIPv4, hasIPv6 bool
			for _, addr := range node.Status.Addresses {
				if addr.Type != v1.NodeInternalIP && addr.Type != v1.NodeExternalIP {
					continue
				}
				if netutils.IsIPv4String(addr.Address) {
					hasIPv4 = true
				} else if netutils.IsIPv6String(addr.Address) {
					hasIPv6 = true
				}
			}
			if hasIPv4 && hasIPv6 {
				found = true
				break
			}
		}

		if !found {
			framework.Failf("Could not find any schedulable node with both an IPv4 IP and an IPv6 IP")
		}
	})

	ginkgo.It("should create pod, add ipv6 and ipv4 ip to pod ips", func(ctx context.Context) {
		podName := "pod-dualstack-ips"