func CreatePodService(
	cr *kdv1.KubeDirectorCluster,
	role *kdv1.Role,
	podName string,
) (*corev1.Service, error) {
	serviceType := shared.ServiceType(*cr.Spec.ServiceType)
	var name string
	namingScheme := *cr.Spec.NamingScheme
	if namingScheme == v1beta1.CrNameRole {
		name = podName
	} else if namingScheme == v1beta1.UID {
		name = svcNamePrefix + podName
	}
	portInfoList, portsErr := catalog.PortsForRole(cr, role.Name)
	if portsErr != nil {
		return nil, portsErr
	}
	if len(portInfoList) == 0 {
		return nil, nil
	}
	service := &corev1.Service{
		TypeMeta: metav1.TypeMeta{
			Kind:       "Service",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Name:            name,
			Namespace:       cr.Namespace,
			OwnerReferences: shared.OwnerReferences(cr),
			Labels:          labelsForService(cr, role),
			Annotations:     annotationsForService(cr, role),
		},
		Spec: corev1.ServiceSpec{
			Selector:                 map[string]string{statefulSetPodLabel: podName},
			Type:                     serviceType,
			PublishNotReadyAddresses: true,
		},
	}
	for _, portInfo := range portInfoList {
		servicePort := corev1.ServicePort{
			Port: portInfo.Port,
			Name: createPortNameForService(portInfo),
		}
		service.Spec.Ports = append(service.Spec.Ports, servicePort)
	}
	createErr := shared.Create(context.TODO(), service)
	return service, createErr
}
CreatePodService creates in k8s a service that exposes the designated
service endpoints of a virtual cluster member. Depending on the app type
definition, this will be either a NodePort service (default) or a
LoadBalancer service. If there are no ports to configure for this service,
no service object will be created and the function will return (nil, nil).
package executor
import (
	"context"
	"github.com/bluek8s/kubedirector/pkg/apis/kubedirector/v1beta1"
	kdv1 "github.com/bluek8s/kubedirector/pkg/apis/kubedirector/v1beta1"
	"github.com/bluek8s/kubedirector/pkg/catalog"
	"github.com/bluek8s/kubedirector/pkg/shared"
	"github.com/go-logr/logr"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/api/errors"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/apimachinery/pkg/types"
)
func CreateHeadlessService(
	cr *kdv1.KubeDirectorCluster,
) (*corev1.Service, error) {
	service := &corev1.Service{
		TypeMeta: metav1.TypeMeta{
			Kind:       "Service",
			APIVersion: "v1",
		},
		ObjectMeta: metav1.ObjectMeta{
			Namespace:       cr.Namespace,
			OwnerReferences: shared.OwnerReferences(cr),
			Labels:          labelsForService(cr, nil),
			Annotations:     annotationsForService(cr, nil),
		},
		Spec: corev1.ServiceSpec{
			ClusterIP: "None",
			Selector: map[string]string{
				HeadlessServiceLabel: cr.Name,
			},
			PublishNotReadyAddresses: true,
			Ports: []corev1.ServicePort{
				{
					Name: "port",
					Port: 8888,  
				},
			},
		},
	}
	namingScheme := *cr.Spec.NamingScheme
	if cr.Status.ClusterService == "" {
		if namingScheme == v1beta1.CrNameRole {
			service.ObjectMeta.GenerateName = MungObjectName(cr.Name)
		} else if namingScheme == v1beta1.UID {
			service.ObjectMeta.GenerateName = headlessSvcNamePrefix
		}
	} else {
		service.ObjectMeta.Name = cr.Status.ClusterService
	}
	err := shared.Create(context.TODO(), service)
	return service, err
}
func UpdateHeadlessService(
	reqLogger logr.Logger,
	cr *kdv1.KubeDirectorCluster,
	service *corev1.Service,
) error {
	if shared.OwnerReferencesPresent(cr, service.OwnerReferences) {
		return nil
	}
	shared.LogInfof(
		reqLogger,
		cr,
		shared.EventReasonNoEvent,
		"repairing owner ref on service{%s}",
		service.Name,
	)
	patchedRes := *service
	patchedRes.OwnerReferences = shared.OwnerReferences(cr)
	return shared.Patch(
		context.TODO(),
		service,
		&patchedRes,
	)
}