You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by mi...@apache.org on 2023/04/20 11:00:09 UTC

[shardingsphere-on-cloud] branch feat-storagenode updated: feat(storagenode): support aws rds instance (#314)

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

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


The following commit(s) were added to refs/heads/feat-storagenode by this push:
     new 17aa43a  feat(storagenode): support aws rds instance (#314)
17aa43a is described below

commit 17aa43a5ff3d0f2043e69cde871b53dfee5ac291
Author: Xu-Wentao <cu...@yahoo.com>
AuthorDate: Thu Apr 20 19:00:02 2023 +0800

    feat(storagenode): support aws rds instance (#314)
---
 .../api/v1alpha1/storage_node_types.go             |  20 +-
 .../cmd/shardingsphere-operator/manager/option.go  |   2 +
 shardingsphere-operator/go.mod                     |  46 ++--
 shardingsphere-operator/go.sum                     | 104 ++++----
 .../pkg/controllers/controllers_suite_test.go      | 102 ++++++++
 .../pkg/controllers/storage_node_controller.go     | 250 +++++++++++++------
 .../controllers/storage_node_controller_test.go    | 264 +++++++++++++++++++--
 .../storagenode/{storagenode.go => aws/aurora.go}  |  35 +--
 .../pkg/reconcile/storagenode/aws/aws.go           |  60 +++++
 .../storagenode/aws/aws_suite_test.go}             |   6 +-
 .../pkg/reconcile/storagenode/aws/mocks/aws.go     | 166 +++++++++++++
 .../pkg/reconcile/storagenode/aws/rdsinstance.go   | 126 ++++++++++
 .../reconcile/storagenode/aws/rdsinstance_test.go  |  53 +++++
 .../reconcile/storagenode/awsaurora/awsaurora.go   | 117 ---------
 .../storagenode/awsaurora/awsaurora_suite_test.go  |  30 ---
 .../storagenode/awsaurora/awsaurora_test.go        | 113 ---------
 .../pkg/reconcile/storagenode/mocks/storagenode.go | 138 -----------
 17 files changed, 1035 insertions(+), 597 deletions(-)

diff --git a/shardingsphere-operator/api/v1alpha1/storage_node_types.go b/shardingsphere-operator/api/v1alpha1/storage_node_types.go
index 1515a96..ced5ff9 100644
--- a/shardingsphere-operator/api/v1alpha1/storage_node_types.go
+++ b/shardingsphere-operator/api/v1alpha1/storage_node_types.go
@@ -31,10 +31,12 @@ const (
 
 type StorageNodeConditionType string
 
-// StorageNodeConditionType shows some states during the startup process of storage node
+// StorageNodeConditionType shows some states during the startup process of storage node.
 const (
 	// StorageNodeConditionTypeAvailable means the all the instances and the cluster are ready, and the storage node is ready to provide external services.
 	StorageNodeConditionTypeAvailable StorageNodeConditionType = "Available"
+	// StorageNodeConditionTypeClusterReady means the cluster is ready, does not mean the instances are all ready.
+	StorageNodeConditionTypeClusterReady StorageNodeConditionType = "ClusterReady"
 )
 
 type StorageNodeConditions []*StorageNodeCondition
@@ -51,10 +53,12 @@ type StorageNodeCondition struct {
 // ClusterStatus is the status of a database cluster, including the primary endpoint, reader endpoints, and other properties.
 // Properties are some additional information about the cluster, like 'arn, identifier, credentials, etc.'
 type ClusterStatus struct {
-	Status          string            `json:"status"`
-	PrimaryEndpoint Endpoint          `json:"primaryEndpoint"`
-	ReaderEndpoints []Endpoint        `json:"readerEndpoints"`
-	Properties      map[string]string `json:"properties"`
+	Status          string   `json:"status"`
+	PrimaryEndpoint Endpoint `json:"primaryEndpoint"`
+	// +optional
+	ReaderEndpoints []Endpoint `json:"readerEndpoints"`
+	// +optional
+	Properties map[string]string `json:"properties"`
 }
 
 type CredentialType struct {
@@ -62,8 +66,9 @@ type CredentialType struct {
 }
 
 type InstanceStatus struct {
-	Status     string            `json:"status"`
-	Endpoint   Endpoint          `json:"primaryEndpoint"`
+	Status   string   `json:"status"`
+	Endpoint Endpoint `json:"primaryEndpoint"`
+	// +optional
 	Properties map[string]string `json:"properties"`
 }
 
@@ -128,7 +133,6 @@ type StorageNodeStatus struct {
 	Cluster ClusterStatus `json:"cluster,omitempty"`
 
 	// Instance contains the current status of the StorageNode instance
-	// +optional
 	Instances []InstanceStatus `json:"instances,omitempty"`
 }
 
diff --git a/shardingsphere-operator/cmd/shardingsphere-operator/manager/option.go b/shardingsphere-operator/cmd/shardingsphere-operator/manager/option.go
index 764f3dd..4e475ef 100644
--- a/shardingsphere-operator/cmd/shardingsphere-operator/manager/option.go
+++ b/shardingsphere-operator/cmd/shardingsphere-operator/manager/option.go
@@ -28,6 +28,7 @@ import (
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/kubernetes/service"
 	"github.com/database-mesh/golang-sdk/aws"
 	"github.com/database-mesh/golang-sdk/aws/client/rds"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 	"go.uber.org/zap/zapcore"
 	corev1 "k8s.io/api/core/v1"
 	"k8s.io/apimachinery/pkg/runtime"
@@ -46,6 +47,7 @@ var (
 func init() {
 	utilruntime.Must(clientgoscheme.AddToScheme(scheme))
 	utilruntime.Must(v1alpha1.AddToScheme(scheme))
+	utilruntime.Must(dbmeshv1alpha1.AddToScheme(scheme))
 }
 
 // Options represents common options for the controller
diff --git a/shardingsphere-operator/go.mod b/shardingsphere-operator/go.mod
index f5beab2..b681c7d 100644
--- a/shardingsphere-operator/go.mod
+++ b/shardingsphere-operator/go.mod
@@ -5,20 +5,20 @@ go 1.19
 require (
 	bou.ke/monkey v1.0.2
 	github.com/antlr/antlr4 v0.0.0-20181218183524-be58ebffde8e
-	github.com/database-mesh/golang-sdk v0.0.0-20230330100228-9fca0778e327
-	github.com/go-logr/logr v1.2.3
+	github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a
+	github.com/go-logr/logr v1.2.4
 	github.com/golang/mock v1.4.4
 	github.com/onsi/ginkgo/v2 v2.8.0
 	github.com/onsi/gomega v1.26.0
 	github.com/prometheus/client_golang v1.14.0
-	github.com/stretchr/testify v1.8.0
+	github.com/stretchr/testify v1.8.1
 	go.uber.org/zap v1.24.0
 	gopkg.in/yaml.v2 v2.4.0
-	k8s.io/api v0.26.1
-	k8s.io/apimachinery v0.26.1
+	k8s.io/api v0.26.4
+	k8s.io/apimachinery v0.26.4
 	k8s.io/client-go v0.26.1
-	k8s.io/utils v0.0.0-20221128185143-99ec85e7a448
-	sigs.k8s.io/controller-runtime v0.14.1
+	k8s.io/utils v0.0.0-20230406110748-d93618cff8a2
+	sigs.k8s.io/controller-runtime v0.14.6
 )
 
 require (
@@ -43,21 +43,21 @@ require (
 	github.com/evanphx/json-patch/v5 v5.6.0 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/go-logr/zapr v1.2.3 // indirect
-	github.com/go-openapi/jsonpointer v0.19.5 // indirect
-	github.com/go-openapi/jsonreference v0.20.0 // indirect
-	github.com/go-openapi/swag v0.19.14 // indirect
+	github.com/go-openapi/jsonpointer v0.19.6 // indirect
+	github.com/go-openapi/jsonreference v0.20.1 // indirect
+	github.com/go-openapi/swag v0.22.3 // indirect
 	github.com/gogo/protobuf v1.3.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
-	github.com/golang/protobuf v1.5.2 // indirect
+	github.com/golang/protobuf v1.5.3 // indirect
 	github.com/google/gnostic v0.5.7-v3refs // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
-	github.com/google/gofuzz v1.1.0 // indirect
-	github.com/google/uuid v1.1.2 // indirect
+	github.com/google/gofuzz v1.2.0 // indirect
+	github.com/google/uuid v1.3.0 // indirect
 	github.com/imdario/mergo v0.3.12 // indirect
 	github.com/jmespath/go-jmespath v0.4.0 // indirect
 	github.com/josharian/intern v1.0.0 // indirect
 	github.com/json-iterator/go v1.1.12 // indirect
-	github.com/mailru/easyjson v0.7.6 // indirect
+	github.com/mailru/easyjson v0.7.7 // indirect
 	github.com/matttproud/golang_protobuf_extensions v1.0.2 // indirect
 	github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
 	github.com/modern-go/reflect2 v1.0.2 // indirect
@@ -70,22 +70,22 @@ require (
 	github.com/spf13/pflag v1.0.5 // indirect
 	go.uber.org/atomic v1.7.0 // indirect
 	go.uber.org/multierr v1.6.0 // indirect
-	golang.org/x/net v0.5.0 // indirect
+	golang.org/x/net v0.9.0 // indirect
 	golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect
-	golang.org/x/sys v0.4.0 // indirect
-	golang.org/x/term v0.4.0 // indirect
-	golang.org/x/text v0.6.0 // indirect
+	golang.org/x/sys v0.7.0 // indirect
+	golang.org/x/term v0.7.0 // indirect
+	golang.org/x/text v0.9.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	gomodules.xyz/jsonpatch/v2 v2.2.0 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/inf.v0 v0.9.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	k8s.io/apiextensions-apiserver v0.26.0 // indirect
-	k8s.io/component-base v0.26.0 // indirect
-	k8s.io/klog/v2 v2.80.1 // indirect
-	k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 // indirect
-	sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 // indirect
+	k8s.io/apiextensions-apiserver v0.26.1 // indirect
+	k8s.io/component-base v0.26.1 // indirect
+	k8s.io/klog/v2 v2.90.1 // indirect
+	k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a // indirect
+	sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
 	sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
 	sigs.k8s.io/yaml v1.3.0 // indirect
 )
diff --git a/shardingsphere-operator/go.sum b/shardingsphere-operator/go.sum
index 6a33bbe..21e798b 100644
--- a/shardingsphere-operator/go.sum
+++ b/shardingsphere-operator/go.sum
@@ -88,8 +88,8 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
 github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
-github.com/database-mesh/golang-sdk v0.0.0-20230330100228-9fca0778e327 h1:iJmMLccduIYbVMMMKLl9temNOUncfoGgrvGl4CyQbz4=
-github.com/database-mesh/golang-sdk v0.0.0-20230330100228-9fca0778e327/go.mod h1:gYPsO263vm+u4GKmOFbPui4xOUEySZmQfZaMdyFogGQ=
+github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a h1:DkGqsSh0KgR3bRuk3DKtbVG5nOe6RIea1oikjbGDGIY=
+github.com/database-mesh/golang-sdk v0.0.0-20230420101548-53265cd9883a/go.mod h1:yUEdo+aGdROl9oC7A1GeDB9/ubUtV2k73uLL+qC3PC4=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -120,18 +120,16 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
 github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
 github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
 github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
 github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
-github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
-github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
-github.com/go-openapi/jsonreference v0.20.0 h1:MYlu0sBgChmCfJxxUKZ8g1cPWFOB37YSZqewK7OKeyA=
-github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
-github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
-github.com/go-openapi/swag v0.19.14 h1:gm3vOOXfiuw5i9p5N9xJvfjvuofpyvLA9Wr6QfK5Fng=
-github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
+github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
+github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
+github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
+github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g=
+github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
@@ -165,8 +163,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
 github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
-github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
 github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
+github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
+github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
 github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/gnostic v0.5.7-v3refs h1:FhTMOKj2VhjpouxvWJAV1TL304uMlb9zcDqkl6cEI54=
@@ -184,8 +183,8 @@ github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeN
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
-github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
-github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
+github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
+github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
 github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
 github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=
 github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -196,8 +195,8 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
 github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
 github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
-github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
+github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
 github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
@@ -229,14 +228,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxv
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
+github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
+github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
-github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
-github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA=
-github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
+github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
+github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
 github.com/matttproud/golang_protobuf_extensions v1.0.2 h1:hAHbPm5IJGijwng3PWk09JkG9WeqChjprR5s9bBZ+OM=
 github.com/matttproud/golang_protobuf_extensions v1.0.2/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
@@ -251,8 +250,6 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
-github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/onsi/ginkgo/v2 v2.8.0 h1:pAM+oBNPrpXRs+E/8spkeGx9QgekbRVyr74EUvRVOUI=
 github.com/onsi/ginkgo/v2 v2.8.0/go.mod h1:6JsQiECmxCa3V5st74AL/AmsV482EDdVrGaVW6z3oYU=
 github.com/onsi/gomega v1.26.0 h1:03cDLK28U6hWvCAns6NeydX3zIm4SF3ci69ulidS32Q=
@@ -299,15 +296,16 @@ github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
+github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
 github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
-github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
-github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
 github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
+github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
+github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@@ -394,8 +392,8 @@ golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwY
 golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw=
-golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws=
+golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM=
+golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -454,12 +452,12 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
+golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.4.0 h1:O7UWfv5+A2qiuulQk30kVinPoMtoIPeVaKLEgLpVkvg=
-golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ=
+golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ=
+golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -467,8 +465,8 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k=
-golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -607,8 +605,8 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
-gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
 gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
 gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
@@ -632,29 +630,29 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.26.1 h1:f+SWYiPd/GsiWwVRz+NbFyCgvv75Pk9NK6dlkZgpCRQ=
-k8s.io/api v0.26.1/go.mod h1:xd/GBNgR0f707+ATNyPmQ1oyKSgndzXij81FzWGsejg=
-k8s.io/apiextensions-apiserver v0.26.0 h1:Gy93Xo1eg2ZIkNX/8vy5xviVSxwQulsnUdQ00nEdpDo=
-k8s.io/apiextensions-apiserver v0.26.0/go.mod h1:7ez0LTiyW5nq3vADtK6C3kMESxadD51Bh6uz3JOlqWQ=
-k8s.io/apimachinery v0.26.1 h1:8EZ/eGJL+hY/MYCNwhmDzVqq2lPl3N3Bo8rvweJwXUQ=
-k8s.io/apimachinery v0.26.1/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
+k8s.io/api v0.26.4 h1:qSG2PmtcD23BkYiWfoYAcak870eF/hE7NNYBYavTT94=
+k8s.io/api v0.26.4/go.mod h1:WwKEXU3R1rgCZ77AYa7DFksd9/BAIKyOmRlbVxgvjCk=
+k8s.io/apiextensions-apiserver v0.26.1 h1:cB8h1SRk6e/+i3NOrQgSFij1B2S0Y0wDoNl66bn8RMI=
+k8s.io/apiextensions-apiserver v0.26.1/go.mod h1:AptjOSXDGuE0JICx/Em15PaoO7buLwTs0dGleIHixSM=
+k8s.io/apimachinery v0.26.4 h1:rZccKdBLg9vP6J09JD+z8Yr99Ce8gk3Lbi9TCx05Jzs=
+k8s.io/apimachinery v0.26.4/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5I=
 k8s.io/client-go v0.26.1 h1:87CXzYJnAMGaa/IDDfRdhTzxk/wzGZ+/HUQpqgVSZXU=
 k8s.io/client-go v0.26.1/go.mod h1:IWNSglg+rQ3OcvDkhY6+QLeasV4OYHDjdqeWkDQZwGE=
-k8s.io/component-base v0.26.0 h1:0IkChOCohtDHttmKuz+EP3j3+qKmV55rM9gIFTXA7Vs=
-k8s.io/component-base v0.26.0/go.mod h1:lqHwlfV1/haa14F/Z5Zizk5QmzaVf23nQzCwVOQpfC8=
-k8s.io/klog/v2 v2.80.1 h1:atnLQ121W371wYYFawwYx1aEY2eUfs4l3J72wtgAwV4=
-k8s.io/klog/v2 v2.80.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280 h1:+70TFaan3hfJzs+7VK2o+OGxg8HsuBr/5f6tVAjDu6E=
-k8s.io/kube-openapi v0.0.0-20221012153701-172d655c2280/go.mod h1:+Axhij7bCpeqhklhUTe3xmOn6bWxolyZEeyaFpjGtl4=
-k8s.io/utils v0.0.0-20221128185143-99ec85e7a448 h1:KTgPnR10d5zhztWptI952TNtt/4u5h3IzDXkdIMuo2Y=
-k8s.io/utils v0.0.0-20221128185143-99ec85e7a448/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/component-base v0.26.1 h1:4ahudpeQXHZL5kko+iDHqLj/FSGAEUnSVO0EBbgDd+4=
+k8s.io/component-base v0.26.1/go.mod h1:VHrLR0b58oC035w6YQiBSbtsf0ThuSwXP+p5dD/kAWU=
+k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
+k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a h1:gmovKNur38vgoWfGtP5QOGNOA7ki4n6qNYoFAgMlNvg=
+k8s.io/kube-openapi v0.0.0-20230308215209-15aac26d736a/go.mod h1:y5VtZWM9sHHc2ZodIH/6SHzXj+TPU5USoA8lcIeKEKY=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
 rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
 rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
 rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
-sigs.k8s.io/controller-runtime v0.14.1 h1:vThDes9pzg0Y+UbCPY3Wj34CGIYPgdmspPm2GIpxpzM=
-sigs.k8s.io/controller-runtime v0.14.1/go.mod h1:GaRkrY8a7UZF0kqFFbUKG7n9ICiTY5T55P1RiE3UZlU=
-sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2 h1:iXTIw73aPyC+oRdyqqvVJuloN1p0AC/kzH07hu3NE+k=
-sigs.k8s.io/json v0.0.0-20220713155537-f223a00ba0e2/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
+sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92KcwQA=
+sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
+sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
+sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
 sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
 sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
 sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
diff --git a/shardingsphere-operator/pkg/controllers/controllers_suite_test.go b/shardingsphere-operator/pkg/controllers/controllers_suite_test.go
index c37e70d..c42c813 100644
--- a/shardingsphere-operator/pkg/controllers/controllers_suite_test.go
+++ b/shardingsphere-operator/pkg/controllers/controllers_suite_test.go
@@ -18,13 +18,115 @@
 package controllers_test
 
 import (
+	"context"
+	"os"
+	"os/exec"
+	"path/filepath"
 	"testing"
 
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/cmd/shardingsphere-operator/manager"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/controllers"
+	dbmesh_aws "github.com/database-mesh/golang-sdk/aws"
+	dbmesh_rds "github.com/database-mesh/golang-sdk/aws/client/rds"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 	. "github.com/onsi/ginkgo/v2"
 	. "github.com/onsi/gomega"
+	"k8s.io/client-go/kubernetes/scheme"
+	"k8s.io/client-go/rest"
+	ctrl "sigs.k8s.io/controller-runtime"
+	"sigs.k8s.io/controller-runtime/pkg/client"
+	"sigs.k8s.io/controller-runtime/pkg/envtest"
+	logf "sigs.k8s.io/controller-runtime/pkg/log"
+	"sigs.k8s.io/controller-runtime/pkg/log/zap"
+)
+
+var (
+	cfg       *rest.Config
+	k8sClient client.Client // You'll be using this client in your tests.
+	testEnv   *envtest.Environment
+	ctx       context.Context
+	cancel    context.CancelFunc
 )
 
 func TestControllers(t *testing.T) {
 	RegisterFailHandler(Fail)
 	RunSpecs(t, "Controllers Suite")
 }
+
+func loadOnlineCRDs() {
+	urls := []string{
+		// DatabaseClass CRD file
+		"https://raw.githubusercontent.com/database-mesh/golang-sdk/main/config/crd/bases/core.database-mesh.io_databaseclasses.yaml",
+	}
+
+	filePath := filepath.Join("..", "..", "config", "crd", "bases")
+	for _, url := range urls {
+		Expect(exec.Command("wget", url, "-nc", "-P", filePath).Run()).Should(Succeed())
+	}
+}
+
+var _ = BeforeSuite(func() {
+	loadOnlineCRDs()
+
+	logf.SetLogger(zap.New(zap.WriteTo(GinkgoWriter), zap.UseDevMode(true)))
+
+	ctx, cancel = context.WithCancel(context.TODO())
+
+	By("bootstrapping test environment for controllers")
+
+	testEnv = &envtest.Environment{
+		CRDDirectoryPaths: []string{
+			filepath.Join("..", "..", "config", "crd", "bases"),
+		},
+		ErrorIfCRDPathMissing: true,
+	}
+
+	var err error
+	// cfg is defined in this file globally.
+	cfg, err = testEnv.Start()
+	Expect(err).NotTo(HaveOccurred())
+	Expect(cfg).NotTo(BeNil())
+
+	Expect(v1alpha1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred())
+	Expect(dbmeshv1alpha1.AddToScheme(scheme.Scheme)).NotTo(HaveOccurred())
+	//+kubebuilder:scaffold:scheme
+
+	k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
+	Expect(err).NotTo(HaveOccurred())
+	Expect(k8sClient).NotTo(BeNil())
+
+	// set metrics bind address to :9081, diff from default metric port:8080 and health check port:8081 to avoid conflict port when running tests
+	os.Args = append(os.Args, "--metrics-bind-address=:9081")
+
+	opt := manager.ParseOptionsFromCmdFlags()
+
+	k8sManager, err := ctrl.NewManager(cfg, opt.Options)
+
+	Expect(err).ToNot(HaveOccurred())
+
+	// print k8sManager Options
+	sess := dbmesh_aws.NewSessions().SetCredential("AwsRegion", "AwsAccessKeyID", "AwsSecretAccessKey").Build()
+	err = (&controllers.StorageNodeReconciler{
+		Client:   k8sManager.GetClient(),
+		Scheme:   k8sManager.GetScheme(),
+		Log:      ctrl.Log.WithName("controllers").WithName("StorageNode"),
+		Recorder: k8sManager.GetEventRecorderFor("StorageNode"),
+		AwsRDS:   dbmesh_rds.NewService(sess["AwsRegion"]),
+	}).SetupWithManager(k8sManager)
+	Expect(err).ToNot(HaveOccurred())
+
+	go func() {
+		defer GinkgoRecover()
+		err = k8sManager.Start(ctx)
+		Expect(err).ToNot(HaveOccurred(), "failed to run manager")
+	}()
+})
+
+var _ = AfterSuite(func() {
+	cancel()
+	By("tearing down the test environment for controllers")
+	err := testEnv.Stop()
+	Expect(err).NotTo(HaveOccurred())
+
+})
diff --git a/shardingsphere-operator/pkg/controllers/storage_node_controller.go b/shardingsphere-operator/pkg/controllers/storage_node_controller.go
index ab8edda..05a8f8c 100644
--- a/shardingsphere-operator/pkg/controllers/storage_node_controller.go
+++ b/shardingsphere-operator/pkg/controllers/storage_node_controller.go
@@ -23,8 +23,7 @@ import (
 	"reflect"
 
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode"
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/aws"
 	"github.com/database-mesh/golang-sdk/aws/client/rds"
 	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 	"github.com/go-logr/logr"
@@ -54,76 +53,83 @@ type StorageNodeReconciler struct {
 func (r *StorageNodeReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
 	logger := r.Log.WithValues(StorageNodeControllerName, req.NamespacedName)
 
+	logger.Info("Reconciling StorageNode")
+
 	node := &v1alpha1.StorageNode{}
 	if err := r.Get(ctx, req.NamespacedName, node); err != nil {
-		if client.IgnoreNotFound(err) != nil {
-			return ctrl.Result{}, client.IgnoreNotFound(err)
+		if client.IgnoreNotFound(err) == nil {
+			logger.Info(fmt.Sprintf("StorageNode [%s:%s] is not exist", req.Namespace, req.Name))
+			return ctrl.Result{}, nil
 		}
+		logger.Error(err, fmt.Sprintf("unable to fetch StorageNode [%s:%s]", req.Namespace, req.Name))
 		return ctrl.Result{Requeue: true}, err
 	}
 
-	desiredState := computeDesiredState(node.Status)
-
-	if !reflect.DeepEqual(node.Status, desiredState) {
-		node.Status = desiredState
-		err := r.Status().Update(ctx, node)
-		if err != nil {
-			return ctrl.Result{Requeue: true}, err
-		}
-	}
-
 	// Get databaseClass with storageNode.Spec.DatabaseClassName
-	// if databaseClass can not be found, requeue and set a warning event to storageNode
-	databaseClass := &dbmeshv1alpha1.DatabaseClass{}
-	if err := r.Get(ctx, client.ObjectKey{Name: node.Spec.DatabaseClassName}, databaseClass); err != nil {
+	databaseClass, err := r.getDatabaseClass(ctx, node)
+	if err != nil {
 		logger.Error(err, fmt.Sprintf("unable to fetch DatabaseClass [%s]", node.Spec.DatabaseClassName))
-		r.Recorder.Event(node, corev1.EventTypeWarning, "DatabaseClassNotFound", fmt.Sprintf("DatabaseClass [%s] not found", node.Spec.DatabaseClassName))
-		return ctrl.Result{RequeueAfter: defaultRequeueTime}, err
+		return ctrl.Result{Requeue: true}, err
+	}
+
+	// TODO: when storage node needed finalized, set deletion timestamp and set status to deleting, waiting database instance deleted. and then remove finalizer and delete storage node.
+
+	// finalize storage node
+	if err := r.finalize(ctx, node, databaseClass); err != nil {
+		logger.Error(err, fmt.Sprintf("unable to finalize StorageNode [%s:%s]", node.GetNamespace(), node.GetName()))
+		return ctrl.Result{}, err
 	}
 
-	var cClient storagenode.IDBClusterClient
+	// reconcile storage node with databaseClass
 	switch databaseClass.Spec.Provisioner {
-	case "aws-aurora":
-		cClient = awsaurora.New(r.AwsRDS)
+	case dbmeshv1alpha1.ProvisionerAWSRDSInstance:
+		if err := r.reconcileAwsRdsInstance(ctx, aws.NewRdsClient(r.AwsRDS), node, databaseClass); err != nil {
+			logger.Error(err, fmt.Sprintf("unable to reconcile AWS RDS Instance [%s:%s], err:%s", node.GetNamespace(), node.GetName(), err.Error()))
+			r.Recorder.Event(node, corev1.EventTypeWarning, fmt.Sprintf("Reconcile [%s:%s] Failed", node.GetNamespace(), node.GetName()), err.Error())
+		}
+	case dbmeshv1alpha1.ProvisionerAWSAurora:
+		if err := r.reconcileAwsAurora(ctx, aws.NewRdsClient(r.AwsRDS), node, databaseClass); err != nil {
+			r.Recorder.Event(node, corev1.EventTypeWarning, fmt.Sprintf("Reconcile [%s:%s] Failed", node.GetNamespace(), node.GetName()), err.Error())
+		}
 	default:
+		r.Recorder.Event(node, corev1.EventTypeWarning, "UnsupportedDatabaseProvisioner", fmt.Sprintf("unsupported database provisioner [%s]", databaseClass.Spec.Provisioner))
 		logger.Error(nil, fmt.Sprintf("unsupported database provisioner [%s]", databaseClass.Spec.Provisioner))
 	}
 
-	if err := cClient.IsValid(node); err != nil {
-		logger.Error(err, fmt.Sprintf("invalid database cluster [%s]", node.Spec.DatabaseClassName))
-		return ctrl.Result{Requeue: true}, err
-	}
+	// update status
+	desiredState := computeDesiredState(node.Status)
 
-	// finalize
-	// nolint:nestif
-	if node.ObjectMeta.DeletionTimestamp.IsZero() {
-		// The object is not being deleted, so if it does not have our finalizer,
-		// then lets add the finalizer and update the object. This is equivalent to registering our finalizer.
-		if !containsString(node.ObjectMeta.Finalizers, FinalizerName) {
-			node.ObjectMeta.Finalizers = append(node.ObjectMeta.Finalizers, FinalizerName)
-			err := r.Update(ctx, node)
-			if err != nil {
-				return ctrl.Result{Requeue: true}, err
-			}
-		}
-	} else if containsString(node.ObjectMeta.Finalizers, FinalizerName) {
-		if err := r.deleteDatabaseCluster(ctx, node, cClient); err != nil {
-			return ctrl.Result{Requeue: true}, err
-		}
-		node.ObjectMeta.Finalizers = removeString(node.ObjectMeta.Finalizers, FinalizerName)
-		err := r.Update(ctx, node)
+	if !reflect.DeepEqual(node.Status, desiredState) {
+		node.Status = desiredState
+		err := r.Status().Update(ctx, node)
 		if err != nil {
+			logger.Error(err, fmt.Sprintf("unable to update StorageNode [%s:%s] status", req.Namespace, req.Name))
 			return ctrl.Result{Requeue: true}, err
 		}
 	}
 
-	// reconcile database cluster
-	if err := r.reconcileDatabaseCluster(ctx, node, cClient, databaseClass.Spec.Parameters); err != nil {
-		logger.Error(err, fmt.Sprintf("unable to reconcile DatabaseCluster [%s], err:%s", node.Spec.DatabaseClassName, err.Error()))
-		return ctrl.Result{Requeue: true}, err
+	return ctrl.Result{RequeueAfter: defaultRequeueTime}, nil
+}
+
+func (r *StorageNodeReconciler) getDatabaseClass(ctx context.Context, node *v1alpha1.StorageNode) (databaseClass *dbmeshv1alpha1.DatabaseClass, err error) {
+	databaseClass = &dbmeshv1alpha1.DatabaseClass{}
+
+	if err := r.Get(ctx, client.ObjectKey{Name: node.Spec.DatabaseClassName}, databaseClass); err != nil {
+		r.Log.Error(err, fmt.Sprintf("unable to fetch DatabaseClass [%s]", node.Spec.DatabaseClassName))
+		r.Recorder.Event(node, corev1.EventTypeWarning, "DatabaseClassNotFound", fmt.Sprintf("DatabaseClass [%s] not found", node.Spec.DatabaseClassName))
+		return nil, err
 	}
 
-	return ctrl.Result{RequeueAfter: defaultRequeueTime}, nil
+	// check provisioner
+	// aws-like provisioner need aws rds client
+	if databaseClass.Spec.Provisioner == dbmeshv1alpha1.ProvisionerAWSRDSInstance || databaseClass.Spec.Provisioner == dbmeshv1alpha1.ProvisionerAWSAurora {
+		if r.AwsRDS == nil {
+			r.Recorder.Event(node, corev1.EventTypeWarning, "AwsRdsClientIsNil", "aws rds client is nil, please check your aws credentials")
+			return nil, fmt.Errorf("aws rds client is nil, please check your aws credentials")
+		}
+	}
+
+	return databaseClass, nil
 }
 
 func removeString(finalizers []string, name string) []string {
@@ -145,23 +151,74 @@ func containsString(finalizers []string, name string) bool {
 	return false
 }
 
-// nolint
+// nolint:nestif
+func (r *StorageNodeReconciler) finalize(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error {
+	if node.ObjectMeta.DeletionTimestamp.IsZero() {
+		// The object is not being deleted, so if it does not have our finalizer,
+		// then lets add the finalizer and update the object. This is equivalent to registering our finalizer.
+		if !containsString(node.ObjectMeta.Finalizers, FinalizerName) {
+			node.ObjectMeta.Finalizers = append(node.ObjectMeta.Finalizers, FinalizerName)
+			if err := r.Update(ctx, node); err != nil {
+				return err
+			}
+		}
+	} else if containsString(node.ObjectMeta.Finalizers, FinalizerName) {
+		// The object is being deleted
+		if err := r.deleteDatabaseCluster(ctx, node, databaseClass); err != nil {
+			return err
+		}
+		// remove our finalizer from the list and update it.
+		node.ObjectMeta.Finalizers = removeString(node.ObjectMeta.Finalizers, FinalizerName)
+		if err := r.Update(ctx, node); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// nolint:gocritic
 func computeDesiredState(status v1alpha1.StorageNodeStatus) v1alpha1.StorageNodeStatus {
 	// Initialize a new status object based on the current state
 	desiredState := status
 
-	// Compute the desired phase based on the number of instances and their readiness
-	if status.Cluster.Status == "Ready" && allInstancesReady(status.Instances) {
+	// TODO: set enums for aws instance status
+
+	// If the cluster status is not empty, then we compute the phase based on the cluster status
+	clusterStatus := ""
+	if status.Cluster.Status != "" {
+		if status.Cluster.Status == "available" {
+			clusterStatus = "Ready"
+		}
+	}
+
+	if (clusterStatus == "" || clusterStatus == "Ready") && allInstancesReady(status.Instances) {
 		desiredState.Phase = v1alpha1.StorageNodePhaseReady
-		desiredState.Cluster.Status = "Ready"
 	} else {
 		desiredState.Phase = v1alpha1.StorageNodePhaseNotReady
-		desiredState.Cluster.Status = "NotReady"
 	}
 
-	// Compute the desired conditions based on the phase and any errors
 	newSNConditions := status.Conditions
 
+	// Update the cluster ready condition if the cluster status is not empty
+	if clusterStatus != "" {
+		if clusterStatus == "Ready" {
+			newSNConditions.UpsertCondition(&v1alpha1.StorageNodeCondition{
+				Type:   v1alpha1.StorageNodeConditionTypeClusterReady,
+				Status: corev1.ConditionTrue,
+				Reason: "Cluster is ready",
+			})
+		} else {
+			newSNConditions.UpsertCondition(&v1alpha1.StorageNodeCondition{
+				Type:   v1alpha1.StorageNodeConditionTypeClusterReady,
+				Status: corev1.ConditionFalse,
+				Reason: "Cluster is not ready",
+			})
+		}
+	} else {
+		newSNConditions.RemoveCondition(v1alpha1.StorageNodeConditionTypeClusterReady)
+	}
+
+	// Update the available condition based on the phase
 	if desiredState.Phase == v1alpha1.StorageNodePhaseReady {
 		newSNConditions.UpsertCondition(&v1alpha1.StorageNodeCondition{
 			Type:   v1alpha1.StorageNodeConditionTypeAvailable,
@@ -186,45 +243,94 @@ func allInstancesReady(instances []v1alpha1.InstanceStatus) bool {
 	if len(instances) == 0 {
 		return false
 	}
-	// nolint
-	for _, instance := range instances {
+
+	for idx := range instances {
+		instance := &instances[idx]
 		if !(instance.Status == "Ready") {
 			return false
 		}
 	}
+
 	return true
 }
 
-func (r *StorageNodeReconciler) reconcileDatabaseCluster(ctx context.Context, node *v1alpha1.StorageNode, client storagenode.IDBClusterClient, params map[string]string) error {
-	cluster, err := client.GetCluster(ctx, node)
+func (r *StorageNodeReconciler) reconcileAwsRdsInstance(ctx context.Context, client aws.IRdsClient, node *v1alpha1.StorageNode, dbClass *dbmeshv1alpha1.DatabaseClass) error {
+	instance, err := client.GetInstance(ctx, node)
 	if err != nil {
-		r.Log.Error(err, fmt.Sprintf("unable to get database cluster [%s]", node.Spec.DatabaseClassName))
 		return err
 	}
 
-	if cluster == nil {
-		cluster, err = client.CreateCluster(ctx, node, params)
+	if instance == nil {
+		err = client.CreateInstance(ctx, node, dbClass.Spec.Parameters)
 		if err != nil {
-			r.Log.Error(err, fmt.Sprintf("unable to create database cluster [%s]", node.Spec.DatabaseClassName))
 			return err
 		}
+
+		instance, err = client.GetInstance(ctx, node)
+		if err != nil {
+			return err
+		}
+	}
+
+	r.Log.Info(fmt.Sprintf("RDS instance [%s] status is [%s]", instance.DBInstanceIdentifier, instance.DBInstanceStatus))
+
+	newStatus := updateInstanceStatus(node, instance)
+	node.Status.Instances = newStatus
+	if err := r.Status().Update(ctx, node); err != nil {
+		r.Log.Error(err, fmt.Sprintf("Failed to update status for node [%s:%s]", node.GetNamespace(), node.GetName()))
 	}
-	r.Log.Info(fmt.Sprintf("database cluster [%+v] is ready", cluster))
+	r.Recorder.Eventf(node, corev1.EventTypeNormal, "Reconcile", "Reconciled RDS instance %s, status is %s", instance.DBInstanceIdentifier, instance.DBInstanceStatus)
 	return nil
 }
 
-// deleteDatabaseCluster when a storageNode is deleted, we need to delete the database cluster
-func (r *StorageNodeReconciler) deleteDatabaseCluster(ctx context.Context, node *v1alpha1.StorageNode, client storagenode.IDBClusterClient) error {
-	cluster, err := client.GetCluster(ctx, node)
+func updateInstanceStatus(node *v1alpha1.StorageNode, instance *rds.DescInstance) []v1alpha1.InstanceStatus {
+	instances := make([]v1alpha1.InstanceStatus, 0)
+
+	status := instance.DBInstanceStatus
+	if status == "available" {
+		status = "Ready"
+	}
+
+	instances = append(instances, v1alpha1.InstanceStatus{
+		Endpoint: v1alpha1.Endpoint{
+			Address: instance.Endpoint.Address,
+			Port:    instance.Endpoint.Port,
+		},
+		Status: status,
+	})
+	return instances
+}
+
+func (r *StorageNodeReconciler) reconcileAwsAurora(ctx context.Context, client aws.IRdsClient, node *v1alpha1.StorageNode, dbClass *dbmeshv1alpha1.DatabaseClass) error {
+	// get instance
+	instance, err := client.GetAuroraCluster(ctx, node)
 	if err != nil {
 		return err
 	}
-	if cluster == nil {
-		return nil
+	if instance == nil {
+		// create instance
+		err = client.CreateAuroraCluster(ctx, node, dbClass.Spec.Parameters)
+		if err != nil {
+			return err
+		}
 	}
-	// delete database cluster
-	if err := client.DeleteCluster(ctx, node); err != nil {
-		return err
+	// TODO: update storage node status
+	return nil
+}
+
+// deleteDatabaseCluster
+func (r *StorageNodeReconciler) deleteDatabaseCluster(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error {
+	switch databaseClass.Spec.Provisioner {
+	case dbmeshv1alpha1.ProvisionerAWSRDSInstance:
+		if err := aws.NewRdsClient(r.AwsRDS).DeleteInstance(ctx, node, databaseClass); err != nil {
+			return err
+		}
+	case dbmeshv1alpha1.ProvisionerAWSAurora:
+		if err := aws.NewRdsClient(r.AwsRDS).DeleteAuroraCluster(ctx, node, databaseClass); err != nil {
+			return err
+		}
+	default:
+		return fmt.Errorf("unsupported database provisioner [%s]", databaseClass.Spec.Provisioner)
 	}
 	return nil
 }
diff --git a/shardingsphere-operator/pkg/controllers/storage_node_controller_test.go b/shardingsphere-operator/pkg/controllers/storage_node_controller_test.go
index 7224fad..a9f07ea 100644
--- a/shardingsphere-operator/pkg/controllers/storage_node_controller_test.go
+++ b/shardingsphere-operator/pkg/controllers/storage_node_controller_test.go
@@ -20,14 +20,16 @@ package controllers_test
 
 import (
 	"context"
+	"reflect"
+	"time"
 
 	"bou.ke/monkey"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/controllers"
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode"
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora"
-	mock_storagenode "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/mocks"
-	"github.com/database-mesh/golang-sdk/aws/client/rds"
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/aws"
+	mock_aws "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode/aws/mocks"
+	dbmesh_aws "github.com/database-mesh/golang-sdk/aws"
+	dbmesh_rds "github.com/database-mesh/golang-sdk/aws/client/rds"
 	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 	"github.com/golang/mock/gomock"
 	. "github.com/onsi/ginkgo/v2"
@@ -43,7 +45,7 @@ import (
 	"sigs.k8s.io/controller-runtime/pkg/log/zap"
 )
 
-var _ = Describe("StorageNode Controller", func() {
+var _ = Describe("StorageNode Controller Mock Test", func() {
 	var fakeClient client.Client
 	var reconciler *controllers.StorageNodeReconciler
 	BeforeEach(func() {
@@ -62,10 +64,12 @@ var _ = Describe("StorageNode Controller", func() {
 			},
 		)
 
+		sess := dbmesh_aws.NewSessions().SetCredential("AwsRegion", "AwsAccessKeyID", "AwsSecretAccessKey").Build()
 		reconciler = &controllers.StorageNodeReconciler{
 			Client:   fakeClient,
 			Log:      logf.Log,
 			Recorder: recorder,
+			AwsRDS:   dbmesh_rds.NewService(sess["AwsRegion"]),
 		}
 	})
 
@@ -114,33 +118,29 @@ var _ = Describe("StorageNode Controller", func() {
 		})
 	})
 
-	Context("create storage node with exist databaseClass", func() {
-		// test create node with exist databaseClass and success
-		It("should reconcile successfully", func() {
-			var mockCtrl *gomock.Controller
-			var cc *mock_storagenode.MockIDBClusterClient
-
+	Context("reconcile storageNode with exist databaseClass", func() {
+		var mockCtrl *gomock.Controller
+		var mockAws *mock_aws.MockIRdsClient
+		BeforeEach(func() {
 			mockCtrl = gomock.NewController(GinkgoT())
-			cc = mock_storagenode.NewMockIDBClusterClient(mockCtrl)
+			mockAws = mock_aws.NewMockIRdsClient(mockCtrl)
 
-			monkey.Patch(awsaurora.New, func(_ rds.RDS) storagenode.IDBClusterClient {
-				return cc
+			monkey.Patch(aws.NewRdsClient, func(rds dbmesh_rds.RDS) aws.IRdsClient {
+				return mockAws
 			})
 
-			defer func() {
-				mockCtrl.Finish()
-			}()
-
+			// create databaseClass
 			dbClass := &dbmeshv1alpha1.DatabaseClass{
 				ObjectMeta: metav1.ObjectMeta{
 					Name: "test-database-class",
 				},
 				Spec: dbmeshv1alpha1.DatabaseClassSpec{
-					Provisioner: "aws-aurora",
+					Provisioner: dbmeshv1alpha1.ProvisionerAWSRDSInstance,
 				},
 			}
 			Expect(fakeClient.Create(context.Background(), dbClass)).Should(Succeed())
 
+			// create storageNode
 			storageNode := &v1alpha1.StorageNode{
 				ObjectMeta: metav1.ObjectMeta{
 					Name:      "test-storage-node",
@@ -150,8 +150,16 @@ var _ = Describe("StorageNode Controller", func() {
 					DatabaseClassName: "test-database-class",
 				},
 			}
+
 			Expect(fakeClient.Create(context.Background(), storageNode)).Should(Succeed())
+		})
+
+		AfterEach(func() {
+			mockCtrl.Finish()
+			monkey.UnpatchAll()
+		})
 
+		It("should reconcile successfully with Creating Instance", func() {
 			req := ctrl.Request{
 				NamespacedName: client.ObjectKey{
 					Name:      "test-storage-node",
@@ -159,15 +167,225 @@ var _ = Describe("StorageNode Controller", func() {
 				},
 			}
 
-			// cluster is not exist and create a new cluster
-			cc.EXPECT().IsValid(gomock.Any()).Return(nil).AnyTimes()
-			cc.EXPECT().GetCluster(gomock.Any(), gomock.Any()).Return(nil, nil).AnyTimes()
-			cc.EXPECT().CreateCluster(gomock.Any(), gomock.Any(), gomock.Any()).Return(&storagenode.DatabaseCluster{}, nil).AnyTimes()
+			rdsInstance := &dbmesh_rds.DescInstance{
+				DBInstanceStatus: "creating",
+				Endpoint: dbmesh_rds.Endpoint{
+					Address: "127.0.0.1",
+					Port:    3306,
+				},
+			}
+
+			// mock aws rds client
+			mockAws.EXPECT().GetInstance(gomock.Any(), gomock.Any()).Return(rdsInstance, nil).AnyTimes()
 			_, err := reconciler.Reconcile(context.Background(), req)
 			Expect(err).To(BeNil())
 
 			newSN := &v1alpha1.StorageNode{}
 			Expect(fakeClient.Get(context.Background(), client.ObjectKey{Name: "test-storage-node", Namespace: "test-namespace"}, newSN)).Should(Succeed())
+			Expect(newSN.Status.Phase).To(Equal(v1alpha1.StorageNodePhaseNotReady))
+			Expect(newSN.Status.Instances).To(HaveLen(1))
+			Expect(newSN.Status.Instances[0].Status).To(Equal("creating"))
+		})
+
+		It("should reconcile successfully with Available Instance", func() {
+			req := ctrl.Request{
+				NamespacedName: client.ObjectKey{
+					Name:      "test-storage-node",
+					Namespace: "test-namespace",
+				},
+			}
+
+			rdsInstance := &dbmesh_rds.DescInstance{
+				DBInstanceStatus: "available",
+				Endpoint: dbmesh_rds.Endpoint{
+					Address: "127.0.0.1",
+					Port:    3306,
+				},
+			}
+
+			// mock aws rds client
+			mockAws.EXPECT().GetInstance(gomock.Any(), gomock.Any()).Return(rdsInstance, nil)
+			_, err := reconciler.Reconcile(context.Background(), req)
+			Expect(err).To(BeNil())
+
+			newSN := &v1alpha1.StorageNode{}
+			Expect(fakeClient.Get(context.Background(), client.ObjectKey{Name: "test-storage-node", Namespace: "test-namespace"}, newSN)).Should(Succeed())
+
+			Expect(newSN.Status.Phase).To(Equal(v1alpha1.StorageNodePhaseReady))
+			Expect(newSN.Status.Instances).To(HaveLen(1))
+			Expect(newSN.Status.Instances[0].Status).To(Equal("Ready"))
+		})
+
+		It("should reconcile successfully when storage node be deleted", func() {
+			req := ctrl.Request{
+				NamespacedName: client.ObjectKey{
+					Name:      "test-storage-node",
+					Namespace: "test-namespace",
+				},
+			}
+
+			rdsInstance := &dbmesh_rds.DescInstance{
+				DBInstanceStatus: "available",
+				Endpoint: dbmesh_rds.Endpoint{
+					Address: "127.0.0.1",
+					Port:    3306,
+				},
+			}
+
+			// mock aws rds client, get instance
+			mockAws.EXPECT().GetInstance(gomock.Any(), gomock.Any()).Return(rdsInstance, nil).AnyTimes()
+			// reconcile storage node, add instance and set status to ready
+			_, err := reconciler.Reconcile(context.Background(), req)
+			Expect(err).To(BeNil())
+
+			// delete storage node
+			sn := &v1alpha1.StorageNode{}
+			Expect(fakeClient.Get(context.Background(), client.ObjectKey{Name: "test-storage-node", Namespace: "test-namespace"}, sn)).Should(Succeed())
+			Expect(fakeClient.Delete(context.Background(), sn)).Should(Succeed())
+
+			// mock aws rds client, delete instance
+			mockAws.EXPECT().DeleteInstance(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
+			_, err = reconciler.Reconcile(context.Background(), req)
+			Expect(err).To(BeNil())
+		})
+	})
+})
+
+var _ = Describe("StorageNode Controller Suite Test", func() {
+	var databaseClassName = "test-database-class"
+
+	BeforeEach(func() {
+
+		databaseClass := &dbmeshv1alpha1.DatabaseClass{
+			ObjectMeta: metav1.ObjectMeta{
+				Name: databaseClassName,
+			},
+			Spec: dbmeshv1alpha1.DatabaseClassSpec{
+				Provisioner: dbmeshv1alpha1.ProvisionerAWSRDSInstance,
+				Parameters: map[string]string{
+					"engine":             "mysql",
+					"engineVersion":      "5.7",
+					"instanceClass":      "db.t3.micro",
+					"allocatedStorage":   "20",
+					"masterUsername":     "root",
+					"masterUserPassword": "root123456",
+				},
+			},
+		}
+
+		Expect(k8sClient.Create(context.Background(), databaseClass)).Should(Succeed())
+	})
+
+	AfterEach(func() {
+		databaseClass := &dbmeshv1alpha1.DatabaseClass{}
+		Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: databaseClassName}, databaseClass)).Should(Succeed())
+		Expect(k8sClient.Delete(context.Background(), databaseClass)).Should(Succeed())
+	})
+
+	Context("reconcile storageNode", func() {
+		BeforeEach(func() {
+
+			// mock get instance func returns Available status
+			monkey.PatchInstanceMethod(reflect.TypeOf(&aws.RdsClient{}), "GetInstance", func(_ *aws.RdsClient, _ context.Context, _ *v1alpha1.StorageNode) (*dbmesh_rds.DescInstance, error) {
+				return &dbmesh_rds.DescInstance{
+					DBInstanceStatus: "available",
+					Endpoint: dbmesh_rds.Endpoint{
+						Address: "127.0.0.1",
+						Port:    3306,
+					},
+				}, nil
+			})
+
+			// mock delete instance func returns success
+			monkey.PatchInstanceMethod(reflect.TypeOf(&aws.RdsClient{}), "DeleteInstance", func(_ *aws.RdsClient, _ context.Context, _ *v1alpha1.StorageNode, _ *dbmeshv1alpha1.DatabaseClass) error {
+				return nil
+			})
+		})
+
+		AfterEach(func() {
+			monkey.UnpatchAll()
+		})
+
+		It("should be success", func() {
+
+			nodeName := "test-storage-node-ready"
+			node := &v1alpha1.StorageNode{
+				ObjectMeta: metav1.ObjectMeta{
+					Name:      nodeName,
+					Namespace: "default",
+					Annotations: map[string]string{
+						dbmeshv1alpha1.AnnotationsInstanceIdentifier: "test-instance-identifier",
+					},
+				},
+				Spec: v1alpha1.StorageNodeSpec{
+					DatabaseClassName: databaseClassName,
+				},
+			}
+
+			// create resource
+			Expect(k8sClient.Create(context.Background(), node)).Should(Succeed())
+
+			// check storage node status
+			Eventually(func() v1alpha1.StorageNodePhaseStatus {
+				newSN := &v1alpha1.StorageNode{}
+				Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: nodeName, Namespace: "default"}, newSN)).Should(Succeed())
+				return newSN.Status.Phase
+			}, 10*time.Second, 1*time.Second).Should(Equal(v1alpha1.StorageNodePhaseReady))
+
+			// delete resource
+			Expect(k8sClient.Delete(context.Background(), node)).Should(Succeed())
+		})
+
+		Context("reconcile storageNode with Creating instance", func() {
+			BeforeEach(func() {
+				// mock get instance func returns creating status
+				monkey.PatchInstanceMethod(reflect.TypeOf(&aws.RdsClient{}), "GetInstance", func(_ *aws.RdsClient, _ context.Context, _ *v1alpha1.StorageNode) (*dbmesh_rds.DescInstance, error) {
+					return &dbmesh_rds.DescInstance{
+						DBInstanceStatus: "creating",
+						Endpoint: dbmesh_rds.Endpoint{
+							Address: "127.0.0.1",
+							Port:    3306,
+						},
+					}, nil
+				})
+				// mock delete instance func return success
+				monkey.PatchInstanceMethod(reflect.TypeOf(&aws.RdsClient{}), "DeleteInstance", func(_ *aws.RdsClient, _ context.Context, _ *v1alpha1.StorageNode, _ *dbmeshv1alpha1.DatabaseClass) error {
+					return nil
+				})
+			})
+
+			AfterEach(func() {
+				monkey.UnpatchAll()
+			})
+
+			It("should be success", func() {
+				nodeName := "test-storage-node-creating"
+				node := &v1alpha1.StorageNode{
+					ObjectMeta: metav1.ObjectMeta{
+						Name:      nodeName,
+						Namespace: "default",
+						Annotations: map[string]string{
+							dbmeshv1alpha1.AnnotationsInstanceIdentifier: "test-instance-identifier",
+						},
+					},
+					Spec: v1alpha1.StorageNodeSpec{
+						DatabaseClassName: databaseClassName,
+					},
+				}
+
+				// create resource
+				Expect(k8sClient.Create(context.Background(), node)).Should(Succeed())
+
+				// check storage node status
+				Eventually(func() v1alpha1.StorageNodePhaseStatus {
+					newSN := &v1alpha1.StorageNode{}
+					Expect(k8sClient.Get(context.Background(), client.ObjectKey{Name: nodeName, Namespace: "default"}, newSN)).Should(Succeed())
+					return newSN.Status.Phase
+				}, 10*time.Second, 1*time.Second).Should(Equal(v1alpha1.StorageNodePhaseNotReady))
+
+				// delete resource
+				Expect(k8sClient.Delete(context.Background(), node)).Should(Succeed())
+			})
 		})
 	})
 })
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/storagenode.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aurora.go
similarity index 51%
rename from shardingsphere-operator/pkg/reconcile/storagenode/storagenode.go
rename to shardingsphere-operator/pkg/reconcile/storagenode/aws/aurora.go
index 67a8ebc..f20ed3c 100644
--- a/shardingsphere-operator/pkg/reconcile/storagenode/storagenode.go
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aurora.go
@@ -13,34 +13,35 @@
  * 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 storagenode
+package aws
 
 import (
 	"context"
 
 	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/database-mesh/golang-sdk/aws/client/rds"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
 )
 
-type DatabaseCluster struct {
-	Status          string   `json:"status"`
-	PrimaryEndpoint string   `json:"primaryEndpoint"`
-	ReaderEndpoints []string `json:"readerEndpoints"`
+func (c *RdsClient) CreateAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error {
+	aurora := c.Aurora()
+	err := aurora.Create(ctx)
+	return err
 }
 
-type DatabaseInstance struct {
-	Endpoint v1alpha1.Endpoint `json:"endpoint"`
+func (c *RdsClient) GetAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode) (cluster *rds.DescCluster, err error) {
+	if node.Status.Cluster.Properties == nil || node.Status.Cluster.Properties["clusterIdentifier"] == "" {
+		// cluster not created
+		return nil, nil
+	}
+
+	aurora := c.Aurora()
+	return aurora.Describe(ctx)
 }
 
-type IDBClusterClient interface {
-	// IsValid validate the client parameters
-	IsValid(node *v1alpha1.StorageNode) error
-	GetCluster(ctx context.Context, node *v1alpha1.StorageNode) (cluster *DatabaseCluster, err error)
-	CreateCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) (cluster *DatabaseCluster, err error)
-	DeleteCluster(ctx context.Context, node *v1alpha1.StorageNode) error
-	GetInstances(ctx context.Context, cluster *DatabaseCluster) ([]*DatabaseInstance, error)
-	CreateInstance(ctx context.Context) error
-	DeleteInstance(ctx context.Context) error
+func (c *RdsClient) DeleteAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error {
+	aurora := c.Aurora()
+	return aurora.Delete(ctx)
 }
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/aws/aws.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aws.go
new file mode 100644
index 0000000..01887d3
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aws.go
@@ -0,0 +1,60 @@
+/*
+ * 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 aws
+
+import (
+	"context"
+
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/database-mesh/golang-sdk/aws/client/rds"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
+)
+
+type RdsClient struct {
+	RDS rds.RDS
+}
+
+type IRdsClient interface {
+	Aurora() rds.Aurora
+	Instance() rds.Instance
+	Cluster() rds.Cluster
+
+	CreateInstance(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error
+	GetInstance(ctx context.Context, node *v1alpha1.StorageNode) (instance *rds.DescInstance, err error)
+	DeleteInstance(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error
+
+	CreateAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error
+	GetAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode) (cluster *rds.DescCluster, err error)
+	DeleteAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error
+}
+
+func NewRdsClient(rds rds.RDS) IRdsClient {
+	return &RdsClient{RDS: rds}
+}
+
+func (c *RdsClient) Aurora() rds.Aurora {
+	return c.RDS.Aurora()
+}
+
+func (c *RdsClient) Instance() rds.Instance {
+	return c.RDS.Instance()
+}
+
+func (c *RdsClient) Cluster() rds.Cluster {
+	return c.RDS.Cluster()
+}
diff --git a/shardingsphere-operator/pkg/controllers/controllers_suite_test.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aws_suite_test.go
similarity index 90%
copy from shardingsphere-operator/pkg/controllers/controllers_suite_test.go
copy to shardingsphere-operator/pkg/reconcile/storagenode/aws/aws_suite_test.go
index c37e70d..3314470 100644
--- a/shardingsphere-operator/pkg/controllers/controllers_suite_test.go
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/aws_suite_test.go
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package controllers_test
+package aws_test
 
 import (
 	"testing"
@@ -24,7 +24,7 @@ import (
 	. "github.com/onsi/gomega"
 )
 
-func TestControllers(t *testing.T) {
+func TestAws(t *testing.T) {
 	RegisterFailHandler(Fail)
-	RunSpecs(t, "Controllers Suite")
+	RunSpecs(t, "Aws Suite")
 }
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/aws/mocks/aws.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/mocks/aws.go
new file mode 100644
index 0000000..4a66311
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/mocks/aws.go
@@ -0,0 +1,166 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: aws.go
+
+// Package mock_aws is a generated GoMock package.
+package mock_aws
+
+import (
+	context "context"
+	reflect "reflect"
+
+	v1alpha1 "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	rds "github.com/database-mesh/golang-sdk/aws/client/rds"
+	v1alpha10 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
+	gomock "github.com/golang/mock/gomock"
+)
+
+// MockIRdsClient is a mock of IRdsClient interface.
+type MockIRdsClient struct {
+	ctrl     *gomock.Controller
+	recorder *MockIRdsClientMockRecorder
+}
+
+// MockIRdsClientMockRecorder is the mock recorder for MockIRdsClient.
+type MockIRdsClientMockRecorder struct {
+	mock *MockIRdsClient
+}
+
+// NewMockIRdsClient creates a new mock instance.
+func NewMockIRdsClient(ctrl *gomock.Controller) *MockIRdsClient {
+	mock := &MockIRdsClient{ctrl: ctrl}
+	mock.recorder = &MockIRdsClientMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockIRdsClient) EXPECT() *MockIRdsClientMockRecorder {
+	return m.recorder
+}
+
+// Aurora mocks base method.
+func (m *MockIRdsClient) Aurora() rds.Aurora {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Aurora")
+	ret0, _ := ret[0].(rds.Aurora)
+	return ret0
+}
+
+// Aurora indicates an expected call of Aurora.
+func (mr *MockIRdsClientMockRecorder) Aurora() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Aurora", reflect.TypeOf((*MockIRdsClient)(nil).Aurora))
+}
+
+// Cluster mocks base method.
+func (m *MockIRdsClient) Cluster() rds.Cluster {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Cluster")
+	ret0, _ := ret[0].(rds.Cluster)
+	return ret0
+}
+
+// Cluster indicates an expected call of Cluster.
+func (mr *MockIRdsClientMockRecorder) Cluster() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Cluster", reflect.TypeOf((*MockIRdsClient)(nil).Cluster))
+}
+
+// CreateAuroraCluster mocks base method.
+func (m *MockIRdsClient) CreateAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateAuroraCluster", ctx, node, params)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CreateAuroraCluster indicates an expected call of CreateAuroraCluster.
+func (mr *MockIRdsClientMockRecorder) CreateAuroraCluster(ctx, node, params interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAuroraCluster", reflect.TypeOf((*MockIRdsClient)(nil).CreateAuroraCluster), ctx, node, params)
+}
+
+// CreateInstance mocks base method.
+func (m *MockIRdsClient) CreateInstance(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "CreateInstance", ctx, node, params)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// CreateInstance indicates an expected call of CreateInstance.
+func (mr *MockIRdsClientMockRecorder) CreateInstance(ctx, node, params interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInstance", reflect.TypeOf((*MockIRdsClient)(nil).CreateInstance), ctx, node, params)
+}
+
+// DeleteAuroraCluster mocks base method.
+func (m *MockIRdsClient) DeleteAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *v1alpha10.DatabaseClass) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteAuroraCluster", ctx, node, databaseClass)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DeleteAuroraCluster indicates an expected call of DeleteAuroraCluster.
+func (mr *MockIRdsClientMockRecorder) DeleteAuroraCluster(ctx, node, databaseClass interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAuroraCluster", reflect.TypeOf((*MockIRdsClient)(nil).DeleteAuroraCluster), ctx, node, databaseClass)
+}
+
+// DeleteInstance mocks base method.
+func (m *MockIRdsClient) DeleteInstance(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *v1alpha10.DatabaseClass) error {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "DeleteInstance", ctx, node, databaseClass)
+	ret0, _ := ret[0].(error)
+	return ret0
+}
+
+// DeleteInstance indicates an expected call of DeleteInstance.
+func (mr *MockIRdsClientMockRecorder) DeleteInstance(ctx, node, databaseClass interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstance", reflect.TypeOf((*MockIRdsClient)(nil).DeleteInstance), ctx, node, databaseClass)
+}
+
+// GetAuroraCluster mocks base method.
+func (m *MockIRdsClient) GetAuroraCluster(ctx context.Context, node *v1alpha1.StorageNode) (*rds.DescCluster, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetAuroraCluster", ctx, node)
+	ret0, _ := ret[0].(*rds.DescCluster)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetAuroraCluster indicates an expected call of GetAuroraCluster.
+func (mr *MockIRdsClientMockRecorder) GetAuroraCluster(ctx, node interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAuroraCluster", reflect.TypeOf((*MockIRdsClient)(nil).GetAuroraCluster), ctx, node)
+}
+
+// GetInstance mocks base method.
+func (m *MockIRdsClient) GetInstance(ctx context.Context, node *v1alpha1.StorageNode) (*rds.DescInstance, error) {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "GetInstance", ctx, node)
+	ret0, _ := ret[0].(*rds.DescInstance)
+	ret1, _ := ret[1].(error)
+	return ret0, ret1
+}
+
+// GetInstance indicates an expected call of GetInstance.
+func (mr *MockIRdsClientMockRecorder) GetInstance(ctx, node interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstance", reflect.TypeOf((*MockIRdsClient)(nil).GetInstance), ctx, node)
+}
+
+// Instance mocks base method.
+func (m *MockIRdsClient) Instance() rds.Instance {
+	m.ctrl.T.Helper()
+	ret := m.ctrl.Call(m, "Instance")
+	ret0, _ := ret[0].(rds.Instance)
+	return ret0
+}
+
+// Instance indicates an expected call of Instance.
+func (mr *MockIRdsClientMockRecorder) Instance() *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Instance", reflect.TypeOf((*MockIRdsClient)(nil).Instance))
+}
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go
new file mode 100644
index 0000000..71ff25f
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance.go
@@ -0,0 +1,126 @@
+/*
+ * 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 aws
+
+import (
+	"context"
+	"errors"
+	"fmt"
+	"strconv"
+
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	"github.com/database-mesh/golang-sdk/aws/client/rds"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
+)
+
+func validCreateInstanceParams(node *v1alpha1.StorageNode, params map[string]string) error {
+	requiredParams := map[string]string{
+		"engine":             "engine is empty",
+		"engineVersion":      "engine version is empty",
+		"instanceClass":      "instance class is empty",
+		"masterUsername":     "master username is empty",
+		"masterUserPassword": "master user password is empty",
+		"allocatedStorage":   "allocated storage is empty",
+	}
+
+	for k, v := range requiredParams {
+		if val, ok := params[k]; !ok || val == "" {
+			return errors.New(v)
+		}
+	}
+
+	// validate instance identifier.
+	if val, ok := node.Annotations[dbmeshv1alpha1.AnnotationsInstanceIdentifier]; !ok || val == "" {
+		return errors.New("instance identifier is empty")
+	}
+
+	// TODO set options to generate password and write back to storage node annos.
+	// TODO set options to set master username by user.
+	// validate master user password length. must be greater than 8. from aws doc.
+	if len(params["masterUserPassword"]) < 8 {
+		return errors.New("master user password length should be greater than 8")
+	}
+
+	return nil
+}
+
+func (c *RdsClient) CreateInstance(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) error {
+	// validate params
+	if err := validCreateInstanceParams(node, params); err != nil {
+		return err
+	}
+
+	storage, err := strconv.ParseInt(params["allocatedStorage"], 10, 64)
+	if err != nil {
+		return fmt.Errorf("allocated storage is not a number: %s", err.Error())
+	}
+
+	instance := c.Instance()
+	instance.SetEngine(params["engine"]).
+		SetEngineVersion(params["engineVersion"]).
+		SetDBInstanceClass(params["instanceClass"]).
+		SetDBInstanceIdentifier(node.Annotations[dbmeshv1alpha1.AnnotationsInstanceIdentifier]).
+		SetMasterUsername(params["masterUsername"]).
+		SetMasterUserPassword(params["masterUserPassword"]).
+		SetAllocatedStorage(int32(storage))
+	return instance.Create(ctx)
+}
+
+func (c *RdsClient) GetInstance(ctx context.Context, node *v1alpha1.StorageNode) (*rds.DescInstance, error) {
+	identifier, ok := node.Annotations[dbmeshv1alpha1.AnnotationsInstanceIdentifier]
+	if !ok {
+		return nil, errors.New("instance identifier is empty")
+	}
+	instance := c.Instance()
+	instance.SetDBInstanceIdentifier(identifier)
+	return instance.Describe(ctx)
+}
+
+// DeleteInstance delete rds instance.
+// aws rds instance status doc: https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/accessing-monitoring.html
+func (c *RdsClient) DeleteInstance(ctx context.Context, node *v1alpha1.StorageNode, databaseClass *dbmeshv1alpha1.DatabaseClass) error {
+	// TODO add more test case.
+	/* TODO set options to skip final snapshot and backup stuff depends on database class ClaimPolicy.
+	"error": "operation error RDS: DeleteDBInstance,
+	https response error StatusCode: 400,
+	RequestID: ae094e3c-d8f1-49ba-aed1-cb0618b3641d,
+	api error InvalidParameterCombination:
+	FinalDBSnapshotIdentifier is required unless SkipFinalSnapshot is specified."
+	*/
+
+	identifier, ok := node.Annotations[dbmeshv1alpha1.AnnotationsInstanceIdentifier]
+	if !ok {
+		return errors.New("instance identifier is empty")
+	}
+
+	instance := c.Instance()
+	instance.SetDBInstanceIdentifier(identifier)
+
+	// check instance status first
+	ins, err := c.GetInstance(ctx, node)
+	if err != nil {
+		return err
+	}
+	if ins == nil || ins.DBInstanceStatus == "deleting" {
+		return nil
+	}
+
+	instance.SetDeleteAutomateBackups(true)
+	instance.SetSkipFinalSnapshot(true)
+	return instance.Delete(ctx)
+}
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance_test.go b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance_test.go
new file mode 100644
index 0000000..2af44ab
--- /dev/null
+++ b/shardingsphere-operator/pkg/reconcile/storagenode/aws/rdsinstance_test.go
@@ -0,0 +1,53 @@
+/*
+ * 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 aws
+
+import (
+	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
+	dbmeshv1alpha1 "github.com/database-mesh/golang-sdk/kubernetes/api/v1alpha1"
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// test validCreateInstanceParams with ginkgo and gomega.
+var _ = Describe("validCreateInstanceParams", func() {
+	Context("validCreateInstanceParams", func() {
+		node := &v1alpha1.StorageNode{
+			ObjectMeta: metav1.ObjectMeta{
+				Name:        "test-instance",
+				Namespace:   "test-namespace",
+				Annotations: map[string]string{},
+			},
+		}
+
+		It("should return true", func() {
+			params := map[string]string{
+				"instanceClass":      "db.t3.micro",
+				"engine":             "mysql",
+				"engineVersion":      "5.7",
+				"masterUsername":     "root",
+				"masterUserPassword": "root123456",
+				"allocatedStorage":   "20",
+			}
+
+			node.Annotations[dbmeshv1alpha1.AnnotationsInstanceIdentifier] = "test-instance"
+			Expect(validCreateInstanceParams(node, params)).To(BeNil())
+		})
+	})
+})
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora.go b/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora.go
deleted file mode 100644
index a8abbf8..0000000
--- a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora.go
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
-* 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 awsaurora
-
-import (
-	"context"
-	"errors"
-	"strings"
-
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode"
-	"github.com/database-mesh/golang-sdk/aws/client/rds"
-)
-
-const (
-	AnnoUsername            = "shardingsphere.apache.org/storagenode-aws-aurora-username"
-	AnnoPassword            = "shardingsphere.apache.org/storagenode-aws-aurora-password"
-	AnnoVpcSecurityGroupIds = "shardingsphere.apache.org/storagenode-aws-aurora-vpcSecurityGroupIds"
-	AnnoSubnetGroupName     = "shardingsphere.apache.org/storagenode-aws-aurora-subnetGroupName"
-	AnnoDBClusterIdentifier = "shardingsphere.apache.org/storagenode-aws-aurora-dbClusterIdentifier"
-)
-
-type AwsAurora struct {
-	aurora rds.Aurora
-}
-
-func New(rds rds.RDS) storagenode.IDBClusterClient {
-	return &AwsAurora{aurora: rds.Aurora()}
-}
-
-// IsValid validate the parameters in annotation for aws aurora
-// required parameters:
-// - username
-// - password
-// - vpcSecurityGroupIds
-// - subnetGroupName
-// - dbClusterIdentifier
-func (a *AwsAurora) IsValid(node *v1alpha1.StorageNode) error {
-	var errMsg []string
-	if node.Annotations[AnnoUsername] == "" {
-		errMsg = append(errMsg, "username is required")
-	}
-	if node.Annotations[AnnoPassword] == "" {
-		errMsg = append(errMsg, "password is required")
-	}
-	if node.Annotations[AnnoVpcSecurityGroupIds] == "" {
-		errMsg = append(errMsg, "vpcSecurityGroupIds is required")
-	}
-	if node.Annotations[AnnoSubnetGroupName] == "" {
-		errMsg = append(errMsg, "subnetGroupName is required")
-	}
-	if node.Annotations[AnnoDBClusterIdentifier] == "" {
-		errMsg = append(errMsg, "dbClusterIdentifier is required")
-	}
-
-	if len(errMsg) > 0 {
-		return errors.New(strings.Join(errMsg, "\n"))
-	}
-	return nil
-}
-
-func (a *AwsAurora) GetCluster(ctx context.Context, node *v1alpha1.StorageNode) (cluster *storagenode.DatabaseCluster, err error) {
-	if node.Status.Cluster.Properties == nil || node.Status.Cluster.Properties["clusterIdentifier"] == "" {
-		// cluster not created
-		return nil, nil
-	}
-
-	//cluster, err := a.aurora.DescribeDBClusters(ctx, node.Status.Cluster.Properties["ClusterIdentifier"])
-	//if err != nil {
-	//	return nil, err
-	//}
-
-	return cluster, nil
-}
-
-func (a *AwsAurora) CreateCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) (cluster *storagenode.DatabaseCluster, err error) {
-	err = a.aurora.Create(ctx)
-	if err != nil {
-		return nil, err
-	}
-	return nil, nil
-}
-
-func (a *AwsAurora) DeleteCluster(ctx context.Context, node *v1alpha1.StorageNode) error {
-	//TODO implement me
-	panic("implement me")
-}
-
-func (a *AwsAurora) GetInstances(ctx context.Context, cluster *storagenode.DatabaseCluster) ([]*storagenode.DatabaseInstance, error) {
-	//TODO implement me
-	panic("implement me")
-}
-
-func (a *AwsAurora) CreateInstance(ctx context.Context) error {
-	//TODO implement me
-	panic("implement me")
-}
-
-func (a *AwsAurora) DeleteInstance(ctx context.Context) error {
-	//TODO implement me
-	panic("implement me")
-}
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_suite_test.go b/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_suite_test.go
deleted file mode 100644
index 355b230..0000000
--- a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_suite_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* 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 awsaurora_test
-
-import (
-	"testing"
-
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-)
-
-func TestAwsaurora(t *testing.T) {
-	RegisterFailHandler(Fail)
-	RunSpecs(t, "Awsaurora Suite")
-}
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_test.go b/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_test.go
deleted file mode 100644
index a286bdc..0000000
--- a/shardingsphere-operator/pkg/reconcile/storagenode/awsaurora/awsaurora_test.go
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
-* 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 awsaurora
-
-import (
-	"github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
-	. "github.com/onsi/ginkgo/v2"
-	. "github.com/onsi/gomega"
-	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-var _ = Describe("Awsaurora", func() {
-	Context("IsValid", func() {
-		node := &v1alpha1.StorageNode{
-			ObjectMeta: metav1.ObjectMeta{
-				Name:        "test-storage-node",
-				Namespace:   "test-namespace",
-				Annotations: map[string]string{},
-			},
-			Spec: v1alpha1.StorageNodeSpec{
-				DatabaseClassName: "aws-aurora",
-			},
-		}
-
-		It("username empty", func() {
-			aurora := AwsAurora{}
-			err := aurora.IsValid(node)
-			Expect(err).To(HaveOccurred())
-			// username
-			Expect(err.Error()).To(ContainSubstring("username is required"))
-			// password
-			Expect(err.Error()).To(ContainSubstring("password is required"))
-			// vpcSecurityGroupIds
-			Expect(err.Error()).To(ContainSubstring("vpcSecurityGroupIds is required"))
-			// subnetGroupName
-			Expect(err.Error()).To(ContainSubstring("subnetGroupName is required"))
-			// dbClusterIdentifier
-			Expect(err.Error()).To(ContainSubstring("dbClusterIdentifier is required"))
-		})
-		It("password empty", func() {
-			aurora := AwsAurora{}
-			node.Annotations[AnnoUsername] = "username"
-			err := aurora.IsValid(node)
-			Expect(err).To(HaveOccurred())
-			Expect(err.Error()).To(ContainSubstring("password is required"))
-			// vpcSecurityGroupIds
-			Expect(err.Error()).To(ContainSubstring("vpcSecurityGroupIds is required"))
-			// subnetGroupName
-			Expect(err.Error()).To(ContainSubstring("subnetGroupName is required"))
-			// dbClusterIdentifier
-			Expect(err.Error()).To(ContainSubstring("dbClusterIdentifier is required"))
-		})
-		It("vpcSecurityGroupIds empty", func() {
-			aurora := AwsAurora{}
-			node.Annotations[AnnoUsername] = "username"
-			node.Annotations[AnnoPassword] = "password"
-			err := aurora.IsValid(node)
-			Expect(err).To(HaveOccurred())
-			Expect(err.Error()).To(ContainSubstring("vpcSecurityGroupIds is required"))
-			// subnetGroupName
-			Expect(err.Error()).To(ContainSubstring("subnetGroupName is required"))
-			// dbClusterIdentifier
-			Expect(err.Error()).To(ContainSubstring("dbClusterIdentifier is required"))
-		})
-		It("subnetGroupName empty", func() {
-			aurora := AwsAurora{}
-			node.Annotations[AnnoUsername] = "username"
-			node.Annotations[AnnoPassword] = "password"
-			node.Annotations[AnnoVpcSecurityGroupIds] = "vpcSecurityGroupIds"
-			err := aurora.IsValid(node)
-			Expect(err).To(HaveOccurred())
-			Expect(err.Error()).To(ContainSubstring("subnetGroupName is required"))
-			// dbClusterIdentifier
-			Expect(err.Error()).To(ContainSubstring("dbClusterIdentifier is required"))
-		})
-		It("dbClusterIdentifier empty", func() {
-			aurora := AwsAurora{}
-			node.Annotations[AnnoUsername] = "username"
-			node.Annotations[AnnoPassword] = "password"
-			node.Annotations[AnnoVpcSecurityGroupIds] = "vpcSecurityGroupIds"
-			node.Annotations[AnnoSubnetGroupName] = "subnetGroupName"
-			err := aurora.IsValid(node)
-			Expect(err).To(HaveOccurred())
-			Expect(err.Error()).To(ContainSubstring("dbClusterIdentifier is required"))
-		})
-		It("all required fields are set", func() {
-			aurora := AwsAurora{}
-			node.Annotations[AnnoUsername] = "username"
-			node.Annotations[AnnoPassword] = "password"
-			node.Annotations[AnnoVpcSecurityGroupIds] = "vpcSecurityGroupIds"
-			node.Annotations[AnnoSubnetGroupName] = "subnetGroupName"
-			node.Annotations[AnnoDBClusterIdentifier] = "dbClusterIdentifier"
-			err := aurora.IsValid(node)
-			Expect(err).ToNot(HaveOccurred())
-		})
-
-	})
-})
diff --git a/shardingsphere-operator/pkg/reconcile/storagenode/mocks/storagenode.go b/shardingsphere-operator/pkg/reconcile/storagenode/mocks/storagenode.go
deleted file mode 100644
index 54a635c..0000000
--- a/shardingsphere-operator/pkg/reconcile/storagenode/mocks/storagenode.go
+++ /dev/null
@@ -1,138 +0,0 @@
-// Code generated by MockGen. DO NOT EDIT.
-// Source: storagenode.go
-
-// Package mock_storagenode is a generated GoMock package.
-package mock_storagenode
-
-import (
-	context "context"
-	reflect "reflect"
-
-	v1alpha1 "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/api/v1alpha1"
-	storagenode "github.com/apache/shardingsphere-on-cloud/shardingsphere-operator/pkg/reconcile/storagenode"
-	gomock "github.com/golang/mock/gomock"
-)
-
-// MockIDBClusterClient is a mock of IDBClusterClient interface.
-type MockIDBClusterClient struct {
-	ctrl     *gomock.Controller
-	recorder *MockIDBClusterClientMockRecorder
-}
-
-// MockIDBClusterClientMockRecorder is the mock recorder for MockIDBClusterClient.
-type MockIDBClusterClientMockRecorder struct {
-	mock *MockIDBClusterClient
-}
-
-// NewMockIDBClusterClient creates a new mock instance.
-func NewMockIDBClusterClient(ctrl *gomock.Controller) *MockIDBClusterClient {
-	mock := &MockIDBClusterClient{ctrl: ctrl}
-	mock.recorder = &MockIDBClusterClientMockRecorder{mock}
-	return mock
-}
-
-// EXPECT returns an object that allows the caller to indicate expected use.
-func (m *MockIDBClusterClient) EXPECT() *MockIDBClusterClientMockRecorder {
-	return m.recorder
-}
-
-// CreateCluster mocks base method.
-func (m *MockIDBClusterClient) CreateCluster(ctx context.Context, node *v1alpha1.StorageNode, params map[string]string) (*storagenode.DatabaseCluster, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CreateCluster", ctx, node, params)
-	ret0, _ := ret[0].(*storagenode.DatabaseCluster)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// CreateCluster indicates an expected call of CreateCluster.
-func (mr *MockIDBClusterClientMockRecorder) CreateCluster(ctx, node, params interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateCluster", reflect.TypeOf((*MockIDBClusterClient)(nil).CreateCluster), ctx, node, params)
-}
-
-// CreateInstance mocks base method.
-func (m *MockIDBClusterClient) CreateInstance(ctx context.Context) error {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "CreateInstance", ctx)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// CreateInstance indicates an expected call of CreateInstance.
-func (mr *MockIDBClusterClientMockRecorder) CreateInstance(ctx interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateInstance", reflect.TypeOf((*MockIDBClusterClient)(nil).CreateInstance), ctx)
-}
-
-// DeleteCluster mocks base method.
-func (m *MockIDBClusterClient) DeleteCluster(ctx context.Context, node *v1alpha1.StorageNode) error {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteCluster", ctx, node)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// DeleteCluster indicates an expected call of DeleteCluster.
-func (mr *MockIDBClusterClientMockRecorder) DeleteCluster(ctx, node interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteCluster", reflect.TypeOf((*MockIDBClusterClient)(nil).DeleteCluster), ctx, node)
-}
-
-// DeleteInstance mocks base method.
-func (m *MockIDBClusterClient) DeleteInstance(ctx context.Context) error {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "DeleteInstance", ctx)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// DeleteInstance indicates an expected call of DeleteInstance.
-func (mr *MockIDBClusterClientMockRecorder) DeleteInstance(ctx interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteInstance", reflect.TypeOf((*MockIDBClusterClient)(nil).DeleteInstance), ctx)
-}
-
-// GetCluster mocks base method.
-func (m *MockIDBClusterClient) GetCluster(ctx context.Context, node *v1alpha1.StorageNode) (*storagenode.DatabaseCluster, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetCluster", ctx, node)
-	ret0, _ := ret[0].(*storagenode.DatabaseCluster)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetCluster indicates an expected call of GetCluster.
-func (mr *MockIDBClusterClientMockRecorder) GetCluster(ctx, node interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetCluster", reflect.TypeOf((*MockIDBClusterClient)(nil).GetCluster), ctx, node)
-}
-
-// GetInstances mocks base method.
-func (m *MockIDBClusterClient) GetInstances(ctx context.Context, cluster *storagenode.DatabaseCluster) ([]*storagenode.DatabaseInstance, error) {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "GetInstances", ctx, cluster)
-	ret0, _ := ret[0].([]*storagenode.DatabaseInstance)
-	ret1, _ := ret[1].(error)
-	return ret0, ret1
-}
-
-// GetInstances indicates an expected call of GetInstances.
-func (mr *MockIDBClusterClientMockRecorder) GetInstances(ctx, cluster interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetInstances", reflect.TypeOf((*MockIDBClusterClient)(nil).GetInstances), ctx, cluster)
-}
-
-// IsValid mocks base method.
-func (m *MockIDBClusterClient) IsValid(node *v1alpha1.StorageNode) error {
-	m.ctrl.T.Helper()
-	ret := m.ctrl.Call(m, "IsValid", node)
-	ret0, _ := ret[0].(error)
-	return ret0
-}
-
-// IsValid indicates an expected call of IsValid.
-func (mr *MockIDBClusterClientMockRecorder) IsValid(node interface{}) *gomock.Call {
-	mr.mock.ctrl.T.Helper()
-	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsValid", reflect.TypeOf((*MockIDBClusterClient)(nil).IsValid), node)
-}