shardingsphere-operator/pkg/kubernetes/service/builder.go (147 lines of code) (raw):

/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package service import ( "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apimachinery/pkg/util/intstr" ) const ( commonAnnotationPrometheusMetricsPath = "prometheus.io/path" commonAnnotationPrometheusMetricsPort = "prometheus.io/port" commonAnnotationPrometheusMetricsScrape = "prometheus.io/scrape" commonAnnotationPrometheusMetricsScheme = "prometheus.io/scheme" DefaultAnnotationJavaAgentEnabled = "shardingsphere.apache.org/java-agent-enabled" ) // NewService returns a new Service func NewService(cn *v1alpha1.ComputeNode) *corev1.Service { builder := NewServiceBuilder(cn.GetObjectMeta(), cn.GetObjectKind().GroupVersionKind()) builder.SetName(cn.Name).SetNamespace(cn.Namespace).SetLabelsAndSelectors(cn.Labels, cn.Spec.Selector).SetType(cn.Spec.ServiceType) ports := []corev1.ServicePort{} for idx := range cn.Spec.PortBindings { ports = append(ports, corev1.ServicePort{ Name: cn.Spec.PortBindings[idx].Name, Port: cn.Spec.PortBindings[idx].ServicePort, TargetPort: intstr.FromInt(int(cn.Spec.PortBindings[idx].ContainerPort)), Protocol: cn.Spec.PortBindings[idx].Protocol, }) } if enabled, ok := cn.Annotations[DefaultAnnotationJavaAgentEnabled]; ok && enabled == "true" { metricsAnnos := map[string]string{} metricsAnnos[commonAnnotationPrometheusMetricsPath] = cn.Annotations[commonAnnotationPrometheusMetricsPath] metricsAnnos[commonAnnotationPrometheusMetricsPort] = cn.Annotations[commonAnnotationPrometheusMetricsPort] metricsAnnos[commonAnnotationPrometheusMetricsScrape] = cn.Annotations[commonAnnotationPrometheusMetricsScrape] metricsAnnos[commonAnnotationPrometheusMetricsScheme] = cn.Annotations[commonAnnotationPrometheusMetricsScheme] builder.SetAnnotations(metricsAnnos) var found bool for i := range ports { if ports[i].Name == "metrics" { ports[i].TargetPort = intstr.FromInt(int(cn.Spec.Bootstrap.AgentConfig.Plugins.Metrics.Prometheus.Port)) found = true break } } if !found { ports = append(ports, corev1.ServicePort{ Name: "metrics", Port: 9090, TargetPort: intstr.FromInt(int(cn.Spec.Bootstrap.AgentConfig.Plugins.Metrics.Prometheus.Port)), }) } } builder.SetPorts(ports) return builder.Build() } // ServiceBuilder returns a ServiceBuilder type ServiceBuilder interface { SetName(name string) ServiceBuilder SetNamespace(namespace string) ServiceBuilder SetLabelsAndSelectors(labels map[string]string, selectors *metav1.LabelSelector) ServiceBuilder SetAnnotations(anno map[string]string) ServiceBuilder SetType(t corev1.ServiceType) ServiceBuilder SetPorts(ports []corev1.ServicePort) ServiceBuilder Build() *corev1.Service } // NewServiceBuilder returns a ServiceBuilder func NewServiceBuilder(meta metav1.Object, gvk schema.GroupVersionKind) ServiceBuilder { return &serviceBuilder{ service: DefaultService(meta, gvk), } } type serviceBuilder struct { service *corev1.Service } // SetName sets the name of Service func (s *serviceBuilder) SetName(name string) ServiceBuilder { s.service.Name = name return s } // SetNamespace sets the namespace of Service func (s *serviceBuilder) SetNamespace(namespace string) ServiceBuilder { s.service.Namespace = namespace return s } // SetLabelsAndSelectors sets the labels and selectors of Service func (s *serviceBuilder) SetLabelsAndSelectors(labels map[string]string, selectors *metav1.LabelSelector) ServiceBuilder { s.service.Labels = labels s.service.Spec.Selector = selectors.MatchLabels return s } // SetAnnotations sets the annotations of Service func (s *serviceBuilder) SetAnnotations(annos map[string]string) ServiceBuilder { s.service.Annotations = annos return s } // SetType sets the ServiceType of Service func (s *serviceBuilder) SetType(t corev1.ServiceType) ServiceBuilder { s.service.Spec.Type = t return s } // SetPorts sets ports of Service func (s *serviceBuilder) SetPorts(ports []corev1.ServicePort) ServiceBuilder { if s.service.Spec.Ports == nil { s.service.Spec.Ports = []corev1.ServicePort{} } s.service.Spec.Ports = ports return s } // Build builds the Service func (s *serviceBuilder) Build() *corev1.Service { return s.service } // DefaultService returns the default Service func DefaultService(meta metav1.Object, gvk schema.GroupVersionKind) *corev1.Service { return &corev1.Service{ ObjectMeta: metav1.ObjectMeta{ Name: "shardingsphere-proxy", Namespace: "default", Labels: map[string]string{}, OwnerReferences: []metav1.OwnerReference{ *metav1.NewControllerRef(meta, gvk), }, }, Spec: corev1.ServiceSpec{ Selector: map[string]string{}, Type: corev1.ServiceTypeClusterIP, }, } } // UpdateService update Service func UpdateService(cn *v1alpha1.ComputeNode, svc *corev1.Service) *corev1.Service { exp := NewService(cn) exp.ObjectMeta = svc.ObjectMeta exp.Spec.ClusterIP = svc.Spec.ClusterIP exp.Spec.ClusterIPs = svc.Spec.ClusterIPs if cn.Spec.ServiceType == corev1.ServiceTypeNodePort { exp.Spec.Ports = updateNodePorts(cn.Spec.PortBindings, svc.Spec.Ports) } return exp } func updateNodePorts(portbindings []v1alpha1.PortBinding, svcports []corev1.ServicePort) []corev1.ServicePort { ports := []corev1.ServicePort{} for pb := range portbindings { for sp := range svcports { if portbindings[pb].Name == svcports[sp].Name { port := corev1.ServicePort{ Name: portbindings[pb].Name, TargetPort: intstr.FromInt(int(portbindings[pb].ContainerPort)), Port: portbindings[pb].ServicePort, Protocol: portbindings[pb].Protocol, } if svcports[sp].NodePort != 0 { port.NodePort = svcports[sp].NodePort } ports = append(ports, port) } } } return ports }