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 0b0d762  refactor: refactor reconcile and resources  (#148)
0b0d762 is described below

commit 0b0d762c0c49c90911aaafc90727132aa4a6c881
Author: liyao <[email protected]>
AuthorDate: Fri Dec 16 16:07:44 2022 +0800

    refactor: refactor reconcile and resources  (#148)
    
    * refactor: refactor workloads
    
    Signed-off-by: mlycore <[email protected]>
    
    * chore: go fmt
    
    Signed-off-by: mlycore <[email protected]>
    
    * fix: IsNotFound should be checked while error is not nil
    
    Signed-off-by: mlycore <[email protected]>
    
    * chore: update UpdateDeployment
    
    Signed-off-by: mlycore <[email protected]>
    
    Signed-off-by: mlycore <[email protected]>
---
 .../api/v1alpha1/groupversion_info.go              |   4 +-
 .../api/v1alpha1/proxy_status.go                   |  16 +-
 .../pkg/controllers/proxy_controller.go            | 196 ++++++++------
 shardingsphere-operator/pkg/reconcile/coverage.txt |  54 ++++
 .../pkg/reconcile/deployment.go                    | 194 ++++++++++++++
 shardingsphere-operator/pkg/reconcile/hpa.go       | 104 ++++++++
 .../pkg/reconcile/reconcile_test.go                | 116 ++++-----
 shardingsphere-operator/pkg/reconcile/resource.go  | 281 +--------------------
 shardingsphere-operator/pkg/reconcile/service.go   |  72 ++++++
 9 files changed, 610 insertions(+), 427 deletions(-)

diff --git a/shardingsphere-operator/api/v1alpha1/groupversion_info.go 
b/shardingsphere-operator/api/v1alpha1/groupversion_info.go
index 7af5844..3e1541c 100644
--- a/shardingsphere-operator/api/v1alpha1/groupversion_info.go
+++ b/shardingsphere-operator/api/v1alpha1/groupversion_info.go
@@ -16,8 +16,8 @@
  */
 
 // Package v1alpha1 contains API Schema definitions for the shardingsphere 
v1alpha1 API group
-//+kubebuilder:object:generate=true
-//+groupName=shardingsphere.apache.org
+// +kubebuilder:object:generate=true
+// +groupName=shardingsphere.apache.org
 package v1alpha1
 
 import (
diff --git a/shardingsphere-operator/api/v1alpha1/proxy_status.go 
b/shardingsphere-operator/api/v1alpha1/proxy_status.go
index a769ff1..af6ffb7 100644
--- a/shardingsphere-operator/api/v1alpha1/proxy_status.go
+++ b/shardingsphere-operator/api/v1alpha1/proxy_status.go
@@ -56,14 +56,14 @@ type ProxyStatus struct {
 type Conditions []Condition
 
 // Condition
-//| **condition** | **status** | **directions**|
-//| ------------- | ---------- | 
---------------------------------------------------- |
-//| Initialized   | true       | Initialization successful|
-//| Initialized   | false      | initialization failed|
-//| Started       | true       | pod started successfully but not ready|
-//| Started       | false      | pod started failed|
-//| Ready         | true       | The pod is ready and can provide external 
services|
-//| Unknown       | true       | ShardingSphere-Proxy failed to start 
correctly due to some problems |
+// | **condition** | **status** | **directions**|
+// | ------------- | ---------- | 
---------------------------------------------------- |
+// | Initialized   | true       | Initialization successful|
+// | Initialized   | false      | initialization failed|
+// | Started       | true       | pod started successfully but not ready|
+// | Started       | false      | pod started failed|
+// | Ready         | true       | The pod is ready and can provide external 
services|
+// | Unknown       | true       | ShardingSphere-Proxy failed to start 
correctly due to some problems |
 type Condition struct {
        Type           ConditionType      `json:"type"`
        Status         v1.ConditionStatus `json:"status"`
diff --git a/shardingsphere-operator/pkg/controllers/proxy_controller.go 
b/shardingsphere-operator/pkg/controllers/proxy_controller.go
index 93ae6dd..85bf3c8 100644
--- a/shardingsphere-operator/pkg/controllers/proxy_controller.go
+++ b/shardingsphere-operator/pkg/controllers/proxy_controller.go
@@ -23,13 +23,16 @@ import (
 
        
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
        
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile"
+
        appsv1 "k8s.io/api/apps/v1"
        autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
        v1 "k8s.io/api/core/v1"
        apierrors "k8s.io/apimachinery/pkg/api/errors"
        "k8s.io/apimachinery/pkg/runtime"
+       "k8s.io/apimachinery/pkg/types"
        ctrl "sigs.k8s.io/controller-runtime"
        "sigs.k8s.io/controller-runtime/pkg/client"
+
        logger "sigs.k8s.io/controller-runtime/pkg/log"
 )
 
@@ -61,106 +64,144 @@ type ProxyReconciler struct {
 func (r *ProxyReconciler) Reconcile(ctx context.Context, req ctrl.Request) 
(ctrl.Result, error) {
        log := logger.FromContext(ctx)
 
-       run := &v1alpha1.ShardingSphereProxy{}
-       err := r.Get(ctx, req.NamespacedName, run)
+       rt, err := r.getRuntimeShardingSphereProxy(ctx, req.NamespacedName)
        if apierrors.IsNotFound(err) {
                log.Info("Resource in work queue no longer exists!")
                return ctrl.Result{}, nil
        } else if err != nil {
-               log.Error(err, "Error getting  CRD resource")
+               log.Error(err, "Error getting CRD resource")
                return ctrl.Result{}, err
        }
 
-       runtimeDeployment := &appsv1.Deployment{}
-       err = r.Get(ctx, req.NamespacedName, runtimeDeployment)
-       if err != nil && !apierrors.IsNotFound(err) {
-               log.Error(err, "Error getting cascaded HPA")
-               return ctrl.Result{}, err
+       return r.reconcile(ctx, req, rt)
+}
+
+func (r *ProxyReconciler) getRuntimeShardingSphereProxy(ctx context.Context, 
namespacedName types.NamespacedName) (*v1alpha1.ShardingSphereProxy, error) {
+       rt := &v1alpha1.ShardingSphereProxy{}
+       err := r.Get(ctx, namespacedName, rt)
+       return rt, err
+}
+
+func (r *ProxyReconciler) reconcile(ctx context.Context, req ctrl.Request, rt 
*v1alpha1.ShardingSphereProxy) (ctrl.Result, error) {
+       log := logger.FromContext(ctx)
+       if res, err := r.reconcileDeployment(ctx, req.NamespacedName, rt); err 
!= nil {
+               log.Error(err, "Error reconcile Deployment")
+               return res, err
        }
-       if apierrors.IsNotFound(err) {
-               cascadingDeployment := 
reconcile.ConstructCascadingDeployment(run)
-               err = r.Create(ctx, cascadingDeployment)
-               if err != nil {
-                       run.SetInitializationFailed()
-                       _ = r.Status().Update(ctx, run)
-                       log.Error(err, "Error creating cascaded deployment")
+
+       if res, err := r.reconcileService(ctx, req.NamespacedName, rt); err != 
nil {
+               log.Error(err, "Error reconcile Service")
+               return res, err
+       }
+       if res, err := r.reconcilePodList(ctx, req.Namespace, req.Name, rt); 
err != nil {
+               log.Error(err, "Error reconcile Pod list")
+               return res, err
+       }
+
+       if res, err := r.reconcileHPA(ctx, req.NamespacedName, rt); err != nil {
+               log.Error(err, "Error reconcile HPA")
+               return res, err
+       }
+
+       return ctrl.Result{}, nil
+}
+
+func (r *ProxyReconciler) reconcileDeployment(ctx context.Context, 
namespacedName types.NamespacedName, ssproxy *v1alpha1.ShardingSphereProxy) 
(ctrl.Result, error) {
+       deploy := &appsv1.Deployment{}
+
+       var err error
+       if err = r.Get(ctx, namespacedName, deploy); err != nil {
+               if !apierrors.IsNotFound(err) {
                        return ctrl.Result{}, err
+               } else {
+                       exp := reconcile.NewDeployment(ssproxy)
+                       if err := r.Create(ctx, exp); err != nil {
+                               ssproxy.SetInitializationFailed()
+                               _ = r.Status().Update(ctx, ssproxy)
+                               return ctrl.Result{}, err
+                       }
                }
        } else {
-               originDeployment := runtimeDeployment.DeepCopy()
-               reconcile.UpdateDeployment(run, originDeployment)
-               err = r.Update(ctx, originDeployment)
-               if err != nil {
-                       log.Error(err, "Error updating cascaded deployment")
+               act := deploy.DeepCopy()
+               exp := reconcile.UpdateDeployment(ssproxy, act)
+
+               //FIXME: using diff to trigger update
+               // if reflect.DeepEqual(act.Spec.Template, exp.Spec.Template) {
+               //      return ctrl.Result{}, nil
+               // }
+
+               if err := r.Update(ctx, exp); err != nil {
                        return ctrl.Result{Requeue: true}, err
                }
        }
-       runtimeHPA := &autoscalingv2beta2.HorizontalPodAutoscaler{}
-       err = r.Get(ctx, req.NamespacedName, runtimeHPA)
-       if err != nil && !apierrors.IsNotFound(err) {
-               log.Error(err, "Error getting cascaded HPA")
-               return ctrl.Result{}, err
-       }
-       if apierrors.IsNotFound(err) {
-               if run.Spec.AutomaticScaling != nil {
-                       cascadingHPA := reconcile.ConstructHPA(run)
-                       err = r.Create(ctx, cascadingHPA)
-                       if err != nil {
-                               run.SetInitializationFailed()
-                               _ = r.Status().Update(ctx, run)
-                               log.Error(err, "Error creating cascaded HPA")
-                               return ctrl.Result{}, err
+       return ctrl.Result{}, nil
+}
+
+func (r *ProxyReconciler) reconcileHPA(ctx context.Context, namespacedName 
types.NamespacedName, ssproxy *v1alpha1.ShardingSphereProxy) (ctrl.Result, 
error) {
+       hpa := &autoscalingv2beta2.HorizontalPodAutoscaler{}
+
+       var err error
+       if err = r.Get(ctx, namespacedName, hpa); err != nil {
+               if !apierrors.IsNotFound(err) {
+                       return ctrl.Result{}, err
+               } else {
+                       if ssproxy.Spec.AutomaticScaling != nil && 
ssproxy.Spec.AutomaticScaling.Enable {
+                               exp := reconcile.NewHPA(ssproxy)
+                               if err := r.Create(ctx, exp); err != nil {
+                                       ssproxy.SetInitializationFailed()
+                                       _ = r.Status().Update(ctx, ssproxy)
+                                       return ctrl.Result{}, err
+                               }
                        }
                }
        } else {
-               if run.Spec.AutomaticScaling == nil {
-                       err = r.Delete(ctx, runtimeHPA)
-                       if err != nil {
-                               log.Error(err, "Error delete cascaded HPA")
+               if ssproxy.Spec.AutomaticScaling == nil || 
!ssproxy.Spec.AutomaticScaling.Enable {
+                       if err := r.Delete(ctx, hpa); err != nil {
                                return ctrl.Result{}, err
                        }
                } else {
-                       originHPA := runtimeHPA.DeepCopy()
-                       reconcile.UpdateHPA(run, originHPA)
-                       err = r.Update(ctx, originHPA)
-                       if err != nil {
-                               log.Error(err, "Error updating cascaded HPA")
+                       act := hpa.DeepCopy()
+                       exp := reconcile.UpdateHPA(ssproxy, act)
+                       if err := r.Update(ctx, exp); err != nil {
                                return ctrl.Result{}, err
                        }
                }
        }
 
-       runtimeService := &v1.Service{}
-       err = r.Get(ctx, req.NamespacedName, runtimeService)
-       if err != nil && !apierrors.IsNotFound(err) {
-               log.Error(err, "Error getting cascaded Service")
-               return ctrl.Result{}, err
-       }
-       if apierrors.IsNotFound(err) {
-               cascadingService := reconcile.ConstructCascadingService(run)
-               err = r.Create(ctx, cascadingService)
-               if err != nil {
-                       run.SetInitializationFailed()
-                       _ = r.Status().Update(ctx, run)
-                       log.Error(err, "Error creating cascaded service")
+       return ctrl.Result{}, nil
+}
+
+func (r *ProxyReconciler) reconcileService(ctx context.Context, namespacedName 
types.NamespacedName, ssproxy *v1alpha1.ShardingSphereProxy) (ctrl.Result, 
error) {
+       service := &v1.Service{}
+
+       var err error
+       if err = r.Get(ctx, namespacedName, service); err != nil {
+               if !apierrors.IsNotFound(err) {
                        return ctrl.Result{}, err
+               } else {
+                       exp := reconcile.NewService(ssproxy)
+                       if err := r.Create(ctx, exp); err != nil {
+                               ssproxy.SetInitializationFailed()
+                               _ = r.Status().Update(ctx, ssproxy)
+                               return ctrl.Result{}, err
+                       }
+                       ssproxy.SetInitialized()
+                       return ctrl.Result{RequeueAfter: WaitingForReady}, nil
                }
-               run.SetInitialized()
-               return ctrl.Result{RequeueAfter: WaitingForReady}, nil
        } else {
-               originService := runtimeService.DeepCopy()
-               reconcile.UpdateService(run, originService)
-               err = r.Update(ctx, originService)
-               if err != nil {
-                       log.Error(err, "Error updating cascaded service")
+               act := service.DeepCopy()
+               reconcile.UpdateService(ssproxy, act)
+               if err := r.Update(ctx, act); err != nil {
                        return ctrl.Result{}, err
                }
        }
 
+       return ctrl.Result{}, nil
+}
+
+func (r *ProxyReconciler) reconcilePodList(ctx context.Context, namespace, 
name string, ssproxy *v1alpha1.ShardingSphereProxy) (ctrl.Result, error) {
        podList := &v1.PodList{}
-       err = r.List(ctx, podList, client.InNamespace(req.Namespace), 
client.MatchingLabels(map[string]string{"apps": req.Name}))
-       if err != nil {
-               log.Error(err, "Error listing cascaded pod")
+       if err := r.List(ctx, podList, client.InNamespace(namespace), 
client.MatchingLabels(map[string]string{"apps": name})); err != nil {
                return ctrl.Result{}, err
        }
 
@@ -169,30 +210,27 @@ func (r *ProxyReconciler) Reconcile(ctx context.Context, 
req ctrl.Request) (ctrl
        if reconcile.IsRunning(podList) {
                if readyNodes < miniReadyCount {
                        result.RequeueAfter = WaitingForReady
-                       if readyNodes != run.Status.ReadyNodes {
-                               run.SetPodStarted(readyNodes)
+                       if readyNodes != ssproxy.Status.ReadyNodes {
+                               ssproxy.SetPodStarted(readyNodes)
                        }
                } else {
-                       if run.Status.Phase != v1alpha1.StatusReady {
-                               log.Info("Status is now ready!")
-                               run.SetReady(readyNodes)
-                       } else if readyNodes != 
*runtimeDeployment.Spec.Replicas {
-                               run.UpdateReadyNodes(readyNodes)
+                       if ssproxy.Status.Phase != v1alpha1.StatusReady {
+                               ssproxy.SetReady(readyNodes)
+                       } else if readyNodes != ssproxy.Spec.Replicas {
+                               ssproxy.UpdateReadyNodes(readyNodes)
                        }
                }
        } else {
                // TODO: Waiting for pods to start exceeds the maximum number 
of retries
-               run.SetPodNotStarted(readyNodes)
+               ssproxy.SetPodNotStarted(readyNodes)
                result.RequeueAfter = WaitingForReady
        }
 
        // TODO: Compare Status with or without modification
-       err = r.Status().Update(ctx, run)
-       if err != nil {
-               log.Error(err, "Error updating status")
+       if err := r.Status().Update(ctx, ssproxy); err != nil {
                return result, err
        }
-       log.Info("RuntimeCRD status ", "status", run.Status)
+
        return result, nil
 }
 
diff --git a/shardingsphere-operator/pkg/reconcile/coverage.txt 
b/shardingsphere-operator/pkg/reconcile/coverage.txt
new file mode 100644
index 0000000..6a9fca8
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/coverage.txt
@@ -0,0 +1,54 @@
+mode: atomic
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:71.91,72.79
 1 3
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:76.2,140.40
 2 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:143.2,143.33
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:146.2,146.37
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:149.2,149.38
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:152.2,152.36
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:155.2,155.42
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:158.2,158.44
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:72.79,74.3
 1 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:140.40,142.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:143.33,145.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:146.37,148.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:149.38,151.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:152.36,154.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:155.42,157.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:161.81,162.79
 1 3
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:166.2,188.59
 2 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:191.2,191.13
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:162.79,164.3
 1 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:188.59,190.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:194.75,196.52
 1 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:210.2,229.3
 4 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:196.52,208.3
 2 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:233.110,234.35
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:237.2,237.11
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:234.35,236.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:241.103,257.2
 2 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:260.100,263.56
 2 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:267.2,300.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:263.56,265.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:304.79,317.2
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:320.75,323.2
 2 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:326.98,328.40
 2 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:331.2,334.42
 4 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:337.2,340.91
 4 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:328.40,330.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:334.42,336.3
 1 0
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:344.85,348.42
 4 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:348.42,350.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:353.109,358.56
 5 2
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:358.56,360.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:360.8,363.3
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/resource.go:366.46,368.2
 1 4
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:24.42,26.36
 2 6
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:32.2,32.15
 1 6
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:26.36,27.83
 1 9
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:27.83,29.4
 1 4
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:35.51,37.36
 2 6
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:45.2,45.18
 1 6
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:37.36,38.45
 1 7
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:41.3,41.87
 1 6
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:38.45,39.12
 1 1
+github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/status.go:41.87,43.4
 1 3
diff --git a/shardingsphere-operator/pkg/reconcile/deployment.go 
b/shardingsphere-operator/pkg/reconcile/deployment.go
new file mode 100644
index 0000000..d40c7a2
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/deployment.go
@@ -0,0 +1,194 @@
+/*
+ * 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 reconcile
+
+import (
+       "fmt"
+       "html/template"
+       "reflect"
+       "strconv"
+       "strings"
+
+       
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+       v1 "k8s.io/api/apps/v1"
+       corev1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func NewDeployment(ssproxy *v1alpha1.ShardingSphereProxy) *v1.Deployment {
+       return ConstructCascadingDeployment(ssproxy)
+}
+func ConstructCascadingDeployment(proxy *v1alpha1.ShardingSphereProxy) 
*v1.Deployment {
+       if proxy == nil || reflect.DeepEqual(proxy, 
&v1alpha1.ShardingSphereProxy{}) {
+               return &v1.Deployment{}
+       }
+
+       dp := &v1.Deployment{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      proxy.Name,
+                       Namespace: proxy.Namespace,
+                       OwnerReferences: []metav1.OwnerReference{
+                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
+                       },
+               },
+               Spec: v1.DeploymentSpec{
+                       Strategy: v1.DeploymentStrategy{
+                               Type: v1.RecreateDeploymentStrategyType,
+                       },
+                       Selector: &metav1.LabelSelector{
+                               MatchLabels: map[string]string{
+                                       "apps": proxy.Name,
+                               },
+                       },
+                       Template: corev1.PodTemplateSpec{
+                               ObjectMeta: metav1.ObjectMeta{
+                                       Labels: map[string]string{
+                                               "apps": proxy.Name,
+                                       },
+                               },
+                               Spec: corev1.PodSpec{
+                                       Containers: []corev1.Container{
+                                               {
+                                                       Name:            
"proxy",
+                                                       Image:           
fmt.Sprintf("%s:%s", imageName, proxy.Spec.Version),
+                                                       ImagePullPolicy: 
corev1.PullIfNotPresent,
+                                                       Ports: 
[]corev1.ContainerPort{
+                                                               {
+                                                                       
ContainerPort: proxy.Spec.Port,
+                                                               },
+                                                       },
+                                                       Env: []corev1.EnvVar{
+                                                               {
+                                                                       Name:  
"PORT",
+                                                                       Value: 
strconv.FormatInt(int64(proxy.Spec.Port), 10),
+                                                               },
+                                                       },
+                                                       VolumeMounts: 
[]corev1.VolumeMount{
+                                                               {
+                                                                       Name:   
   "config",
+                                                                       
MountPath: "/opt/shardingsphere-proxy/conf",
+                                                               },
+                                                       },
+                                               },
+                                       },
+                                       Volumes: []corev1.Volume{
+                                               {
+                                                       Name: "config",
+                                                       VolumeSource: 
corev1.VolumeSource{
+                                                               ConfigMap: 
&corev1.ConfigMapVolumeSource{
+                                                                       
LocalObjectReference: corev1.LocalObjectReference{
+                                                                               
Name: proxy.Spec.ProxyConfigName,
+                                                                       },
+                                                               },
+                                                       },
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+       if proxy.Spec.AutomaticScaling == nil {
+               dp.Spec.Replicas = &proxy.Spec.Replicas
+       }
+       if proxy.Spec.Resources != nil {
+               dp.Spec.Template.Spec.Containers[0].Resources = 
*proxy.Spec.Resources
+       }
+       if proxy.Spec.LivenessProbe != nil {
+               dp.Spec.Template.Spec.Containers[0].LivenessProbe = 
proxy.Spec.LivenessProbe
+       }
+       if proxy.Spec.ReadinessProbe != nil {
+               dp.Spec.Template.Spec.Containers[0].ReadinessProbe = 
proxy.Spec.ReadinessProbe
+       }
+       if proxy.Spec.StartupProbe != nil {
+               dp.Spec.Template.Spec.Containers[0].StartupProbe = 
proxy.Spec.StartupProbe
+       }
+       if len(proxy.Spec.ImagePullSecrets) > 0 {
+               dp.Spec.Template.Spec.ImagePullSecrets = 
proxy.Spec.ImagePullSecrets
+       }
+       return processOptionalParameter(proxy, dp)
+}
+
+func processOptionalParameter(proxy *v1alpha1.ShardingSphereProxy, dp 
*v1.Deployment) *v1.Deployment {
+       if proxy.Spec.MySQLDriver != nil {
+               addInitContainer(dp, proxy.Spec.MySQLDriver)
+       }
+       return dp
+}
+
+func addInitContainer(dp *v1.Deployment, mysql *v1alpha1.MySQLDriver) {
+
+       if len(dp.Spec.Template.Spec.InitContainers) == 0 {
+               dp.Spec.Template.Spec.Containers[0].VolumeMounts = 
append(dp.Spec.Template.Spec.Containers[0].VolumeMounts, corev1.VolumeMount{
+                       Name:      "mysql-connect-jar",
+                       MountPath: "/opt/shardingsphere-proxy/ext-lib",
+               })
+
+               dp.Spec.Template.Spec.Volumes = 
append(dp.Spec.Template.Spec.Volumes, corev1.Volume{
+                       Name: "mysql-connect-jar",
+                       VolumeSource: corev1.VolumeSource{
+                               EmptyDir: &corev1.EmptyDirVolumeSource{},
+                       },
+               })
+       }
+
+       scriptStr := strings.Builder{}
+       t1, _ := template.New("shell").Parse(`wget 
https://repo1.maven.org/maven2/mysql/mysql-connector-java/{{ .Version 
}}/mysql-connector-java-{{ .Version }}.jar;
+wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/{{ .Version 
}}/mysql-connector-java-{{ .Version }}.jar.md5;
+if [ $(md5sum /mysql-connector-java-{{ .Version }}.jar | cut -d ' ' -f1) = 
$(cat /mysql-connector-java-{{ .Version }}.jar.md5) ];
+then echo success;
+else echo failed;exit 1;fi;mv /mysql-connector-java-{{ .Version }}.jar 
/opt/shardingsphere-proxy/ext-lib`)
+       _ = t1.Execute(&scriptStr, mysql)
+       dp.Spec.Template.Spec.InitContainers = []corev1.Container{
+               {
+                       Name:    "download-mysql-connect",
+                       Image:   "busybox:1.35.0",
+                       Command: []string{"/bin/sh", "-c", scriptStr.String()},
+                       VolumeMounts: []corev1.VolumeMount{
+                               {
+                                       Name:      "mysql-connect-jar",
+                                       MountPath: 
"/opt/shardingsphere-proxy/ext-lib",
+                               },
+                       },
+               },
+       }
+
+}
+
+// UpdateDeployment FIXME:merge UpdateDeployment and 
ConstructCascadingDeployment
+func UpdateDeployment(proxy *v1alpha1.ShardingSphereProxy, act *v1.Deployment) 
*v1.Deployment {
+       if proxy.Spec.AutomaticScaling == nil || 
!proxy.Spec.AutomaticScaling.Enable {
+               act.Spec.Replicas = &proxy.Spec.Replicas
+       }
+
+       act.Spec.Template.Spec.Containers[0].Image = fmt.Sprintf("%s:%s", 
imageName, proxy.Spec.Version)
+       act.Spec.Template.Spec.Containers[0].Env[0].Value = 
strconv.FormatInt(int64(proxy.Spec.Port), 10)
+       act.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort = 
proxy.Spec.Port
+       act.Spec.Template.Spec.Containers[0].Resources = *proxy.Spec.Resources
+       act.Spec.Template.Spec.Containers[0].LivenessProbe = 
proxy.Spec.LivenessProbe
+       act.Spec.Template.Spec.Containers[0].ReadinessProbe = 
proxy.Spec.ReadinessProbe
+       act.Spec.Template.Spec.Containers[0].StartupProbe = 
proxy.Spec.StartupProbe
+
+       act.Spec.Template.Spec.Volumes[0].ConfigMap.Name = 
proxy.Spec.ProxyConfigName
+
+       if proxy.Spec.MySQLDriver.Version != "" {
+               addInitContainer(act, proxy.Spec.MySQLDriver)
+       }
+
+       exp := act.DeepCopy()
+       return exp
+}
diff --git a/shardingsphere-operator/pkg/reconcile/hpa.go 
b/shardingsphere-operator/pkg/reconcile/hpa.go
new file mode 100644
index 0000000..8428f7a
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/hpa.go
@@ -0,0 +1,104 @@
+/*
+ * 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 reconcile
+
+import (
+       
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+       appsv1 "k8s.io/api/apps/v1"
+       autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func NewHPA(ssproxy *v1alpha1.ShardingSphereProxy) 
*autoscalingv2beta2.HorizontalPodAutoscaler {
+       return ConstructHPA(ssproxy)
+}
+
+// ConstructHPA Create HPA if you need
+func ConstructHPA(proxy *v1alpha1.ShardingSphereProxy) 
*autoscalingv2beta2.HorizontalPodAutoscaler {
+       var metrics = 
ConstructDefaultHPAMetric(&proxy.Spec.AutomaticScaling.Target)
+
+       if len(proxy.Spec.AutomaticScaling.CustomMetrics) > 0 {
+               metrics = proxy.Spec.AutomaticScaling.CustomMetrics
+       }
+
+       return &autoscalingv2beta2.HorizontalPodAutoscaler{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      proxy.Name,
+                       Namespace: proxy.Namespace,
+                       OwnerReferences: []metav1.OwnerReference{
+                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
+                       },
+               },
+               Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
+                       ScaleTargetRef: 
autoscalingv2beta2.CrossVersionObjectReference{
+                               Kind:       "Deployment",
+                               Name:       proxy.Name,
+                               APIVersion: appsv1.SchemeGroupVersion.String(),
+                       },
+                       MinReplicas: &proxy.Spec.AutomaticScaling.MinInstance,
+                       MaxReplicas: proxy.Spec.AutomaticScaling.MaxInstance,
+                       Metrics:     metrics,
+                       Behavior: 
&autoscalingv2beta2.HorizontalPodAutoscalerBehavior{
+                               ScaleUp: &autoscalingv2beta2.HPAScalingRules{
+                                       StabilizationWindowSeconds: 
&proxy.Spec.AutomaticScaling.ScaleUpWindows,
+                               },
+                               ScaleDown: &autoscalingv2beta2.HPAScalingRules{
+                                       StabilizationWindowSeconds: 
&proxy.Spec.AutomaticScaling.ScaleDownWindows,
+                                       Policies: 
[]autoscalingv2beta2.HPAScalingPolicy{
+                                               {
+                                                       Type:          
autoscalingv2beta2.PodsScalingPolicy,
+                                                       Value:         1,
+                                                       PeriodSeconds: 30,
+                                               },
+                                       },
+                               },
+                       },
+               },
+       }
+
+}
+func ConstructDefaultHPAMetric(target *int32) []autoscalingv2beta2.MetricSpec {
+       return []autoscalingv2beta2.MetricSpec{
+               {
+                       Type: autoscalingv2beta2.ResourceMetricSourceType,
+                       Resource: &autoscalingv2beta2.ResourceMetricSource{
+                               Name: "cpu",
+                               Target: autoscalingv2beta2.MetricTarget{
+                                       Type:               
autoscalingv2beta2.UtilizationMetricType,
+                                       AverageUtilization: target,
+                               },
+                       },
+               },
+       }
+}
+
+func UpdateHPA(proxy *v1alpha1.ShardingSphereProxy, act 
*autoscalingv2beta2.HorizontalPodAutoscaler) 
*autoscalingv2beta2.HorizontalPodAutoscaler {
+       act.Spec.Behavior.ScaleDown.StabilizationWindowSeconds = 
&proxy.Spec.AutomaticScaling.ScaleDownWindows
+       act.Spec.Behavior.ScaleUp.StabilizationWindowSeconds = 
&proxy.Spec.AutomaticScaling.ScaleUpWindows
+       act.Spec.MaxReplicas = proxy.Spec.AutomaticScaling.MaxInstance
+       act.Spec.MinReplicas = &proxy.Spec.AutomaticScaling.MinInstance
+       if len(proxy.Spec.AutomaticScaling.CustomMetrics) > 0 {
+               act.Spec.Metrics = proxy.Spec.AutomaticScaling.CustomMetrics
+       } else {
+               // We need to reconstruct the default hpa metric when the user 
deletes the custom metric.
+               act.Spec.Metrics = 
ConstructDefaultHPAMetric(&proxy.Spec.AutomaticScaling.Target)
+       }
+
+       exp := act.DeepCopy()
+       return exp
+}
diff --git a/shardingsphere-operator/pkg/reconcile/reconcile_test.go 
b/shardingsphere-operator/pkg/reconcile/reconcile_test.go
index b415292..aed6768 100644
--- a/shardingsphere-operator/pkg/reconcile/reconcile_test.go
+++ b/shardingsphere-operator/pkg/reconcile/reconcile_test.go
@@ -528,86 +528,86 @@ func Test_ConstructCascadingService(t *testing.T) {
 }
 
 func Test_addInitContaienr(t *testing.T) {
-    cases := []struct{
-        deploy *appsv1.Deployment
-        mysql *v1alpha1.MySQLDriver
-        message string
-    }{
-        {
-            deploy: &appsv1.Deployment{
-                Spec: appsv1.DeploymentSpec{
-                    Template: v1.PodTemplateSpec{
-                        Spec: v1.PodSpec{
-                            InitContainers: []v1.Container{},
-                            Containers: []v1.Container{
-                                {
-                                    VolumeMounts: []v1.VolumeMount{},
-                                },
-                            },
-                            Volumes: []v1.Volume{},
-                        },
-                    },
-                },
-            },
-            mysql: &v1alpha1.MySQLDriver{
-                Version: "5.1.47",
-            },
-            message: "Add InitContainer for MySQL Driver",
-        },
-    }
+       cases := []struct {
+               deploy  *appsv1.Deployment
+               mysql   *v1alpha1.MySQLDriver
+               message string
+       }{
+               {
+                       deploy: &appsv1.Deployment{
+                               Spec: appsv1.DeploymentSpec{
+                                       Template: v1.PodTemplateSpec{
+                                               Spec: v1.PodSpec{
+                                                       InitContainers: 
[]v1.Container{},
+                                                       Containers: 
[]v1.Container{
+                                                               {
+                                                                       
VolumeMounts: []v1.VolumeMount{},
+                                                               },
+                                                       },
+                                                       Volumes: []v1.Volume{},
+                                               },
+                                       },
+                               },
+                       },
+                       mysql: &v1alpha1.MySQLDriver{
+                               Version: "5.1.47",
+                       },
+                       message: "Add InitContainer for MySQL Driver",
+               },
+       }
 
-    for _, c := range cases {
-        addInitContainer(c.deploy, c.mysql)
-        assert.Equal(t, c.deploy.Spec.Template.Spec.InitContainers[0].Name, 
"download-mysql-connect", c.message)
-    }
+       for _, c := range cases {
+               addInitContainer(c.deploy, c.mysql)
+               assert.Equal(t, 
c.deploy.Spec.Template.Spec.InitContainers[0].Name, "download-mysql-connect", 
c.message)
+       }
 }
 
 func Test_processOptionalParameter(t *testing.T) {
-    /*
-    cases := []struct{
+       /*
+          cases := []struct{
 
-    }{
-        {
+          }{
+              {
 
-        },
-    }
+              },
+          }
 
-    for _, c := range cases {
+          for _, c := range cases {
 
-    }
-    */
+          }
+       */
 }
 
 func Test_ConstructCascadingConfigmap(t *testing.T) {
-    /*
-    cases := []struct{
+       /*
+          cases := []struct{
 
-    }{
-        {
+          }{
+              {
 
-        },
-    }
+              },
+          }
 
-    for _, c := range cases {
+          for _, c := range cases {
 
-    }
-    */
+          }
+       */
 }
 
 func Test_ConstructHPA(t *testing.T) {
-    /*
-    cases := []struct{
+       /*
+          cases := []struct{
 
-    }{
-        {
+          }{
+              {
 
-        },
-    }
+              },
+          }
 
-    for _, c := range cases {
+          for _, c := range cases {
 
-    }
-    */
+          }
+       */
 }
 
 func Test_ToYAML(t *testing.T) {
diff --git a/shardingsphere-operator/pkg/reconcile/resource.go 
b/shardingsphere-operator/pkg/reconcile/resource.go
index a1e8e49..e90f0d8 100644
--- a/shardingsphere-operator/pkg/reconcile/resource.go
+++ b/shardingsphere-operator/pkg/reconcile/resource.go
@@ -18,16 +18,8 @@
 package reconcile
 
 import (
-       "fmt"
-       "html/template"
-       "reflect"
-       "strconv"
-       "strings"
-
        
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
        "gopkg.in/yaml.v2"
-       appsv1 "k8s.io/api/apps/v1"
-       autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
        v1 "k8s.io/api/core/v1"
        metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
        "k8s.io/apimachinery/pkg/util/intstr"
@@ -35,7 +27,7 @@ import (
 
 const imageName = "apache/shardingsphere-proxy"
 
-var logback = `<?xml version="1.0"?>
+const logback = `<?xml version="1.0"?>
 <configuration>
     <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
         <encoder>
@@ -68,175 +60,6 @@ var logback = `<?xml version="1.0"?>
 </configuration> 
 `
 
-func ConstructCascadingDeployment(proxy *v1alpha1.ShardingSphereProxy) 
*appsv1.Deployment {
-       if proxy == nil || reflect.DeepEqual(proxy, 
&v1alpha1.ShardingSphereProxy{}) {
-               return &appsv1.Deployment{}
-       }
-
-       dp := &appsv1.Deployment{
-               ObjectMeta: metav1.ObjectMeta{
-                       Name:      proxy.Name,
-                       Namespace: proxy.Namespace,
-                       OwnerReferences: []metav1.OwnerReference{
-                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
-                       },
-               },
-               Spec: appsv1.DeploymentSpec{
-                       Strategy: appsv1.DeploymentStrategy{
-                               Type: appsv1.RecreateDeploymentStrategyType,
-                       },
-                       Selector: &metav1.LabelSelector{
-                               MatchLabels: map[string]string{
-                                       "apps": proxy.Name,
-                               },
-                       },
-                       Template: v1.PodTemplateSpec{
-                               ObjectMeta: metav1.ObjectMeta{
-                                       Labels: map[string]string{
-                                               "apps": proxy.Name,
-                                       },
-                               },
-                               Spec: v1.PodSpec{
-                                       Containers: []v1.Container{
-                                               {
-                                                       Name:            
"proxy",
-                                                       Image:           
fmt.Sprintf("%s:%s", imageName, proxy.Spec.Version),
-                                                       ImagePullPolicy: 
v1.PullIfNotPresent,
-                                                       Ports: 
[]v1.ContainerPort{
-                                                               {
-                                                                       
ContainerPort: proxy.Spec.Port,
-                                                               },
-                                                       },
-                                                       Env: []v1.EnvVar{
-                                                               {
-                                                                       Name:  
"PORT",
-                                                                       Value: 
strconv.FormatInt(int64(proxy.Spec.Port), 10),
-                                                               },
-                                                       },
-                                                       VolumeMounts: 
[]v1.VolumeMount{
-                                                               {
-                                                                       Name:   
   "config",
-                                                                       
MountPath: "/opt/shardingsphere-proxy/conf",
-                                                               },
-                                                       },
-                                               },
-                                       },
-                                       Volumes: []v1.Volume{
-                                               {
-                                                       Name: "config",
-                                                       VolumeSource: 
v1.VolumeSource{
-                                                               ConfigMap: 
&v1.ConfigMapVolumeSource{
-                                                                       
LocalObjectReference: v1.LocalObjectReference{
-                                                                               
Name: proxy.Spec.ProxyConfigName,
-                                                                       },
-                                                               },
-                                                       },
-                                               },
-                                       },
-                               },
-                       },
-               },
-       }
-       if proxy.Spec.AutomaticScaling == nil {
-               dp.Spec.Replicas = &proxy.Spec.Replicas
-       }
-       if proxy.Spec.Resources != nil {
-               dp.Spec.Template.Spec.Containers[0].Resources = 
*proxy.Spec.Resources
-       }
-       if proxy.Spec.LivenessProbe != nil {
-               dp.Spec.Template.Spec.Containers[0].LivenessProbe = 
proxy.Spec.LivenessProbe
-       }
-       if proxy.Spec.ReadinessProbe != nil {
-               dp.Spec.Template.Spec.Containers[0].ReadinessProbe = 
proxy.Spec.ReadinessProbe
-       }
-       if proxy.Spec.StartupProbe != nil {
-               dp.Spec.Template.Spec.Containers[0].StartupProbe = 
proxy.Spec.StartupProbe
-       }
-       if len(proxy.Spec.ImagePullSecrets) > 0 {
-               dp.Spec.Template.Spec.ImagePullSecrets = 
proxy.Spec.ImagePullSecrets
-       }
-       return processOptionalParameter(proxy, dp)
-}
-
-func ConstructCascadingService(proxy *v1alpha1.ShardingSphereProxy) 
*v1.Service {
-       if proxy == nil || reflect.DeepEqual(proxy, 
&v1alpha1.ShardingSphereProxy{}) {
-               return &v1.Service{}
-       }
-
-       svc := v1.Service{
-               ObjectMeta: metav1.ObjectMeta{
-                       Name:      proxy.Name,
-                       Namespace: proxy.Namespace,
-                       OwnerReferences: []metav1.OwnerReference{
-                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
-                       },
-               },
-               Spec: v1.ServiceSpec{
-                       Selector: map[string]string{
-                               "apps": proxy.Name,
-                       },
-                       Type: proxy.Spec.ServiceType.Type,
-                       Ports: []v1.ServicePort{
-                               {
-                                       Name:       "proxy-port",
-                                       TargetPort: fromInt32(proxy.Spec.Port),
-                                       Port:       proxy.Spec.Port,
-                               },
-                       },
-               },
-       }
-       if proxy.Spec.ServiceType.Type == v1.ServiceTypeNodePort {
-               svc.Spec.Ports[0].NodePort = proxy.Spec.ServiceType.NodePort
-       }
-       return &svc
-}
-
-func addInitContainer(dp *appsv1.Deployment, mysql *v1alpha1.MySQLDriver) {
-
-       if len(dp.Spec.Template.Spec.InitContainers) == 0 {
-               dp.Spec.Template.Spec.Containers[0].VolumeMounts = 
append(dp.Spec.Template.Spec.Containers[0].VolumeMounts, v1.VolumeMount{
-                       Name:      "mysql-connect-jar",
-                       MountPath: "/opt/shardingsphere-proxy/ext-lib",
-               })
-
-               dp.Spec.Template.Spec.Volumes = 
append(dp.Spec.Template.Spec.Volumes, v1.Volume{
-                       Name: "mysql-connect-jar",
-                       VolumeSource: v1.VolumeSource{
-                               EmptyDir: &v1.EmptyDirVolumeSource{},
-                       },
-               })
-       }
-
-       scriptStr := strings.Builder{}
-       t1, _ := template.New("shell").Parse(`wget 
https://repo1.maven.org/maven2/mysql/mysql-connector-java/{{ .Version 
}}/mysql-connector-java-{{ .Version }}.jar;
-wget https://repo1.maven.org/maven2/mysql/mysql-connector-java/{{ .Version 
}}/mysql-connector-java-{{ .Version }}.jar.md5;
-if [ $(md5sum /mysql-connector-java-{{ .Version }}.jar | cut -d ' ' -f1) = 
$(cat /mysql-connector-java-{{ .Version }}.jar.md5) ];
-then echo success;
-else echo failed;exit 1;fi;mv /mysql-connector-java-{{ .Version }}.jar 
/opt/shardingsphere-proxy/ext-lib`)
-       _ = t1.Execute(&scriptStr, mysql)
-       dp.Spec.Template.Spec.InitContainers = []v1.Container{
-               {
-                       Name:    "download-mysql-connect",
-                       Image:   "busybox:1.35.0",
-                       Command: []string{"/bin/sh", "-c", scriptStr.String()},
-                       VolumeMounts: []v1.VolumeMount{
-                               {
-                                       Name:      "mysql-connect-jar",
-                                       MountPath: 
"/opt/shardingsphere-proxy/ext-lib",
-                               },
-                       },
-               },
-       }
-
-}
-
-func processOptionalParameter(proxy *v1alpha1.ShardingSphereProxy, dp 
*appsv1.Deployment) *appsv1.Deployment {
-       if proxy.Spec.MySQLDriver != nil {
-               addInitContainer(dp, proxy.Spec.MySQLDriver)
-       }
-       return dp
-}
-
 // ConstructCascadingConfigmap Construct spec resources to Configmap
 func ConstructCascadingConfigmap(proxyConfig 
*v1alpha1.ShardingSphereProxyServerConfig) *v1.ConfigMap {
        y := toYaml(proxyConfig)
@@ -253,67 +76,6 @@ func ConstructCascadingConfigmap(proxyConfig 
*v1alpha1.ShardingSphereProxyServer
                        "logback.xml": logback,
                },
        }
-
-}
-
-// ConstructHPA Create HPA if you need
-func ConstructHPA(proxy *v1alpha1.ShardingSphereProxy) 
*autoscalingv2beta2.HorizontalPodAutoscaler {
-       var metrics = 
ConstructDefaultHPAMetric(&proxy.Spec.AutomaticScaling.Target)
-
-       if len(proxy.Spec.AutomaticScaling.CustomMetrics) > 0 {
-               metrics = proxy.Spec.AutomaticScaling.CustomMetrics
-       }
-
-       return &autoscalingv2beta2.HorizontalPodAutoscaler{
-               ObjectMeta: metav1.ObjectMeta{
-                       Name:      proxy.Name,
-                       Namespace: proxy.Namespace,
-                       OwnerReferences: []metav1.OwnerReference{
-                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
-                       },
-               },
-               Spec: autoscalingv2beta2.HorizontalPodAutoscalerSpec{
-                       ScaleTargetRef: 
autoscalingv2beta2.CrossVersionObjectReference{
-                               Kind:       "Deployment",
-                               Name:       proxy.Name,
-                               APIVersion: appsv1.SchemeGroupVersion.String(),
-                       },
-                       MinReplicas: &proxy.Spec.AutomaticScaling.MinInstance,
-                       MaxReplicas: proxy.Spec.AutomaticScaling.MaxInstance,
-                       Metrics:     metrics,
-                       Behavior: 
&autoscalingv2beta2.HorizontalPodAutoscalerBehavior{
-                               ScaleUp: &autoscalingv2beta2.HPAScalingRules{
-                                       StabilizationWindowSeconds: 
&proxy.Spec.AutomaticScaling.ScaleUpWindows,
-                               },
-                               ScaleDown: &autoscalingv2beta2.HPAScalingRules{
-                                       StabilizationWindowSeconds: 
&proxy.Spec.AutomaticScaling.ScaleDownWindows,
-                                       Policies: 
[]autoscalingv2beta2.HPAScalingPolicy{
-                                               {
-                                                       Type:          
autoscalingv2beta2.PodsScalingPolicy,
-                                                       Value:         1,
-                                                       PeriodSeconds: 30,
-                                               },
-                                       },
-                               },
-                       },
-               },
-       }
-
-}
-
-func ConstructDefaultHPAMetric(target *int32) []autoscalingv2beta2.MetricSpec {
-       return []autoscalingv2beta2.MetricSpec{
-               {
-                       Type: autoscalingv2beta2.ResourceMetricSourceType,
-                       Resource: &autoscalingv2beta2.ResourceMetricSource{
-                               Name: "cpu",
-                               Target: autoscalingv2beta2.MetricTarget{
-                                       Type:               
autoscalingv2beta2.UtilizationMetricType,
-                                       AverageUtilization: target,
-                               },
-                       },
-               },
-       }
 }
 
 // ToYaml Convert ShardingSphereProxyServerConfig spec content to yaml format
@@ -322,47 +84,6 @@ func toYaml(proxyConfig 
*v1alpha1.ShardingSphereProxyServerConfig) string {
        return string(y)
 }
 
-// UpdateDeployment FIXME:merge UpdateDeployment and 
ConstructCascadingDeployment
-func UpdateDeployment(proxy *v1alpha1.ShardingSphereProxy, runtimeDeployment 
*appsv1.Deployment) {
-       runtimeDeployment.Spec.Template.Spec.Containers[0].Image = 
fmt.Sprintf("%s:%s", imageName, proxy.Spec.Version)
-       if proxy.Spec.AutomaticScaling == nil {
-               runtimeDeployment.Spec.Replicas = &proxy.Spec.Replicas
-       }
-       runtimeDeployment.Spec.Template.Spec.Volumes[0].ConfigMap.Name = 
proxy.Spec.ProxyConfigName
-       runtimeDeployment.Spec.Template.Spec.Containers[0].Env[0].Value = 
strconv.FormatInt(int64(proxy.Spec.Port), 10)
-       
runtimeDeployment.Spec.Template.Spec.Containers[0].Ports[0].ContainerPort = 
proxy.Spec.Port
-       if proxy.Spec.MySQLDriver.Version != "" {
-               addInitContainer(runtimeDeployment, proxy.Spec.MySQLDriver)
-       }
-       runtimeDeployment.Spec.Template.Spec.Containers[0].Resources = 
*proxy.Spec.Resources
-       runtimeDeployment.Spec.Template.Spec.Containers[0].LivenessProbe = 
proxy.Spec.LivenessProbe
-       runtimeDeployment.Spec.Template.Spec.Containers[0].ReadinessProbe = 
proxy.Spec.ReadinessProbe
-       runtimeDeployment.Spec.Template.Spec.Containers[0].StartupProbe = 
proxy.Spec.StartupProbe
-
-}
-
-func UpdateService(proxy *v1alpha1.ShardingSphereProxy, runtimeService 
*v1.Service) {
-       runtimeService.Spec.Type = proxy.Spec.ServiceType.Type
-       runtimeService.Spec.Ports[0].Port = proxy.Spec.Port
-       runtimeService.Spec.Ports[0].TargetPort = fromInt32(proxy.Spec.Port)
-       if proxy.Spec.ServiceType.NodePort != 0 {
-               runtimeService.Spec.Ports[0].NodePort = 
proxy.Spec.ServiceType.NodePort
-       }
-}
-
-func UpdateHPA(proxy *v1alpha1.ShardingSphereProxy, runtimeHPA 
*autoscalingv2beta2.HorizontalPodAutoscaler) {
-       runtimeHPA.Spec.Behavior.ScaleDown.StabilizationWindowSeconds = 
&proxy.Spec.AutomaticScaling.ScaleDownWindows
-       runtimeHPA.Spec.Behavior.ScaleUp.StabilizationWindowSeconds = 
&proxy.Spec.AutomaticScaling.ScaleUpWindows
-       runtimeHPA.Spec.MaxReplicas = proxy.Spec.AutomaticScaling.MaxInstance
-       runtimeHPA.Spec.MinReplicas = &proxy.Spec.AutomaticScaling.MinInstance
-       if len(proxy.Spec.AutomaticScaling.CustomMetrics) > 0 {
-               runtimeHPA.Spec.Metrics = 
proxy.Spec.AutomaticScaling.CustomMetrics
-       } else {
-               // We need to reconstruct the default hpa metric when the user 
deletes the custom metric.
-               runtimeHPA.Spec.Metrics = 
ConstructDefaultHPAMetric(&proxy.Spec.AutomaticScaling.Target)
-       }
-}
-
 func fromInt32(val int32) intstr.IntOrString {
        return intstr.IntOrString{Type: intstr.Int, IntVal: val}
 }
diff --git a/shardingsphere-operator/pkg/reconcile/service.go 
b/shardingsphere-operator/pkg/reconcile/service.go
new file mode 100644
index 0000000..3fdf693
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/service.go
@@ -0,0 +1,72 @@
+/*
+ * 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 reconcile
+
+import (
+       "reflect"
+
+       
"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+       v1 "k8s.io/api/core/v1"
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+func NewService(ssproxy *v1alpha1.ShardingSphereProxy) *v1.Service {
+       return ConstructCascadingService(ssproxy)
+}
+
+func ConstructCascadingService(proxy *v1alpha1.ShardingSphereProxy) 
*v1.Service {
+       if proxy == nil || reflect.DeepEqual(proxy, 
&v1alpha1.ShardingSphereProxy{}) {
+               return &v1.Service{}
+       }
+
+       svc := v1.Service{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      proxy.Name,
+                       Namespace: proxy.Namespace,
+                       OwnerReferences: []metav1.OwnerReference{
+                               *metav1.NewControllerRef(proxy.GetObjectMeta(), 
proxy.GroupVersionKind()),
+                       },
+               },
+               Spec: v1.ServiceSpec{
+                       Selector: map[string]string{
+                               "apps": proxy.Name,
+                       },
+                       Type: proxy.Spec.ServiceType.Type,
+                       Ports: []v1.ServicePort{
+                               {
+                                       Name:       "proxy-port",
+                                       TargetPort: fromInt32(proxy.Spec.Port),
+                                       Port:       proxy.Spec.Port,
+                               },
+                       },
+               },
+       }
+       if proxy.Spec.ServiceType.Type == v1.ServiceTypeNodePort {
+               svc.Spec.Ports[0].NodePort = proxy.Spec.ServiceType.NodePort
+       }
+       return &svc
+}
+
+func UpdateService(proxy *v1alpha1.ShardingSphereProxy, runtimeService 
*v1.Service) {
+       runtimeService.Spec.Type = proxy.Spec.ServiceType.Type
+       runtimeService.Spec.Ports[0].Port = proxy.Spec.Port
+       runtimeService.Spec.Ports[0].TargetPort = fromInt32(proxy.Spec.Port)
+       if proxy.Spec.ServiceType.NodePort != 0 {
+               runtimeService.Spec.Ports[0].NodePort = 
proxy.Spec.ServiceType.NodePort
+       }
+}


Reply via email to