github.com/interconnectedcloud/qdr-operator@v0.0.0-20210826174505-576d2b33dac7/pkg/resources/services/service.go (about) 1 package services 2 3 import ( 4 "reflect" 5 "strconv" 6 7 v1alpha1 "github.com/interconnectedcloud/qdr-operator/pkg/apis/interconnectedcloud/v1alpha1" 8 "github.com/interconnectedcloud/qdr-operator/pkg/constants" 9 "github.com/interconnectedcloud/qdr-operator/pkg/utils/selectors" 10 corev1 "k8s.io/api/core/v1" 11 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 12 "k8s.io/apimachinery/pkg/util/intstr" 13 logf "sigs.k8s.io/controller-runtime/pkg/runtime/log" 14 ) 15 16 var ( 17 log = logf.Log.WithName("services") 18 ) 19 20 func nameForListener(l *v1alpha1.Listener) string { 21 if l.Name == "" { 22 return strconv.Itoa(int(l.Port)) 23 } else { 24 return l.Name 25 } 26 } 27 28 func servicePortsForListeners(listeners []v1alpha1.Listener) []corev1.ServicePort { 29 ports := []corev1.ServicePort{} 30 for _, listener := range listeners { 31 ports = append(ports, corev1.ServicePort{ 32 Name: nameForListener(&listener), 33 Protocol: "TCP", 34 Port: listener.Port, 35 TargetPort: intstr.FromInt(int(listener.Port)), 36 }) 37 } 38 return ports 39 } 40 41 func servicePortsForRouter(m *v1alpha1.Interconnect) []corev1.ServicePort { 42 ports := []corev1.ServicePort{} 43 external := servicePortsForListeners(m.Spec.Listeners) 44 internal := servicePortsForListeners(m.Spec.InterRouterListeners) 45 edge := servicePortsForListeners(m.Spec.EdgeListeners) 46 ports = append(ports, external...) 47 ports = append(ports, internal...) 48 ports = append(ports, edge...) 49 return ports 50 } 51 52 func CheckService(desired *corev1.Service, actual *corev1.Service) bool { 53 update := false 54 if !reflect.DeepEqual(desired.Annotations[constants.CertRequestAnnotation], actual.Annotations[constants.CertRequestAnnotation]) { 55 actual.Annotations[constants.CertRequestAnnotation] = desired.Annotations[constants.CertRequestAnnotation] 56 } 57 if !reflect.DeepEqual(desired.Spec.Selector, actual.Spec.Selector) { 58 actual.Spec.Selector = desired.Spec.Selector 59 } 60 if !reflect.DeepEqual(desired.Spec.Ports, actual.Spec.Ports) { 61 actual.Spec.Ports = desired.Spec.Ports 62 } 63 return update 64 } 65 66 // Create newServiceForCR method to create normal service 67 func NewServiceForCR(m *v1alpha1.Interconnect, requestCert bool) *corev1.Service { 68 labels := selectors.LabelsForInterconnect(m.Name) 69 service := &corev1.Service{ 70 TypeMeta: metav1.TypeMeta{ 71 APIVersion: "v1", 72 Kind: "Service", 73 }, 74 ObjectMeta: metav1.ObjectMeta{ 75 Labels: labels, 76 Name: m.Name, 77 Namespace: m.Namespace, 78 }, 79 Spec: corev1.ServiceSpec{ 80 Selector: labels, 81 Ports: servicePortsForRouter(m), 82 }, 83 } 84 if requestCert { 85 service.Annotations = map[string]string{constants.CertRequestAnnotation: m.Name + "-cert"} 86 } 87 if m.Spec.DeploymentPlan.ServiceType == "ClusterIP" || m.Spec.DeploymentPlan.ServiceType == "NodePort" || m.Spec.DeploymentPlan.ServiceType == "LoadBalancer" { 88 service.Spec.Type = corev1.ServiceType(m.Spec.DeploymentPlan.ServiceType) 89 } else if m.Spec.DeploymentPlan.ServiceType != "" { 90 log.Info("Unrecognised ServiceType", "ServiceType", m.Spec.DeploymentPlan.ServiceType) 91 } 92 return service 93 } 94 95 // Create newServiceForCR method to create normal service 96 func NewNormalServiceForCR(m *v1alpha1.Interconnect, requestCert bool) *corev1.Service { 97 labels := selectors.LabelsForInterconnect(m.Name) 98 service := &corev1.Service{ 99 TypeMeta: metav1.TypeMeta{ 100 APIVersion: "v1", 101 Kind: "Service", 102 }, 103 ObjectMeta: metav1.ObjectMeta{ 104 Labels: labels, 105 Name: m.Name + "-normal", 106 Namespace: m.Namespace, 107 }, 108 Spec: corev1.ServiceSpec{ 109 Type: "LoadBalancer", 110 Selector: labels, 111 Ports: servicePortsForListeners(m.Spec.Listeners), 112 }, 113 } 114 if requestCert { 115 service.Annotations = map[string]string{constants.CertRequestAnnotation: m.Name + "-cert"} 116 } 117 return service 118 } 119 120 // Create newHeadlessServiceForCR method to create normal service 121 func NewHeadlessServiceForCR(m *v1alpha1.Interconnect, requestCert bool) *corev1.Service { 122 service := &corev1.Service{ 123 TypeMeta: metav1.TypeMeta{ 124 APIVersion: "v1", 125 Kind: "Service", 126 }, 127 ObjectMeta: metav1.ObjectMeta{ 128 Name: m.Name + "-headless", 129 Namespace: m.Namespace, 130 }, 131 Spec: corev1.ServiceSpec{ 132 ClusterIP: "None", 133 Selector: selectors.LabelsForInterconnect(m.Name), 134 Ports: servicePortsForListeners(m.Spec.InterRouterListeners), 135 }, 136 } 137 if requestCert { 138 service.Annotations = map[string]string{constants.CertRequestAnnotation: m.Name + "-cert"} 139 } 140 return service 141 }