From 7f4d5847462a4d9c99c71d11860d2e69a7786730 Mon Sep 17 00:00:00 2001 From: "Md. Mobarak Hossain" <50540163+MobarakHsn@users.noreply.github.com> Date: Fri, 19 Jan 2024 11:13:34 +0600 Subject: [PATCH] Add Pgpool DB-Client (#80) * Pgpool db-client Signed-off-by: MobarakHsn * Pgpool db client with latest pgpool api Signed-off-by: MobarakHsn * Apimachinary updated Signed-off-by: MobarakHsn * Pgpool auth problem Signed-off-by: MobarakHsn * Add pgpool db client Signed-off-by: MobarakHsn * Fixed pgpool db-client Signed-off-by: MobarakHsn --------- Signed-off-by: MobarakHsn --- go.mod | 4 +- go.sum | 4 +- pgpool/client.go | 31 ++++ pgpool/kubedb_client_builder.go | 156 ++++++++++++++++++ .../apis/kubedb/v1alpha2/openapi_generated.go | 4 +- .../apis/kubedb/v1alpha2/pgpool_types.go | 10 +- .../apis/kubedb/v1alpha2/pgpool_webhook.go | 6 + .../apimachinery/crds/kubedb.com_pgpools.yaml | 1 + vendor/modules.txt | 2 +- 9 files changed, 206 insertions(+), 12 deletions(-) create mode 100644 pgpool/client.go create mode 100644 pgpool/kubedb_client_builder.go diff --git a/go.mod b/go.mod index c61df4bf4..301ee0869 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,8 @@ require ( k8s.io/apimachinery v0.29.0 k8s.io/klog/v2 v2.110.1 kmodules.xyz/client-go v0.29.6 - kubedb.dev/apimachinery v0.41.0-beta.0.0.20240117131030-72d44aef7411 + kmodules.xyz/custom-resources v0.29.0 + kubedb.dev/apimachinery v0.41.0-beta.0.0.20240118063916-9d6870498d68 sigs.k8s.io/controller-runtime v0.16.3 xorm.io/xorm v1.3.6 ) @@ -115,7 +116,6 @@ require ( k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a // indirect k8s.io/utils v0.0.0-20231127182322-b307cd553661 // indirect kmodules.xyz/apiversion v0.2.0 // indirect - kmodules.xyz/custom-resources v0.29.0 // indirect kmodules.xyz/monitoring-agent-api v0.29.0 // indirect kmodules.xyz/offshoot-api v0.29.0 // indirect modernc.org/memory v1.5.0 // indirect diff --git a/go.sum b/go.sum index f5392648a..8d267a8b2 100644 --- a/go.sum +++ b/go.sum @@ -580,8 +580,8 @@ kmodules.xyz/monitoring-agent-api v0.29.0 h1:gpFl6OZrlMLb/ySMHdREI9EwGtnJ91oZBn9 kmodules.xyz/monitoring-agent-api v0.29.0/go.mod h1:iNbvaMTgVFOI5q2LJtGK91j4Dmjv4ZRiRdasGmWLKQI= kmodules.xyz/offshoot-api v0.29.0 h1:GHLhxxT9jU1N8+FvOCCeJNyU5g0duYS46UGrs6AHNLY= kmodules.xyz/offshoot-api v0.29.0/go.mod h1:5NxhBblXoDHWStx9HCDJR2KFTwYjEZ7i1Id3jelIunw= -kubedb.dev/apimachinery v0.41.0-beta.0.0.20240117131030-72d44aef7411 h1:ZSVihIHPJfZSoegK5WGpSsVPTDZzHuaLsqOK9Hp+6Xg= -kubedb.dev/apimachinery v0.41.0-beta.0.0.20240117131030-72d44aef7411/go.mod h1:9iHsSfX02yJ6eA9IXSCruVjckH8wWgHB93ivpNVc1EY= +kubedb.dev/apimachinery v0.41.0-beta.0.0.20240118063916-9d6870498d68 h1:2J1DMU9OiiMzQMKfv+gTGkmcN34JTARqS5CA0pjctMc= +kubedb.dev/apimachinery v0.41.0-beta.0.0.20240118063916-9d6870498d68/go.mod h1:9iHsSfX02yJ6eA9IXSCruVjckH8wWgHB93ivpNVc1EY= lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI= lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk= diff --git a/pgpool/client.go b/pgpool/client.go new file mode 100644 index 000000000..36b275338 --- /dev/null +++ b/pgpool/client.go @@ -0,0 +1,31 @@ +/* +Copyright AppsCode Inc. and Contributors + +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 pgpool + +import ( + "database/sql" + + "xorm.io/xorm" +) + +type Client struct { + *sql.DB +} + +type XormClient struct { + *xorm.Engine +} diff --git a/pgpool/kubedb_client_builder.go b/pgpool/kubedb_client_builder.go new file mode 100644 index 000000000..1b2a5fc8a --- /dev/null +++ b/pgpool/kubedb_client_builder.go @@ -0,0 +1,156 @@ +/* +Copyright AppsCode Inc. and Contributors + +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 pgpool + +import ( + "context" + "fmt" + + _ "github.com/lib/pq" + core "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + appbinding "kmodules.xyz/custom-resources/apis/appcatalog/v1alpha1" + api "kubedb.dev/apimachinery/apis/kubedb/v1alpha2" + "sigs.k8s.io/controller-runtime/pkg/client" + "xorm.io/xorm" +) + +const ( + DefaultBackendDBName = "postgres" + DefaultPgpoolPort = 9999 + TLSModeDisable = "disable" +) + +type KubeDBClientBuilder struct { + kc client.Client + pgpool *api.Pgpool + url string + podName string + backendDBName string + ctx context.Context +} + +func NewKubeDBClientBuilder(kc client.Client, pp *api.Pgpool) *KubeDBClientBuilder { + return &KubeDBClientBuilder{ + kc: kc, + pgpool: pp, + } +} + +func (o *KubeDBClientBuilder) WithURL(url string) *KubeDBClientBuilder { + o.url = url + return o +} + +func (o *KubeDBClientBuilder) WithPod(podName string) *KubeDBClientBuilder { + o.podName = podName + return o +} + +func (o *KubeDBClientBuilder) WithPgpoolDB(pgDB string) *KubeDBClientBuilder { + o.backendDBName = pgDB + return o +} + +func (o *KubeDBClientBuilder) WithContext(ctx context.Context) *KubeDBClientBuilder { + o.ctx = ctx + return o +} + +func (o *KubeDBClientBuilder) GetPgpoolXormClient() (*XormClient, error) { + if o.ctx == nil { + o.ctx = context.Background() + } + + connector, err := o.getConnectionString() + if err != nil { + return nil, err + } + + engine, err := xorm.NewEngine("postgres", connector) + if err != nil { + return nil, err + } + _, err = engine.Query("SELECT 1") + if err != nil { + err = engine.Close() + if err != nil { + return nil, err + } + return nil, err + } + + engine.SetDefaultContext(o.ctx) + return &XormClient{ + engine, + }, nil +} + +func (o *KubeDBClientBuilder) getURL() string { + return fmt.Sprintf("%s.%s.%s.svc", o.podName, o.pgpool.GoverningServiceName(), o.pgpool.Namespace) +} + +func (o *KubeDBClientBuilder) getBackendAuth() (string, string, error) { + pp := o.pgpool + var secretName string + if pp.Spec.Backend != nil { + apb := &appbinding.AppBinding{} + err := o.kc.Get(o.ctx, types.NamespacedName{ + Name: pp.Spec.Backend.Name, + Namespace: pp.Namespace, + }, apb) + if err != nil { + return "", "", err + } + if apb.Spec.Secret == nil { + return "", "", fmt.Errorf("backend database auth secret not found") + } + secretName = apb.Spec.Secret.Name + } + var secret core.Secret + err := o.kc.Get(o.ctx, client.ObjectKey{Namespace: pp.Namespace, Name: secretName}, &secret) + if err != nil { + return "", "", err + } + user, ok := secret.Data[core.BasicAuthUsernameKey] + if !ok { + return "", "", fmt.Errorf("error getting backend username") + } + pass, ok := secret.Data[core.BasicAuthPasswordKey] + if !ok { + return "", "", fmt.Errorf("error getting backend password") + } + return string(user), string(pass), nil +} + +func (o *KubeDBClientBuilder) getConnectionString() (string, error) { + user, pass, err := o.getBackendAuth() + if err != nil { + return "", err + } + + if o.podName != "" { + o.url = o.getURL() + } + + if o.backendDBName == "" { + o.backendDBName = DefaultBackendDBName + } + //TODO ssl mode is disable now need to work on this after adding tls support + connector := fmt.Sprintf("user=%s password=%s host=%s port=%d connect_timeout=10 dbname=%s sslmode=%s", user, pass, o.url, DefaultPgpoolPort, o.backendDBName, TLSModeDisable) + return connector, nil +} diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go index cd87d2df5..f8a6fa246 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/openapi_generated.go @@ -27684,7 +27684,7 @@ func schema_apimachinery_apis_kubedb_v1alpha2_PgpoolSpec(ref common.ReferenceCal }, "configSecret": { SchemaProps: spec.SchemaProps{ - Description: "ConfigSecret is an optional field to provide custom configuration file for database (i.e pgpool.conf). If specified, this file will be used as configuration file otherwise default configuration file will be used.", + Description: "ConfigSecret is a configuration secret which will be created with default and InitConfiguration", Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), }, }, @@ -27728,7 +27728,7 @@ func schema_apimachinery_apis_kubedb_v1alpha2_PgpoolSpec(ref common.ReferenceCal }, }, }, - Required: []string{"version"}, + Required: []string{"version", "backend"}, }, }, Dependencies: []string{ diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_types.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_types.go index 7ed4c14a7..da03c0741 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_types.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_types.go @@ -58,9 +58,9 @@ type PgpoolSpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file - // +optional // SyncUsers is a boolean type and when enabled, operator fetches all users created in the backend server to the // Pgpool server . Password changes are also synced in pgpool when it is enabled. + // +optional SyncUsers bool `json:"syncUsers,omitempty"` // Version of Pgpool to be deployed. @@ -71,22 +71,22 @@ type PgpoolSpec struct { Replicas *int32 `json:"replicas,omitempty"` // Backend refers to the AppBinding of the backend PostgreSQL server - Backend *core.LocalObjectReference `json:"backend,omitempty"` + Backend *core.LocalObjectReference `json:"backend"` // Pgpool secret containing username and password for pgpool pcp user // +optional AuthSecret *SecretReference `json:"authSecret,omitempty"` - // ConfigSecret is an optional field to provide custom configuration file for database (i.e pgpool.conf). - // If specified, this file will be used as configuration file otherwise default configuration file will be used. + // ConfigSecret is a configuration secret which will be created with default and InitConfiguration + // +optional ConfigSecret *core.LocalObjectReference `json:"configSecret,omitempty"` // PodTemplate is an optional configuration for pods used to expose Pgpool // +optional PodTemplate *ofst.PodTemplateSpec `json:"podTemplate,omitempty"` - // +optional // InitConfiguration contains information with which the Pgpool will bootstrap + // +optional InitConfiguration *PgpoolConfiguration `json:"initConfig,omitempty"` // ServiceTemplates is an optional configuration for services used to expose Pgpool diff --git a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go index 453e17ca1..a5aeb304d 100644 --- a/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go +++ b/vendor/kubedb.dev/apimachinery/apis/kubedb/v1alpha2/pgpool_webhook.go @@ -110,6 +110,12 @@ func (p *Pgpool) ValidateCreateOrUpdate() field.ErrorList { } } + if p.Spec.Backend == nil { + errorList = append(errorList, field.Required(field.NewPath("spec").Child("backend").Child("name"), + "`spec.backend.name` is missing", + )) + } + if p.Spec.Replicas != nil { if *p.Spec.Replicas <= 0 { errorList = append(errorList, field.Required(field.NewPath("spec").Child("replicas"), diff --git a/vendor/kubedb.dev/apimachinery/crds/kubedb.com_pgpools.yaml b/vendor/kubedb.dev/apimachinery/crds/kubedb.com_pgpools.yaml index c13580b62..1a8e1e9f4 100644 --- a/vendor/kubedb.dev/apimachinery/crds/kubedb.com_pgpools.yaml +++ b/vendor/kubedb.dev/apimachinery/crds/kubedb.com_pgpools.yaml @@ -3531,6 +3531,7 @@ spec: version: type: string required: + - backend - version type: object status: diff --git a/vendor/modules.txt b/vendor/modules.txt index 7d77128f1..280aa66da 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1402,7 +1402,7 @@ kmodules.xyz/monitoring-agent-api/api/v1 ## explicit; go 1.21.5 kmodules.xyz/offshoot-api/api/v1 kmodules.xyz/offshoot-api/api/v2 -# kubedb.dev/apimachinery v0.41.0-beta.0.0.20240117131030-72d44aef7411 +# kubedb.dev/apimachinery v0.41.0-beta.0.0.20240118063916-9d6870498d68 ## explicit; go 1.21.5 kubedb.dev/apimachinery/apis kubedb.dev/apimachinery/apis/catalog