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

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

commit 8d4bedc57b55bfd7e2ba9b166e20cb30282ad404
Author: Ghoul_Lee <[email protected]>
AuthorDate: Mon Apr 18 23:43:45 2022 +0800

    Create ProxyConfig CRD Resource. (#3)
    
    * ADD: Init ProxyConfig CRD Resources
    
    * ADD: Convert ProxyConfig spec content to yaml format && apply resources 
to Kubernetes
    
    * ADD: add ProxyConfig CRD sample;
    UPDATE: optimize ProxyConfig Controller logic;Update ProxyConfig status to 
show what cluster type  now is
    
    * FIX: export RepositoryConfig
    UPDATE: change serverConfig struct location
---
 PROJECT                                            |   9 ++
 api/v1alpha1/proxyconfig_types.go                  |  67 ++++++++++
 api/v1alpha1/serverconfig.go                       |  65 +++++++++
 api/v1alpha1/zz_generated.deepcopy.go              |  89 +++++++++++++
 .../shardingsphere.sphere-ex.com_proxyconfigs.yaml | 148 +++++++++++++++++++++
 config/crd/kustomization.yaml                      |   5 +-
 .../crd/patches/cainjection_in_proxyconfigs.yaml   |   7 +
 config/crd/patches/webhook_in_proxyconfigs.yaml    |  16 +++
 config/rbac/proxyconfig_editor_role.yaml           |  24 ++++
 config/rbac/proxyconfig_viewer_role.yaml           |  20 +++
 config/rbac/role.yaml                              |  26 ++++
 config/samples/shardingsphere_v1alpha1_proxy.yaml  |   1 +
 .../shardingsphere_v1alpha1_proxyconfig.yaml       |  27 ++++
 main.go                                            |   8 ++
 pkg/controllers/proxyconfig_controller.go          | 115 ++++++++++++++++
 pkg/reconcile/resource.go                          |  31 +++++
 16 files changed, 657 insertions(+), 1 deletion(-)

diff --git a/PROJECT b/PROJECT
index c933d7b..2fae1fe 100644
--- a/PROJECT
+++ b/PROJECT
@@ -13,4 +13,13 @@ resources:
   kind: Proxy
   path: sphere-ex.com/shardingsphere-operator/api/v1alpha1
   version: v1alpha1
+- api:
+    crdVersion: v1
+    namespaced: true
+  controller: true
+  domain: sphere-ex.com
+  group: shardingsphere
+  kind: ProxyConfig
+  path: sphere-ex.com/shardingsphere-operator/api/v1alpha1
+  version: v1alpha1
 version: "3"
diff --git a/api/v1alpha1/proxyconfig_types.go 
b/api/v1alpha1/proxyconfig_types.go
new file mode 100644
index 0000000..02108ad
--- /dev/null
+++ b/api/v1alpha1/proxyconfig_types.go
@@ -0,0 +1,67 @@
+/*
+Copyright 2022.
+
+Licensed 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 v1alpha1
+
+import (
+       metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
+// NOTE: json tags are required.  Any new fields you add must have json tags 
for the fields to be serialized.
+
+// ProxyConfigSpec defines the desired state of ProxyConfig
+type ProxyConfigSpec struct {
+       ClusterConfig ClusterConfig `json:"mode" yaml:"mode"`
+       Authority     Auth          `json:"authority" yaml:"authority"`
+       // +optional
+       Props Props `json:"props,omitempty" yaml:"props,omitempty"`
+}
+
+// ProxyConfigStatus defines the observed state of ProxyConfig
+type ProxyConfigStatus struct {
+       MetadataRepository string `json:"metadataRepository"`
+}
+
+//+kubebuilder:printcolumn:JSONPath=".status.metadataRepository",name=MetadataRepository,type=string
+//+kubebuilder:object:root=true
+//+kubebuilder:subresource:status
+
+// ProxyConfig is the Schema for the proxyconfigs API
+type ProxyConfig struct {
+       metav1.TypeMeta   `json:",inline"`
+       metav1.ObjectMeta `json:"metadata,omitempty"`
+
+       Spec   ProxyConfigSpec   `json:"spec,omitempty"`
+       Status ProxyConfigStatus `json:"status,omitempty"`
+}
+
+//+kubebuilder:object:root=true
+
+// ProxyConfigList contains a list of ProxyConfig
+type ProxyConfigList struct {
+       metav1.TypeMeta `json:",inline"`
+       metav1.ListMeta `json:"metadata,omitempty"`
+       Items           []ProxyConfig `json:"items"`
+}
+
+func init() {
+       SchemeBuilder.Register(&ProxyConfig{}, &ProxyConfigList{})
+}
+
+func (in *ProxyConfig) SetMetadataRepository(metadataType string) {
+       in.Status.MetadataRepository = metadataType
+}
diff --git a/api/v1alpha1/serverconfig.go b/api/v1alpha1/serverconfig.go
new file mode 100644
index 0000000..a2cb8d7
--- /dev/null
+++ b/api/v1alpha1/serverconfig.go
@@ -0,0 +1,65 @@
+package v1alpha1
+
+// User TODO: description
+type User struct {
+       // +optional
+       UserConfig string `json:"-" yaml:"user"`
+       UserName   string `json:"userName" yaml:"-"`
+       PassWord   string `json:"passWord" yaml:"-"`
+       // +optional
+       HostName string `json:"hostName,omitempty" yaml:"-"`
+}
+
+// Provider TODO: description
+type Provider struct {
+       Type string `json:"type" yaml:"type"`
+}
+
+// Auth TODO: description
+type Auth struct {
+       Users []User `json:"users" yaml:"users"`
+       // +optional
+       Provider Provider `json:"provider,omitempty"`
+}
+
+// Props TODO: description
+type Props struct {
+       // +optional
+       KernelExecutorSize int `json:"kernel-executor-size,omitempty" 
yaml:"kernel-executor-size"`
+       // +optional
+       CheckTableMetadataEnabled bool 
`json:"check-table-metadata-enabled,omitempty" 
yaml:"check-table-metadata-enabled"`
+       // +optional
+       ProxyBackendQueryFetchSize int 
`json:"proxy-backend-query-fetch-size,omitempty" 
yaml:"proxy-backend-query-fetch-size"`
+       // +optional
+       CheckDuplicateTableEnabled bool 
`json:"check-duplicate-table-enabled,omitempty" 
yaml:"check-duplicate-table-enabled"`
+       // +optional
+       ProxyFrontendExecutorSize int 
`json:"proxy-frontend-executor-size,omitempty" 
yaml:"proxy-frontend-executor-size"`
+       // +optional
+       ProxyBackendExecutorSuitable string 
`json:"proxy-backend-executor-suitable,omitempty" 
yaml:"proxy-backend-executor-suitable"`
+}
+
+type ClusterProps struct {
+       NameSpace   string `json:"namespace" yaml:"namespace"`
+       ServerLists string `json:"server-lists" yaml:"server-lists"`
+       // +optional
+       RetryIntervalMilliseconds int 
`json:"retryIntervalMilliseconds,omitempty" 
yaml:"retryIntervalMilliseconds,omitempty"`
+       // +optional
+       MaxRetries int `json:"maxRetries,omitempty" yaml:"maxRetries,omitempty"`
+       // +optional
+       TimeToLiveSeconds int `json:"timeToLiveSeconds,omitempty" 
yaml:"timeToLiveSeconds,omitempty"`
+       // +optional
+       OperationTimeoutMilliseconds int 
`json:"operationTimeoutMilliseconds,omitempty" 
yaml:"operationTimeoutMilliseconds,omitempty"`
+       // +optional
+       Digest string `json:"digest,omitempty" yaml:"digest,omitempty"`
+}
+
+type RepositoryConfig struct {
+       Type  string       `json:"type" yaml:"type"`
+       Props ClusterProps `json:"props" yaml:"props"`
+}
+
+type ClusterConfig struct {
+       Type       string           `json:"type" yaml:"type"`
+       Repository RepositoryConfig `json:"repository" yaml:"repository"`
+       Overwrite  bool             `json:"overwrite" yaml:"overwrite"`
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go 
b/api/v1alpha1/zz_generated.deepcopy.go
index 5a73331..77c82f2 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -105,6 +105,95 @@ func (in *Proxy) DeepCopyObject() runtime.Object {
        return nil
 }
 
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ProxyConfig) DeepCopyInto(out *ProxyConfig) {
+       *out = *in
+       out.TypeMeta = in.TypeMeta
+       in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+       out.Spec = in.Spec
+       out.Status = in.Status
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ProxyConfig.
+func (in *ProxyConfig) DeepCopy() *ProxyConfig {
+       if in == nil {
+               return nil
+       }
+       out := new(ProxyConfig)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, 
creating a new runtime.Object.
+func (in *ProxyConfig) DeepCopyObject() runtime.Object {
+       if c := in.DeepCopy(); c != nil {
+               return c
+       }
+       return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ProxyConfigList) DeepCopyInto(out *ProxyConfigList) {
+       *out = *in
+       out.TypeMeta = in.TypeMeta
+       in.ListMeta.DeepCopyInto(&out.ListMeta)
+       if in.Items != nil {
+               in, out := &in.Items, &out.Items
+               *out = make([]ProxyConfig, len(*in))
+               for i := range *in {
+                       (*in)[i].DeepCopyInto(&(*out)[i])
+               }
+       }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ProxyConfigList.
+func (in *ProxyConfigList) DeepCopy() *ProxyConfigList {
+       if in == nil {
+               return nil
+       }
+       out := new(ProxyConfigList)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, 
creating a new runtime.Object.
+func (in *ProxyConfigList) DeepCopyObject() runtime.Object {
+       if c := in.DeepCopy(); c != nil {
+               return c
+       }
+       return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ProxyConfigSpec) DeepCopyInto(out *ProxyConfigSpec) {
+       *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ProxyConfigSpec.
+func (in *ProxyConfigSpec) DeepCopy() *ProxyConfigSpec {
+       if in == nil {
+               return nil
+       }
+       out := new(ProxyConfigSpec)
+       in.DeepCopyInto(out)
+       return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
+func (in *ProxyConfigStatus) DeepCopyInto(out *ProxyConfigStatus) {
+       *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, 
creating a new ProxyConfigStatus.
+func (in *ProxyConfigStatus) DeepCopy() *ProxyConfigStatus {
+       if in == nil {
+               return nil
+       }
+       out := new(ProxyConfigStatus)
+       in.DeepCopyInto(out)
+       return out
+}
+
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, 
writing into out. in must be non-nil.
 func (in *ProxyList) DeepCopyInto(out *ProxyList) {
        *out = *in
diff --git a/config/crd/bases/shardingsphere.sphere-ex.com_proxyconfigs.yaml 
b/config/crd/bases/shardingsphere.sphere-ex.com_proxyconfigs.yaml
new file mode 100644
index 0000000..3536493
--- /dev/null
+++ b/config/crd/bases/shardingsphere.sphere-ex.com_proxyconfigs.yaml
@@ -0,0 +1,148 @@
+---
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    controller-gen.kubebuilder.io/version: v0.8.0
+  creationTimestamp: null
+  name: proxyconfigs.shardingsphere.sphere-ex.com
+spec:
+  group: shardingsphere.sphere-ex.com
+  names:
+    kind: ProxyConfig
+    listKind: ProxyConfigList
+    plural: proxyconfigs
+    singular: proxyconfig
+  scope: Namespaced
+  versions:
+  - additionalPrinterColumns:
+    - jsonPath: .status.metadataRepository
+      name: MetadataRepository
+      type: string
+    name: v1alpha1
+    schema:
+      openAPIV3Schema:
+        description: ProxyConfig is the Schema for the proxyconfigs API
+        properties:
+          apiVersion:
+            description: 'APIVersion defines the versioned schema of this 
representation
+              of an object. Servers should convert recognized schemas to the 
latest
+              internal value, and may reject unrecognized values. More info: 
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+            type: string
+          kind:
+            description: 'Kind is a string value representing the REST 
resource this
+              object represents. Servers may infer this from the endpoint the 
client
+              submits requests to. Cannot be updated. In CamelCase. More info: 
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+            type: string
+          metadata:
+            type: object
+          spec:
+            description: ProxyConfigSpec defines the desired state of 
ProxyConfig
+            properties:
+              AUTHORITY:
+                description: 'Auth TODO: description'
+                properties:
+                  provider:
+                    description: 'Provider TODO: description'
+                    properties:
+                      type:
+                        type: string
+                    required:
+                    - type
+                    type: object
+                  users:
+                    items:
+                      description: 'User TODO: description'
+                      properties:
+                        hostName:
+                          type: string
+                        passWord:
+                          type: string
+                        userName:
+                          type: string
+                      required:
+                      - passWord
+                      - userName
+                      type: object
+                    type: array
+                required:
+                - users
+                type: object
+              mode:
+                properties:
+                  overwrite:
+                    type: boolean
+                  repository:
+                    properties:
+                      props:
+                        properties:
+                          digest:
+                            type: string
+                          maxRetries:
+                            type: integer
+                          namespace:
+                            type: string
+                          operationTimeoutMilliseconds:
+                            type: integer
+                          retryIntervalMilliseconds:
+                            type: integer
+                          server-lists:
+                            type: string
+                          timeToLiveSeconds:
+                            type: integer
+                        required:
+                        - namespace
+                        - server-lists
+                        type: object
+                      type:
+                        type: string
+                    required:
+                    - props
+                    - type
+                    type: object
+                  type:
+                    type: string
+                required:
+                - overwrite
+                - repository
+                - type
+                type: object
+              props:
+                description: 'Props TODO: description'
+                properties:
+                  check-duplicate-table-enabled:
+                    type: boolean
+                  check-table-metadata-enabled:
+                    type: boolean
+                  kernel-executor-size:
+                    type: integer
+                  proxy-backend-executor-suitable:
+                    type: string
+                  proxy-backend-query-fetch-size:
+                    type: integer
+                  proxy-frontend-executor-size:
+                    type: integer
+                type: object
+            required:
+            - AUTHORITY
+            - mode
+            type: object
+          status:
+            description: ProxyConfigStatus defines the observed state of 
ProxyConfig
+            properties:
+              metadataRepository:
+                type: string
+            required:
+            - metadataRepository
+            type: object
+        type: object
+    served: true
+    storage: true
+    subresources:
+      status: {}
+status:
+  acceptedNames:
+    kind: ""
+    plural: ""
+  conditions: []
+  storedVersions: []
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 6738560..704404b 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -2,18 +2,21 @@
 # since it depends on service name and namespace that are out of this 
kustomize package.
 # It should be run by config/default
 resources:
-- bases/shardingsphere.sphere-ex.com_proxies.yaml.bak
+- bases/shardingsphere.sphere-ex.com_proxies.yaml
+- bases/shardingsphere.sphere-ex.com_proxyconfigs.yaml
 #+kubebuilder:scaffold:crdkustomizeresource
 
 patchesStrategicMerge:
 # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] 
prefix.
 # patches here are for enabling the conversion webhook for each CRD
 #- patches/webhook_in_proxies.yaml
+#- patches/webhook_in_proxyconfigs.yaml
 #+kubebuilder:scaffold:crdkustomizewebhookpatch
 
 # [CERTMANAGER] To enable cert-manager, uncomment all the sections with 
[CERTMANAGER] prefix.
 # patches here are for enabling the CA injection for each CRD
 #- patches/cainjection_in_proxies.yaml
+#- patches/cainjection_in_proxyconfigs.yaml
 #+kubebuilder:scaffold:crdkustomizecainjectionpatch
 
 # the following config is for teaching kustomize how to do kustomization for 
CRDs.
diff --git a/config/crd/patches/cainjection_in_proxyconfigs.yaml 
b/config/crd/patches/cainjection_in_proxyconfigs.yaml
new file mode 100644
index 0000000..3f189ca
--- /dev/null
+++ b/config/crd/patches/cainjection_in_proxyconfigs.yaml
@@ -0,0 +1,7 @@
+# The following patch adds a directive for certmanager to inject CA into the 
CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  annotations:
+    cert-manager.io/inject-ca-from: 
$(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+  name: proxyconfigs.shardingsphere.sphere-ex.com
diff --git a/config/crd/patches/webhook_in_proxyconfigs.yaml 
b/config/crd/patches/webhook_in_proxyconfigs.yaml
new file mode 100644
index 0000000..8f80f69
--- /dev/null
+++ b/config/crd/patches/webhook_in_proxyconfigs.yaml
@@ -0,0 +1,16 @@
+# The following patch enables a conversion webhook for the CRD
+apiVersion: apiextensions.k8s.io/v1
+kind: CustomResourceDefinition
+metadata:
+  name: proxyconfigs.shardingsphere.sphere-ex.com
+spec:
+  conversion:
+    strategy: Webhook
+    webhook:
+      clientConfig:
+        service:
+          namespace: system
+          name: webhook-service
+          path: /convert
+      conversionReviewVersions:
+      - v1
diff --git a/config/rbac/proxyconfig_editor_role.yaml 
b/config/rbac/proxyconfig_editor_role.yaml
new file mode 100644
index 0000000..94b6bd8
--- /dev/null
+++ b/config/rbac/proxyconfig_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit proxyconfigs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: proxyconfig-editor-role
+rules:
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - update
+  - watch
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs/status
+  verbs:
+  - get
diff --git a/config/rbac/proxyconfig_viewer_role.yaml 
b/config/rbac/proxyconfig_viewer_role.yaml
new file mode 100644
index 0000000..759bf01
--- /dev/null
+++ b/config/rbac/proxyconfig_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view proxyconfigs.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+  name: proxyconfig-viewer-role
+rules:
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs
+  verbs:
+  - get
+  - list
+  - watch
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs/status
+  verbs:
+  - get
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index db72e1e..b2711b0 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -70,3 +70,29 @@ rules:
   - get
   - patch
   - update
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs
+  verbs:
+  - create
+  - delete
+  - get
+  - list
+  - patch
+  - update
+  - watch
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs/finalizers
+  verbs:
+  - update
+- apiGroups:
+  - shardingsphere.sphere-ex.com
+  resources:
+  - proxyconfigs/status
+  verbs:
+  - get
+  - patch
+  - update
diff --git a/config/samples/shardingsphere_v1alpha1_proxy.yaml 
b/config/samples/shardingsphere_v1alpha1_proxy.yaml
index d3c7fdf..61a1776 100644
--- a/config/samples/shardingsphere_v1alpha1_proxy.yaml
+++ b/config/samples/shardingsphere_v1alpha1_proxy.yaml
@@ -8,6 +8,7 @@ spec:
     type: ClusterIP
   replicas: 1
   proxyConfigName: "sharding-proxy"
+  port: 3307
   mySQLDriver:
     version: "5.1.47"
   resource:
diff --git a/config/samples/shardingsphere_v1alpha1_proxyconfig.yaml 
b/config/samples/shardingsphere_v1alpha1_proxyconfig.yaml
new file mode 100644
index 0000000..6b18c59
--- /dev/null
+++ b/config/samples/shardingsphere_v1alpha1_proxyconfig.yaml
@@ -0,0 +1,27 @@
+apiVersion: shardingsphere.sphere-ex.com/v1alpha1
+kind: ProxyConfig
+metadata:
+  name: proxyconfig-sample
+spec:
+  AUTHORITY:
+    users:
+      - userName: root
+        passWord: root
+        hostName: "%"
+      - userName: admin
+        passWord: root
+        hostName: "%"
+    provider:
+      type: ALL_PRIVILEGES_PERMITTED
+  mode:
+    type: Cluster
+    repository:
+      type: ZooKeeper
+      props:
+        namespace: "governance_ds"
+        server-lists: "zookeeper.default:2181"
+        retryIntervalMilliseconds: 500
+        timeToLiveSeconds: 600
+        maxRetries: 3
+        operationTimeoutMilliseconds: 5000
+    overwrite: false
\ No newline at end of file
diff --git a/main.go b/main.go
index 016fb80..d2ece79 100644
--- a/main.go
+++ b/main.go
@@ -19,6 +19,7 @@ package main
 import (
        "flag"
        "os"
+
        "sphere-ex.com/shardingsphere-operator/pkg/controllers"
 
        // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, 
etc.)
@@ -85,6 +86,13 @@ func main() {
                setupLog.Error(err, "unable to create controller", 
"controller", "Proxy")
                os.Exit(1)
        }
+       if err = (&controllers.ProxyConfigReconciler{
+               Client: mgr.GetClient(),
+               Scheme: mgr.GetScheme(),
+       }).SetupWithManager(mgr); err != nil {
+               setupLog.Error(err, "unable to create controller", 
"controller", "ProxyConfig")
+               os.Exit(1)
+       }
        //+kubebuilder:scaffold:builder
 
        if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
diff --git a/pkg/controllers/proxyconfig_controller.go 
b/pkg/controllers/proxyconfig_controller.go
new file mode 100644
index 0000000..043087a
--- /dev/null
+++ b/pkg/controllers/proxyconfig_controller.go
@@ -0,0 +1,115 @@
+/*
+Copyright 2022.
+
+Licensed 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 controllers
+
+import (
+       "context"
+       v1 "k8s.io/api/core/v1"
+       "k8s.io/apimachinery/pkg/api/equality"
+       apierrors "k8s.io/apimachinery/pkg/api/errors"
+       "sphere-ex.com/shardingsphere-operator/pkg/reconcile"
+
+       "k8s.io/apimachinery/pkg/runtime"
+       ctrl "sigs.k8s.io/controller-runtime"
+       "sigs.k8s.io/controller-runtime/pkg/client"
+       logger "sigs.k8s.io/controller-runtime/pkg/log"
+
+       shardingspherev1alpha1 
"sphere-ex.com/shardingsphere-operator/api/v1alpha1"
+)
+
+// ProxyConfigReconciler reconciles a ProxyConfig object
+type ProxyConfigReconciler struct {
+       client.Client
+       Scheme *runtime.Scheme
+}
+
+//+kubebuilder:rbac:groups=shardingsphere.sphere-ex.com,resources=proxyconfigs,verbs=get;list;watch;create;update;patch;delete
+//+kubebuilder:rbac:groups=shardingsphere.sphere-ex.com,resources=proxyconfigs/status,verbs=get;update;patch
+//+kubebuilder:rbac:groups=shardingsphere.sphere-ex.com,resources=proxyconfigs/finalizers,verbs=update
+
+// Reconcile is part of the main kubernetes reconciliation loop which aims to
+// move the current state of the cluster closer to the desired state.
+// TODO(user): Modify the Reconcile function to compare the state specified by
+// the ProxyConfig object against the actual cluster state, and then
+// perform operations to make the cluster state reflect the state specified by
+// the user.
+//
+// For more details, check Reconcile and its Result here:
+// - https://pkg.go.dev/sigs.k8s.io/[email protected]/pkg/reconcile
+func (r *ProxyConfigReconciler) Reconcile(ctx context.Context, req 
ctrl.Request) (ctrl.Result, error) {
+       log := logger.FromContext(ctx)
+
+       run := &shardingspherev1alpha1.ProxyConfig{}
+       err := r.Get(ctx, req.NamespacedName, run)
+       if apierrors.IsNotFound(err) {
+               log.Error(err, "ProxyConfig in work queue no longer exists!")
+               return ctrl.Result{}, nil
+       } else if err != nil {
+               log.Error(err, "Get CRD Resource Error")
+               return ctrl.Result{RequeueAfter: SyncBuildStatusInterval}, err
+       }
+
+       cm := &v1.ConfigMap{}
+       configmap := reconcile.ConstructCascadingConfigmap(run)
+       err = r.Get(ctx, req.NamespacedName, cm)
+       if err != nil {
+               if apierrors.IsNotFound(err) {
+                       log.Info("Create the configmap")
+                       err = r.Create(ctx, configmap)
+                       if err != nil {
+                               log.Error(err, "Create Configmap Resource 
Error")
+                               return ctrl.Result{RequeueAfter: 
SyncBuildStatusInterval}, err
+                       }
+                       
run.SetMetadataRepository(run.Spec.ClusterConfig.Repository.Type)
+                       err = r.Status().Update(ctx, run)
+                       if err != nil {
+                               log.Error(err, "Update CRD Resource Status 
Error")
+                               return ctrl.Result{RequeueAfter: 
SyncBuildStatusInterval}, err
+                       }
+                       return ctrl.Result{}, nil
+               } else {
+                       log.Error(err, "Get Configmap Resource Error")
+                       return ctrl.Result{RequeueAfter: 
SyncBuildStatusInterval}, err
+               }
+       }
+       if !equality.Semantic.DeepEqual(configmap.Data, cm.Data) {
+               cm = configmap
+               log.Info("Update or correct the configmap")
+               err = r.Update(ctx, configmap)
+               if err != nil {
+                       log.Error(err, "Update Configmap Resource Error")
+                       return ctrl.Result{RequeueAfter: 
SyncBuildStatusInterval}, err
+               }
+       }
+       if run.Status.MetadataRepository != 
run.Spec.ClusterConfig.Repository.Type || run.Status.MetadataRepository == "" {
+               
run.SetMetadataRepository(run.Spec.ClusterConfig.Repository.Type)
+               err = r.Status().Update(ctx, run)
+               if err != nil {
+                       log.Error(err, "Update CRD Resource Status Error")
+                       return ctrl.Result{RequeueAfter: 
SyncBuildStatusInterval}, err
+               }
+       }
+       return ctrl.Result{}, nil
+}
+
+// SetupWithManager sets up the controller with the Manager.
+func (r *ProxyConfigReconciler) SetupWithManager(mgr ctrl.Manager) error {
+       return ctrl.NewControllerManagedBy(mgr).
+               For(&shardingspherev1alpha1.ProxyConfig{}).
+               Owns(&v1.ConfigMap{}).
+               Complete(r)
+}
diff --git a/pkg/reconcile/resource.go b/pkg/reconcile/resource.go
index 9d46f76..5f4cc04 100644
--- a/pkg/reconcile/resource.go
+++ b/pkg/reconcile/resource.go
@@ -2,6 +2,7 @@ package reconcile
 
 import (
        "fmt"
+       "gopkg.in/yaml.v2"
        "html/template"
        appsv1 "k8s.io/api/apps/v1"
        v1 "k8s.io/api/core/v1"
@@ -211,3 +212,33 @@ func processOptionalParameter(proxy 
*shardingspherev1alpha1.Proxy, dp *appsv1.De
        }
        return dp
 }
+
+// ConstructCascadingConfigmap Construct spec resources to Configmap
+func ConstructCascadingConfigmap(proxyConfig 
*shardingspherev1alpha1.ProxyConfig) *v1.ConfigMap {
+       y := toYaml(proxyConfig)
+       return &v1.ConfigMap{
+               ObjectMeta: metav1.ObjectMeta{
+                       Name:      proxyConfig.Name,
+                       Namespace: proxyConfig.Namespace,
+                       OwnerReferences: []metav1.OwnerReference{
+                               
*metav1.NewControllerRef(proxyConfig.GetObjectMeta(), 
proxyConfig.GroupVersionKind()),
+                       },
+               },
+               Data: map[string]string{
+                       "server.yaml": y,
+               },
+       }
+
+}
+
+// ToYaml Convert ProxyConfig spec content to yaml format
+func toYaml(proxyConfig *shardingspherev1alpha1.ProxyConfig) string {
+
+       for i := 0; i < len(proxyConfig.Spec.AUTHORITY.Users); i++ {
+               proxyConfig.Spec.AUTHORITY.Users[i].UserConfig = 
proxyConfig.Spec.AUTHORITY.Users[i].UserName +
+                       "@" + proxyConfig.Spec.AUTHORITY.Users[i].HostName +
+                       ":" + proxyConfig.Spec.AUTHORITY.Users[i].PassWord
+       }
+       y, _ := yaml.Marshal(proxyConfig.Spec)
+       return string(y)
+}

Reply via email to