func generateEndpoints(subsets []v1.EndpointSubset, namespace string, subsetNumber int) []v1.Endpoints {
	eps := make([]v1.Endpoints, 0)
	sbs := make([]v1.EndpointSubset, 0)
	e := 0
	for i := 0; i < len(subsets); i++ {
		sbs = append(sbs, subsets[i])
		if e == subsetNumber-1 {
			host := uuid.New()
			eps = append(eps, v1.Endpoints{
				ObjectMeta: meta_v1.ObjectMeta{
					Name:      "app-" + host.String()[:13],
					Namespace: namespace,
					Labels:    map[string]string{stressTestLabel: "true"},
				},
				Subsets: sbs,
			})
			sbs = make([]v1.EndpointSubset, 0)
			e = 0
		} else {
			e++
		}
	}
	return eps
}
CreateEndPoint creates endpoint with specified name
package endpointsgen
import (
	"fmt"
	"net"
	"strings"
	"github.com/google/uuid"
	v1 "k8s.io/api/core/v1"
	meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/client-go/kubernetes"
)
const (
	portBase        = 16384
	stressTestLabel = "endpoints/stressTest"
)
func EnsureNamespace(k8s *kubernetes.Clientset, namespace string) error {
	namespaces, err := k8s.CoreV1().Namespaces().List(meta_v1.ListOptions{})
	if err != nil {
		return err
	}
	for _, ns := range namespaces.Items {
		if ns.ObjectMeta.Name == namespace {
			return nil
		}
	}
	_, err = k8s.CoreV1().Namespaces().Create(&v1.Namespace{
		ObjectMeta: meta_v1.ObjectMeta{
			Name: namespace,
		},
	})
	return err
}
func CreateEndPoint(k8s *kubernetes.Clientset, eps []v1.Endpoints) error {
	for _, ep := range eps {
		if _, err := k8s.CoreV1().Endpoints(ep.ObjectMeta.Namespace).Create(&ep); err != nil {
			return err
		}
	}
	return nil
}
func CreateService(k8s *kubernetes.Clientset, svcs []v1.Service) error {
	for _, svc := range svcs {
		if _, err := k8s.CoreV1().Services(svc.ObjectMeta.Namespace).Create(&svc); err != nil {
			return err
		}
	}
	return nil
}
func DeleteEndPoints(k8s *kubernetes.Clientset, namespace string) error {
	err := k8s.CoreV1().Endpoints(namespace).DeleteCollection(&meta_v1.DeleteOptions{}, meta_v1.ListOptions{
		LabelSelector: stressTestLabel,
	})
	return err
}
func DeleteServices(k8s *kubernetes.Clientset, namespace string) error {
	svcList, err := k8s.CoreV1().Services(namespace).List(meta_v1.ListOptions{
		LabelSelector: stressTestLabel,
	})
	if err == nil {
		for _, s := range svcList.Items {
			_ = k8s.CoreV1().Services(namespace).Delete(s.ObjectMeta.Name, &meta_v1.DeleteOptions{})
		}
	}
	return err
}
func CleanServicesAndEndpoints(k8s *kubernetes.Clientset, namespace string) {
	_ = DeleteEndPoints(k8s, namespace)
	_ = DeleteServices(k8s, namespace)
}
func checkStartingIP(ip string, number int, ipv6 bool) ([]byte, error) {
	var addr []byte
	firstByteLimit := 223
	if ipv6 {
		addr = net.ParseIP(ip).To16()
		firstByteLimit = 32
	} else {
		addr = net.ParseIP(ip).To4()
	}
	total := int((254 - addr[len(addr)-1]))
	for i := len(addr) - 2; i > 0; i-- {
		total += (int(255-addr[i]) * total)
		if total > number {
			return addr, nil
		}
	}
	if int(addr[0]) < firstByteLimit {
		total += ((firstByteLimit - int(addr[0])) * total)
	}
	if number > total {
		return nil, fmt.Errorf("start with ip address: %s, does not allow generating of %d sequential addresses", ip, number)
	}
	return addr, nil
}
func GenerateTestObjects(k8s *kubernetes.Clientset, namespace, stackMode string, svcNumber, subsetNumber, ipInSubset int, startIPv4, startIPv6 string) error {
	totalIPs := svcNumber * subsetNumber * ipInSubset
	var ipv6 bool
	var addr []byte
	var err error
	switch stackMode {
	case "ipv4":
		addr, err = checkStartingIP(startIPv4, totalIPs, false)
		if err != nil {
			return err
		}
		ipv6 = false
	case "ipv6":
		addr, err = checkStartingIP(startIPv6, totalIPs, true)
		if err != nil {
			return err
		}
		ipv6 = true
	case "dual":
	}
	subsets := generateSusbsets(addr, ipv6, totalIPs, ipInSubset)
	endpoints := generateEndpoints(subsets, namespace, subsetNumber)
	services := generateServices(endpoints, namespace)
	if err := CreateService(k8s, services); err != nil {
		return err
	}
	if err := CreateEndPoint(k8s, endpoints); err != nil {
		return err
	}
	return nil
}
func generateServices(endpoints []v1.Endpoints, namespace string) []v1.Service {
	svcs := make([]v1.Service, 0)
	for i := 0; i < len(endpoints); i++ {
		ports := make([]v1.ServicePort, 0)
		for _, subset := range endpoints[i].Subsets {
			for _, port := range subset.Ports {
				ports = append(ports, v1.ServicePort{
					Name:     port.Name,
					Protocol: port.Protocol,
					Port:     port.Port,
				})
			}
		}
		svcs = append(svcs, v1.Service{
			ObjectMeta: meta_v1.ObjectMeta{
				Name:      endpoints[i].ObjectMeta.Name,
				Namespace: endpoints[i].ObjectMeta.Namespace,
				Labels:    map[string]string{stressTestLabel: "true"},
			},
			Spec: v1.ServiceSpec{
				Ports: ports,
			},
		})
	}
	return svcs
}