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)
-}