You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by su...@apache.org on 2023/01/27 03:41:46 UTC

[shardingsphere-on-cloud] branch main updated: refactor(operator): refactor Service and ConfigMap build (#190)

This is an automated email from the ASF dual-hosted git repository.

sunnianjun pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/shardingsphere-on-cloud.git


The following commit(s) were added to refs/heads/main by this push:
     new 6ce0649  refactor(operator): refactor Service and ConfigMap build (#190)
6ce0649 is described below

commit 6ce06492698bda13c0748d84aa6370eaa599f457
Author: liyao <ma...@126.com>
AuthorDate: Fri Jan 27 11:41:41 2023 +0800

    refactor(operator): refactor Service and ConfigMap build (#190)
    
    * feat: add builder for ConfigMap
    
    Signed-off-by: mlycore <ma...@126.com>
    
    * feat: add builder for Service
    
    Signed-off-by: mlycore <ma...@126.com>
    
    * refactor: using builder for ConfigMap and Service
    
    Signed-off-by: mlycore <ma...@126.com>
    
    * fix: fix unit test
    
    Signed-off-by: mlycore <ma...@126.com>
    
    Signed-off-by: mlycore <ma...@126.com>
---
 .../cmd/shardingsphere-operator/manager/manager.go |   4 +
 .../pkg/controllers/compute_node_controller.go     | 117 ++++++++++++++-------
 .../pkg/kubernetes/configmap/configmap.go          |  75 +++++++++++++
 .../pkg/kubernetes/service/service.go              |  74 +++++++++++++
 .../pkg/reconcile/computenode/configmap.go         |  79 +++++++++++---
 .../pkg/reconcile/computenode/service.go           |  88 ++++++++++++----
 .../pkg/reconcile/computenode/service_test.go      |   2 +-
 7 files changed, 369 insertions(+), 70 deletions(-)

diff --git a/shardingsphere-operator/cmd/shardingsphere-operator/manager/manager.go b/shardingsphere-operator/cmd/shardingsphere-operator/manager/manager.go
index 6e14a67..5ab4eb1 100644
--- a/shardingsphere-operator/cmd/shardingsphere-operator/manager/manager.go
+++ b/shardingsphere-operator/cmd/shardingsphere-operator/manager/manager.go
@@ -22,7 +22,9 @@ import (
 	"flag"
 	"os"
 
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/configmap"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/deployment"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/service"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/metrics"
 
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
@@ -114,6 +116,8 @@ func New(opts *Options) *Manager {
 			Scheme:     mgr.GetScheme(),
 			Log:        mgr.GetLogger(),
 			Deployment: deployment.NewDeployment(mgr.GetClient()),
+			Service:    service.NewService(mgr.GetClient()),
+			ConfigMap:  configmap.NewConfigMap(mgr.GetClient()),
 		}).SetupWithManager(mgr); err != nil {
 			setupLog.Error(err, "unable to create controller", "controller", "ComputeNode")
 			os.Exit(1)
diff --git a/shardingsphere-operator/pkg/controllers/compute_node_controller.go b/shardingsphere-operator/pkg/controllers/compute_node_controller.go
index 8849f6a..b52502e 100644
--- a/shardingsphere-operator/pkg/controllers/compute_node_controller.go
+++ b/shardingsphere-operator/pkg/controllers/compute_node_controller.go
@@ -22,7 +22,9 @@ import (
 	"time"
 
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/configmap"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/deployment"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/service"
 	reconcile "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/computenode"
 	"github.com/go-logr/logr"
 	appsv1 "k8s.io/api/apps/v1"
@@ -46,8 +48,8 @@ type ComputeNodeReconciler struct {
 	Log    logr.Logger
 
 	Deployment deployment.Deployment
-	// Service
-	// ConfigMap
+	Service    service.Service
+	ConfigMap  configmap.ConfigMap
 }
 
 // SetupWithManager sets up the controller with the Manager.
@@ -151,23 +153,32 @@ func (r *ComputeNodeReconciler) getDeploymentByNamespacedName(ctx context.Contex
 }
 
 func (r *ComputeNodeReconciler) reconcileService(ctx context.Context, cn *v1alpha1.ComputeNode) error {
-	cur := &v1.Service{}
-	if err := r.Get(ctx, types.NamespacedName{
-		Namespace: cn.Namespace,
-		Name:      cn.Name,
-	}, cur); err != nil {
-		if apierrors.IsNotFound(err) {
-			// create
-			exp := reconcile.ComputeNodeNewService(cn)
-			if err := r.Create(ctx, exp); err != nil {
+	svc, found, err := r.getServiceByNamespacedName(ctx, types.NamespacedName{Namespace: cn.Namespace, Name: cn.Name})
+	if found {
+		if err := r.updateService(ctx, cn, svc); err != nil {
+			return err
+		}
+	} else {
+		if err != nil {
+			return err
+		} else {
+			if err := r.createService(ctx, cn); err != nil {
 				return err
 			}
-			return nil
-		} else {
-			return err
 		}
 	}
+	return nil
+}
 
+func (r *ComputeNodeReconciler) createService(ctx context.Context, cn *v1alpha1.ComputeNode) error {
+	svc := reconcile.NewService(cn)
+	if err := r.Create(ctx, svc); err != nil {
+		return err
+	}
+	return nil
+}
+
+func (r *ComputeNodeReconciler) updateService(ctx context.Context, cn *v1alpha1.ComputeNode, cur *v1.Service) error {
 	if cn.Spec.ServiceType == v1.ServiceTypeNodePort {
 		for _, p := range cur.Spec.Ports {
 			for idx := range cn.Spec.PortBindings {
@@ -195,40 +206,74 @@ func (r *ComputeNodeReconciler) reconcileService(ctx context.Context, cn *v1alph
 		}
 	}
 
-	// update
-	exp := reconcile.ComputeNodeUpdateService(cn, cur)
+	exp := reconcile.UpdateService(cn, cur)
 	if err := r.Update(ctx, exp); err != nil {
 		return err
 	}
-
 	return nil
 }
 
-func (r *ComputeNodeReconciler) reconcileConfigMap(ctx context.Context, cn *v1alpha1.ComputeNode) error {
-	cur := &v1.ConfigMap{}
-	if err := r.Get(ctx, types.NamespacedName{
-		Namespace: cn.Namespace,
-		Name:      cn.Name,
-	}, cur); err != nil {
-		if apierrors.IsNotFound(err) {
-			// create
-			exp := reconcile.ComputeNodeNewConfigMap(cn)
-			if err := r.Create(ctx, exp); err != nil {
-				return err
-			}
-			return nil
-		} else {
-			return err
-		}
+func (r *ComputeNodeReconciler) getServiceByNamespacedName(ctx context.Context, namespacedName types.NamespacedName) (*v1.Service, bool, error) {
+	svc, err := r.Service.GetByNamespacedName(ctx, namespacedName)
+	// found
+	if svc != nil {
+		return svc, true, nil
+	}
+	// error
+	if err != nil {
+		return nil, false, err
+	} else {
+		// not found
+		return nil, false, nil
 	}
+}
+
+func (r *ComputeNodeReconciler) createConfigMap(ctx context.Context, cn *v1alpha1.ComputeNode) error {
+	cm := reconcile.NewConfigMap(cn)
+	if err := r.Create(ctx, cm); err != nil {
+		return err
+	}
+	return nil
+}
 
-	// update
-	//FIXME: need to rolling update Deployment if ConfigMap indeed updated
-	exp := reconcile.ComputeNodeUpdateConfigMap(cn, cur)
+func (r *ComputeNodeReconciler) updateConfigMap(ctx context.Context, cn *v1alpha1.ComputeNode, cm *v1.ConfigMap) error {
+	exp := reconcile.UpdateConfigMap(cn, cm)
 	if err := r.Update(ctx, exp); err != nil {
 		return err
 	}
+	return nil
+}
 
+func (r *ComputeNodeReconciler) getConfigMapByNamespacedName(ctx context.Context, namespacedName types.NamespacedName) (*v1.ConfigMap, bool, error) {
+	cm, err := r.ConfigMap.GetByNamespacedName(ctx, namespacedName)
+	// found
+	if cm != nil {
+		return cm, true, nil
+	}
+	// error
+	if err != nil {
+		return nil, false, err
+	} else {
+		// not found
+		return nil, false, nil
+	}
+}
+
+func (r *ComputeNodeReconciler) reconcileConfigMap(ctx context.Context, cn *v1alpha1.ComputeNode) error {
+	cm, found, err := r.getConfigMapByNamespacedName(ctx, types.NamespacedName{Namespace: cn.Namespace, Name: cn.Name})
+	if found {
+		if err := r.updateConfigMap(ctx, cn, cm); err != nil {
+			return err
+		}
+	} else {
+		if err != nil {
+			return err
+		} else {
+			if err := r.createConfigMap(ctx, cn); err != nil {
+				return err
+			}
+		}
+	}
 	return nil
 }
 
diff --git a/shardingsphere-operator/pkg/kubernetes/configmap/configmap.go b/shardingsphere-operator/pkg/kubernetes/configmap/configmap.go
new file mode 100644
index 0000000..bf188ef
--- /dev/null
+++ b/shardingsphere-operator/pkg/kubernetes/configmap/configmap.go
@@ -0,0 +1,75 @@
+/*
+ * 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 configmap
+
+import (
+	"context"
+
+	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func NewConfigMap(c client.Client) ConfigMap {
+	return configmapClient{
+		configmapGetter: configmapGetter{
+			Client: c,
+		},
+		configmapSetter: configmapSetter{
+			Client: c,
+		},
+	}
+}
+
+type ConfigMap interface {
+	ConfigMapGetter
+	ConfigMapSetter
+}
+
+type ConfigMapGetter interface {
+	GetByNamespacedName(context.Context, types.NamespacedName) (*corev1.ConfigMap, error)
+}
+
+type ConfigMapSetter interface {
+}
+
+type configmapClient struct {
+	configmapGetter
+	configmapSetter
+}
+
+type configmapGetter struct {
+	client.Client
+}
+
+func (cg configmapGetter) GetByNamespacedName(ctx context.Context, namespacedName types.NamespacedName) (*corev1.ConfigMap, error) {
+	cm := &corev1.ConfigMap{}
+	if err := cg.Get(ctx, namespacedName, cm); err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil, nil
+		}
+		return nil, err
+	} else {
+		return cm, err
+	}
+}
+
+type configmapSetter struct {
+	client.Client
+}
diff --git a/shardingsphere-operator/pkg/kubernetes/service/service.go b/shardingsphere-operator/pkg/kubernetes/service/service.go
new file mode 100644
index 0000000..dea41cc
--- /dev/null
+++ b/shardingsphere-operator/pkg/kubernetes/service/service.go
@@ -0,0 +1,74 @@
+/*
+ * 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 (
+	"context"
+
+	corev1 "k8s.io/api/core/v1"
+	apierrors "k8s.io/apimachinery/pkg/api/errors"
+	"k8s.io/apimachinery/pkg/types"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+func NewService(c client.Client) Service {
+	return serviceClient{
+		serviceGetter: serviceGetter{
+			Client: c,
+		},
+		serviceSetter: serviceSetter{
+			Client: c,
+		},
+	}
+}
+
+type Service interface {
+	ServiceGetter
+	ServiceSetter
+}
+
+type ServiceGetter interface {
+	GetByNamespacedName(context.Context, types.NamespacedName) (*corev1.Service, error)
+}
+
+type ServiceSetter interface{}
+
+type serviceClient struct {
+	serviceGetter
+	serviceSetter
+}
+
+type serviceGetter struct {
+	client.Client
+}
+
+type serviceSetter struct {
+	client.Client
+}
+
+func (sg serviceGetter) GetByNamespacedName(ctx context.Context, namespacedName types.NamespacedName) (*corev1.Service, error) {
+	svc := &corev1.Service{}
+	if err := sg.Get(ctx, namespacedName, svc); err != nil {
+		if apierrors.IsNotFound(err) {
+			return nil, nil
+		}
+		return nil, err
+	} else {
+		return svc, nil
+	}
+}
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
index f193eaf..30dba82 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/configmap.go
@@ -36,19 +36,17 @@ const (
 	AnnoLogbackConfig     = "computenode.shardingsphere.org/logback"
 )
 
-func ComputeNodeNewConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
+func NewConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
+	builder := NewConfigMapBuilder(cn.GetObjectMeta(), cn.GetObjectKind().GroupVersionKind())
+	builder.SetName(cn.Name).SetNamespace(cn.Namespace).SetLabels(cn.Labels).SetAnnotations(cn.Annotations)
+
 	cluster := cn.Annotations[AnnoClusterRepoConfig]
 	logback := cn.Annotations[AnnoLogbackConfig]
 
-	cm := ComputeNodeDefaultConfigMap(cn.GetObjectMeta(), cn.GroupVersionKind())
-	cm.Name = cn.Name
-	cm.Namespace = cn.Namespace
-	cm.Labels = cn.Labels
-
 	if len(logback) > 0 {
-		cm.Data[ConfigForLogback] = logback
+		builder.SetLogback(logback)
 	} else {
-		cm.Data[ConfigForLogback] = string(defaultLogback)
+		builder.SetLogback(string(defaultLogback))
 	}
 
 	// NOTE: ShardingSphere Proxy 5.3.0 needs a server.yaml no matter if it is empty
@@ -60,16 +58,69 @@ func ComputeNodeNewConfigMap(cn *v1alpha1.ComputeNode) *v1.ConfigMap {
 			}
 		}
 		if y, err := yaml.Marshal(servconf); err == nil {
-			cm.Data[ConfigForServer] = string(y)
+			builder.SetServerConfig(string(y))
 		}
 	} else {
-		cm.Data[ConfigForServer] = "# Empty file is needed"
+		builder.SetServerConfig("# Empty file is needed")
 	}
 
-	return cm
+	return builder.Build()
+}
+
+type ConfigMapBuilder interface {
+	SetName(name string) ConfigMapBuilder
+	SetNamespace(namespace string) ConfigMapBuilder
+	SetLabels(labels map[string]string) ConfigMapBuilder
+	SetAnnotations(annos map[string]string) ConfigMapBuilder
+	SetLogback(logback string) ConfigMapBuilder
+	SetServerConfig(serverConfig string) ConfigMapBuilder
+	Build() *v1.ConfigMap
+}
+
+type configmapBuilder struct {
+	configmap *v1.ConfigMap
+}
+
+func NewConfigMapBuilder(meta metav1.Object, gvk schema.GroupVersionKind) ConfigMapBuilder {
+	return &configmapBuilder{
+		configmap: DefaultConfigMap(meta, gvk),
+	}
+}
+
+func (c *configmapBuilder) SetName(name string) ConfigMapBuilder {
+	c.configmap.Name = name
+	return c
+}
+
+func (c *configmapBuilder) SetNamespace(namespace string) ConfigMapBuilder {
+	c.configmap.Namespace = namespace
+	return c
+}
+
+func (c *configmapBuilder) SetLabels(labels map[string]string) ConfigMapBuilder {
+	c.configmap.Labels = labels
+	return c
+}
+
+func (c *configmapBuilder) SetAnnotations(annos map[string]string) ConfigMapBuilder {
+	c.configmap.Annotations = annos
+	return c
+}
+func (c *configmapBuilder) SetLogback(logback string) ConfigMapBuilder {
+	c.configmap.Data[ConfigForLogback] = logback
+	return c
+}
+
+func (c *configmapBuilder) SetServerConfig(serviceConfig string) ConfigMapBuilder {
+	c.configmap.Data[ConfigForServer] = serviceConfig
+	return c
+}
+
+func (c *configmapBuilder) Build() *v1.ConfigMap {
+	return c.configmap
 }
 
-func ComputeNodeDefaultConfigMap(meta metav1.Object, gvk schema.GroupVersionKind) *v1.ConfigMap {
+func DefaultConfigMap(meta metav1.Object, gvk schema.GroupVersionKind) *v1.ConfigMap {
 	return &v1.ConfigMap{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      "shardingsphere-proxy",
@@ -84,13 +135,13 @@ func ComputeNodeDefaultConfigMap(meta metav1.Object, gvk schema.GroupVersionKind
 }
 
 // FIXME: check if changed first, then decide if need to respawn the Pods
-func ComputeNodeUpdateConfigMap(cn *v1alpha1.ComputeNode, cur *v1.ConfigMap) *v1.ConfigMap {
+func UpdateConfigMap(cn *v1alpha1.ComputeNode, cur *v1.ConfigMap) *v1.ConfigMap {
 	exp := &v1.ConfigMap{}
 	exp.ObjectMeta = cur.ObjectMeta
 	exp.ObjectMeta.ResourceVersion = ""
 	exp.Labels = cur.Labels
 	exp.Annotations = cur.Annotations
-	exp.Data = ComputeNodeNewConfigMap(cn).Data
+	exp.Data = NewConfigMap(cn).Data
 	return exp
 }
 
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/service.go b/shardingsphere-operator/pkg/reconcile/computenode/service.go
index f1ecad3..8a569f5 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/service.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/service.go
@@ -26,31 +26,82 @@ import (
 	"k8s.io/apimachinery/pkg/util/intstr"
 )
 
-func ComputeNodeNewService(cn *v1alpha1.ComputeNode) *v1.Service {
-	svc := ComputeNodeDefaultService(cn.GetObjectMeta(), cn.GroupVersionKind())
-	svc.Name = cn.Name
-	svc.Namespace = cn.Namespace
-	svc.Labels = cn.Labels
-	svc.Spec.Selector = cn.Spec.Selector.MatchLabels
-	svc.Spec.Type = cn.Spec.ServiceType
-
-	if svc.Spec.Ports == nil {
-		svc.Spec.Ports = []corev1.ServicePort{}
-	}
+func NewService(cn *v1alpha1.ComputeNode) *v1.Service {
+	builder := NewServiceBuilder(cn.GetObjectMeta(), cn.GetObjectKind().GroupVersionKind())
+	builder.SetName(cn.Name).SetNamespace(cn.Namespace).SetLabelsAndSelectors(cn.Labels, cn.Spec.Selector).SetAnnotations(cn.Annotations).SetType(cn.Spec.ServiceType)
+
+	ports := []v1.ServicePort{}
 	for _, pb := range cn.Spec.PortBindings {
-		svc.Spec.Ports = append(svc.Spec.Ports, corev1.ServicePort{
+		ports = append(ports, corev1.ServicePort{
 			Name:       pb.Name,
-			TargetPort: intstr.FromInt(int(pb.ContainerPort)),
 			Port:       pb.ServicePort,
-			NodePort:   pb.NodePort,
+			TargetPort: intstr.FromInt(int(pb.ContainerPort)),
 			Protocol:   pb.Protocol,
 		})
 	}
+	builder.SetPorts(ports)
+	return builder.Build()
+}
+
+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
+}
+
+func NewServiceBuilder(meta metav1.Object, gvk schema.GroupVersionKind) ServiceBuilder {
+	return &serviceBuilder{
+		service: DefaultService(meta, gvk),
+	}
+}
+
+type serviceBuilder struct {
+	service *corev1.Service
+}
+
+func (s *serviceBuilder) SetName(name string) ServiceBuilder {
+	s.service.Name = name
+	return s
+}
+
+func (s *serviceBuilder) SetNamespace(namespace string) ServiceBuilder {
+	s.service.Namespace = namespace
+	return s
+}
+
+func (s *serviceBuilder) SetLabelsAndSelectors(labels map[string]string, selectors *metav1.LabelSelector) ServiceBuilder {
+	s.service.Labels = labels
+	s.service.Spec.Selector = selectors.MatchLabels
+	return s
+}
+
+func (s *serviceBuilder) SetAnnotations(annos map[string]string) ServiceBuilder {
+	s.service.Annotations = annos
+	return s
+}
+
+func (s *serviceBuilder) SetType(t corev1.ServiceType) ServiceBuilder {
+	s.service.Spec.Type = t
+	return s
+}
+
+func (s *serviceBuilder) SetPorts(ports []corev1.ServicePort) ServiceBuilder {
+	if s.service.Spec.Ports == nil {
+		s.service.Spec.Ports = []v1.ServicePort{}
+	}
+	s.service.Spec.Ports = ports
+	return s
+}
 
-	return svc
+func (s *serviceBuilder) Build() *corev1.Service {
+	return s.service
 }
 
-func ComputeNodeDefaultService(meta metav1.Object, gvk schema.GroupVersionKind) *v1.Service {
+func DefaultService(meta metav1.Object, gvk schema.GroupVersionKind) *v1.Service {
 	return &v1.Service{
 		ObjectMeta: metav1.ObjectMeta{
 			Name:      "shardingsphere-proxy",
@@ -63,17 +114,16 @@ func ComputeNodeDefaultService(meta metav1.Object, gvk schema.GroupVersionKind)
 		Spec: v1.ServiceSpec{
 			Selector: map[string]string{},
 			Type:     v1.ServiceTypeClusterIP,
-			Ports:    []v1.ServicePort{},
 		},
 	}
 }
 
-func ComputeNodeUpdateService(cn *v1alpha1.ComputeNode, cur *v1.Service) *v1.Service {
+func UpdateService(cn *v1alpha1.ComputeNode, cur *v1.Service) *v1.Service {
 	exp := &v1.Service{}
 	exp.ObjectMeta = cur.ObjectMeta
 	exp.Labels = cur.Labels
 	exp.Annotations = cur.Annotations
-	exp.Spec = ComputeNodeNewService(cn).Spec
+	exp.Spec = NewService(cn).Spec
 	exp.Spec.ClusterIP = cur.Spec.ClusterIP
 	exp.Spec.ClusterIPs = cur.Spec.ClusterIPs
 	if cn.Spec.ServiceType == corev1.ServiceTypeNodePort {
diff --git a/shardingsphere-operator/pkg/reconcile/computenode/service_test.go b/shardingsphere-operator/pkg/reconcile/computenode/service_test.go
index 0a08d2c..bdd811a 100644
--- a/shardingsphere-operator/pkg/reconcile/computenode/service_test.go
+++ b/shardingsphere-operator/pkg/reconcile/computenode/service_test.go
@@ -223,7 +223,7 @@ func Test_ComputeNodeUpdateService(t *testing.T) {
 	}
 
 	for _, c := range cases {
-		act := ComputeNodeUpdateService(c.cn, c.cur)
+		act := UpdateService(c.cn, c.cur)
 		assert.Equal(t, act, c.exp, fmt.Sprintf("%d: %s\n", c.id, c.msg))
 	}
 }