Skip to content

Commit

Permalink
Pass containerPort as parameter (#134)
Browse files Browse the repository at this point in the history
Signed-off-by: Hiranmoy Das Chowdhury <[email protected]>
  • Loading branch information
HiranmoyChowdhury authored Sep 24, 2024
1 parent e11cb0a commit 5182394
Show file tree
Hide file tree
Showing 13 changed files with 546 additions and 94 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ require (
k8s.io/klog/v2 v2.130.1
kmodules.xyz/client-go v0.30.13
kmodules.xyz/custom-resources v0.30.0
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee
kubedb.dev/apimachinery v0.47.1-0.20240924090635-38154e492f4e
sigs.k8s.io/controller-runtime v0.18.4
xorm.io/xorm v1.3.6
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -802,8 +802,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.30.0 h1:dq9F93pu4Q8rL9oTcCk+vGGy8vpS7RNt0GSwx7Bvhec=
kmodules.xyz/offshoot-api v0.30.0/go.mod h1:o9VoA3ImZMDBp3lpLb8+kc2d/KBxioRwCpaKDfLIyDw=
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee h1:RMFhW05n0VbzB3sTt4H3UqlKocCWW6m3h7DCAVsEwKE=
kubedb.dev/apimachinery v0.47.1-0.20240916095012-c4598e143fee/go.mod h1:iD6XKg9Blvfd9iYEO0N9GKiSz6r+yzEPZnfkYdESNG4=
kubedb.dev/apimachinery v0.47.1-0.20240924090635-38154e492f4e h1:Js68QYtwGJh06liBeFfSWfLRqdqeFEBzzBgcNve1HUM=
kubedb.dev/apimachinery v0.47.1-0.20240924090635-38154e492f4e/go.mod h1:iD6XKg9Blvfd9iYEO0N9GKiSz6r+yzEPZnfkYdESNG4=
kubeops.dev/petset v0.0.5-0.20240603165102-e2d9decb8abe h1:uWyps3VIDFwGuL0yQa0eMGaLg4ofVwpy59U14Trxnz8=
kubeops.dev/petset v0.0.5-0.20240603165102-e2d9decb8abe/go.mod h1:A15vh0r979NsvL65DTIZKWsa/NoX9VapHBAEw1ZsdYI=
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
Expand Down
9 changes: 5 additions & 4 deletions pgbouncer/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,9 @@ type XormClientList struct {
Mutex sync.Mutex
WG sync.WaitGroup

context context.Context
pb *dbapi.PgBouncer
auth *Auth
dbName string
context context.Context
pb *dbapi.PgBouncer
pbContainerPort rune
auth *Auth
dbName string
}
35 changes: 22 additions & 13 deletions pgbouncer/kubedb_client_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,15 @@ type Auth struct {
}

type KubeDBClientBuilder struct {
kc client.Client
pgbouncer *dbapi.PgBouncer
url string
podName string
backendDBName string
ctx context.Context
databaseRef *dbapi.Database
auth *Auth
kc client.Client
pgbouncer *dbapi.PgBouncer
url string
podName string
pbContainerPort *int32
backendDBName string
ctx context.Context
databaseRef *dbapi.Database
auth *Auth
}

func NewKubeDBClientBuilder(kc client.Client, pb *dbapi.PgBouncer) *KubeDBClientBuilder {
Expand All @@ -65,6 +66,11 @@ func (o *KubeDBClientBuilder) WithURL(url string) *KubeDBClientBuilder {
return o
}

func (o *KubeDBClientBuilder) WithPbPort(listenPort int32) *KubeDBClientBuilder {
o.pbContainerPort = &listenPort
return o
}

func (o *KubeDBClientBuilder) WithAuth(auth *Auth) *KubeDBClientBuilder {
if auth != nil && auth.UserName != "" && auth.Password != "" {
o.auth = auth
Expand All @@ -82,7 +88,7 @@ func (o *KubeDBClientBuilder) WithDatabaseRef(db *dbapi.Database) *KubeDBClientB
return o
}

func (o *KubeDBClientBuilder) WithPostgresDBName(dbName string) *KubeDBClientBuilder {
func (o *KubeDBClientBuilder) WithDatabaseName(dbName string) *KubeDBClientBuilder {
if dbName == "" {
o.backendDBName = o.databaseRef.DatabaseName
} else {
Expand Down Expand Up @@ -176,22 +182,23 @@ func (o *KubeDBClientBuilder) getConnectionString() (string, error) {
}

var listeningPort int = kubedb.PgBouncerDatabasePort
if o.pgbouncer.Spec.ConnectionPool.Port != nil {
listeningPort = int(*o.pgbouncer.Spec.ConnectionPool.Port)
if o.pbContainerPort != nil {
listeningPort = int(*o.pbContainerPort)
}
// 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, listeningPort, o.backendDBName, TLSModeDisable)
return connector, nil
}

func GetXormClientList(kc client.Client, pb *dbapi.PgBouncer, ctx context.Context, auth *Auth, dbName string) (*XormClientList, error) {
func GetXormClientList(kc client.Client, pb *dbapi.PgBouncer, ctx context.Context, auth *Auth, dbName string, listenPort rune) (*XormClientList, error) {
clientlist := &XormClientList{
List: []*XormClient{},
}
clientlist.context = ctx
clientlist.pb = pb
clientlist.auth = auth
clientlist.dbName = dbName
clientlist.pbContainerPort = listenPort

for i := 0; int32(i) < *pb.Spec.Replicas; i++ {
podName := fmt.Sprintf("%s-%d", pb.OffshootName(), i)
Expand All @@ -216,7 +223,9 @@ func GetXormClientList(kc client.Client, pb *dbapi.PgBouncer, ctx context.Contex
}

func (l *XormClientList) addXormClient(kc client.Client, podName string) {
xormClient, err := NewKubeDBClientBuilder(kc, l.pb).WithContext(l.context).WithDatabaseRef(&l.pb.Spec.Database).WithPod(podName).WithAuth(l.auth).WithPostgresDBName(l.dbName).GetPgBouncerXormClient()
xormClient, err := NewKubeDBClientBuilder(kc, l.pb).WithContext(l.context).WithDatabaseRef(&l.pb.Spec.Database).
WithPod(podName).WithAuth(l.auth).WithDatabaseName(l.dbName).WithPbPort(l.pbContainerPort).GetPgBouncerXormClient()

l.Mutex.Lock()
defer l.Mutex.Unlock()
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions vendor/kubedb.dev/apimachinery/apis/kubedb/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -576,6 +576,10 @@ const (
PgBouncerConfigMountPath = "/etc/config"
PgBouncerSecretMountPath = "/var/run/pgbouncer/secret"
PgBouncerServingCertMountPath = "/var/run/pgbouncer/tls/serving"
PgBouncerConfigSectionDatabases = "databases"
PgBouncerConfigSectionPeers = "peers"
PgBouncerConfigSectionPgbouncer = "pgbouncer"
PgBouncerConfigSectionUsers = "users"

// =========================== Pgpool Constants ============================
EnvPostgresUsername = "POSTGRES_USERNAME"
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

93 changes: 46 additions & 47 deletions vendor/kubedb.dev/apimachinery/apis/kubedb/v1/pgbouncer_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ limitations under the License.
package v1

import (
"context"
"fmt"
"strconv"

"kubedb.dev/apimachinery/apis"
catalog "kubedb.dev/apimachinery/apis/catalog/v1alpha1"
Expand All @@ -29,6 +31,7 @@ import (
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/types"
kmapi "kmodules.xyz/client-go/api/v1"
"kmodules.xyz/client-go/apiextensions"
core_util "kmodules.xyz/client-go/core/v1"
Expand Down Expand Up @@ -127,8 +130,19 @@ func (p PgBouncer) GetBackendSecretName() string {
return meta_util.NameWithSuffix(p.OffshootName(), "backend")
}

func (p PgBouncer) ConfigSecretName() string {
return meta_util.NameWithSuffix(p.ServiceName(), "config")
func (p PgBouncer) IsPgBouncerFinalConfigSecretExist() bool {
secret, err := p.GetPgBouncerFinalConfigSecret()
return (secret != nil && err == nil)
}

func (p PgBouncer) GetPgBouncerFinalConfigSecret() (*core.Secret, error) {
var secret core.Secret
err := DefaultClient.Get(context.TODO(), types.NamespacedName{Name: p.PgBouncerFinalConfigSecretName(), Namespace: p.GetNamespace()}, &secret)
return &secret, err
}

func (p PgBouncer) PgBouncerFinalConfigSecretName() string {
return meta_util.NameWithSuffix(p.ServiceName(), "final-config")
}

type pgbouncerApp struct {
Expand Down Expand Up @@ -200,8 +214,6 @@ func (p *PgBouncer) SetDefaults(pgBouncerVersion *catalog.PgBouncerVersion, uses
p.Spec.DeletionPolicy = DeletionPolicyDelete
}

p.setConnectionPoolConfigDefaults()

if p.Spec.TLS != nil {
if p.Spec.SSLMode == "" {
p.Spec.SSLMode = PgBouncerSSLModeVerifyFull
Expand Down Expand Up @@ -273,7 +285,7 @@ func (p *PgBouncer) GetPersistentSecrets() []string {
var secrets []string
secrets = append(secrets, p.GetAuthSecretName())
secrets = append(secrets, p.GetBackendSecretName())
secrets = append(secrets, p.ConfigSecretName())
secrets = append(secrets, p.PgBouncerFinalConfigSecretName())

return secrets
}
Expand Down Expand Up @@ -308,48 +320,6 @@ func (p *PgBouncer) SetHealthCheckerDefaults() {
}
}

func (p *PgBouncer) setConnectionPoolConfigDefaults() {
if p.Spec.ConnectionPool == nil {
p.Spec.ConnectionPool = &ConnectionPoolConfig{}
}
if p.Spec.ConnectionPool.Port == nil {
p.Spec.ConnectionPool.Port = pointer.Int32P(5432)
}
if p.Spec.ConnectionPool.PoolMode == "" {
p.Spec.ConnectionPool.PoolMode = kubedb.PgBouncerDefaultPoolMode
}
if p.Spec.ConnectionPool.MaxClientConnections == nil {
p.Spec.ConnectionPool.MaxClientConnections = pointer.Int64P(100)
}
if p.Spec.ConnectionPool.DefaultPoolSize == nil {
p.Spec.ConnectionPool.DefaultPoolSize = pointer.Int64P(20)
}
if p.Spec.ConnectionPool.MinPoolSize == nil {
p.Spec.ConnectionPool.MinPoolSize = pointer.Int64P(0)
}
if p.Spec.ConnectionPool.ReservePoolSize == nil {
p.Spec.ConnectionPool.ReservePoolSize = pointer.Int64P(0)
}
if p.Spec.ConnectionPool.ReservePoolTimeoutSeconds == nil {
p.Spec.ConnectionPool.ReservePoolTimeoutSeconds = pointer.Int64P(5)
}
if p.Spec.ConnectionPool.MaxDBConnections == nil {
p.Spec.ConnectionPool.MaxDBConnections = pointer.Int64P(0)
}
if p.Spec.ConnectionPool.MaxUserConnections == nil {
p.Spec.ConnectionPool.MaxUserConnections = pointer.Int64P(0)
}
if p.Spec.ConnectionPool.StatsPeriodSeconds == nil {
p.Spec.ConnectionPool.StatsPeriodSeconds = pointer.Int64P(60)
}
if p.Spec.ConnectionPool.AuthType == "" {
p.Spec.ConnectionPool.AuthType = PgBouncerClientAuthModeMD5
}
if p.Spec.ConnectionPool.IgnoreStartupParameters == "" {
p.Spec.ConnectionPool.IgnoreStartupParameters = kubedb.PgBouncerDefaultIgnoreStartupParameters
}
}

func (p *PgBouncer) SetSecurityContext(pgBouncerVersion *catalog.PgBouncerVersion) {
container := core_util.GetContainerByName(p.Spec.PodTemplate.Spec.Containers, kubedb.PgBouncerContainerName)
if container == nil {
Expand Down Expand Up @@ -405,3 +375,32 @@ func (p *PgBouncer) SetSecurityContext(pgBouncerVersion *catalog.PgBouncerVersio
core_util.UpsertContainer(p.Spec.PodTemplate.Spec.Containers, *container)
}
}

func PgBouncerConfigSections() *[]string {
sections := []string{
kubedb.PgBouncerConfigSectionDatabases, kubedb.PgBouncerConfigSectionPeers,
kubedb.PgBouncerConfigSectionPgbouncer, kubedb.PgBouncerConfigSectionUsers,
}
return &sections
}

func PgBouncerDefaultConfig() string {
defaultConfig := "[pgbouncer]\n" +
"\n" +
"listen_port = " + strconv.Itoa(kubedb.PgBouncerDatabasePort) + "\n" +
"pool_mode = " + kubedb.PgBouncerDefaultPoolMode + "\n" +
"max_client_conn = 100\n" +
"default_pool_size = 20\n" +
"min_pool_size = 1\n" +
"reserve_pool_size = 1\n" +
"reserve_pool_timeout = 5\n" +
"max_db_connections = 1\n" +
"max_user_connections = 2\n" +
"stats_period = 60\n" +
"auth_type = " + string(PgBouncerClientAuthModeMD5) + "\n" +
"ignore_startup_parameters = " + "extra_float_digits, " + kubedb.PgBouncerDefaultIgnoreStartupParameters + "\n" +
"logfile = /tmp/pgbouncer.log\n" +
"pidfile = /tmp/pgbouncer.pid\n" +
"listen_addr = *"
return defaultConfig
}
14 changes: 1 addition & 13 deletions vendor/kubedb.dev/apimachinery/apis/kubedb/v1/pgbouncer_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ type PgBouncerSpec struct {
PodTemplate ofstv2.PodTemplateSpec `json:"podTemplate,omitempty"`

// Database to proxy by connection pooling.
Database Database `json:"database,omitempty"`
Database Database `json:"database"`

// ConnectionPoolConfig defines Connection pool configuration.
// +optional
Expand Down Expand Up @@ -136,54 +136,42 @@ type Database struct {

type ConnectionPoolConfig struct {
// Port is the port number on which PgBouncer listens to clients. Default: 5432.
// +kubebuilder:default=5432
// +optional
Port *int32 `json:"port,omitempty"`
// PoolMode is the pooling mechanism type. Default: session.
// +kubebuilder:default="session"
// +optional
PoolMode string `json:"poolMode,omitempty"`
// MaxClientConnections is the maximum number of allowed client connections. Default: 100.
// +kubebuilder:default=100
// +optional
MaxClientConnections *int64 `json:"maxClientConnections,omitempty"`
// DefaultPoolSize specifies how many server connections to allow per user/database pair. Default: 20.
// +kubebuilder:default=20
// +optional
DefaultPoolSize *int64 `json:"defaultPoolSize,omitempty"`
// MinPoolSize is used to add more server connections to pool if below this number. Default: 0 (disabled).
// +kubebuilder:default=0
// +optional
MinPoolSize *int64 `json:"minPoolSize,omitempty"`
// ReservePoolSize specifies how many additional connections to allow to a pool. 0 disables. Default: 0 (disabled).
// +kubebuilder:default=0
// +optional
ReservePoolSize *int64 `json:"reservePoolSize,omitempty"`
// ReservePoolTimeoutSeconds is the number of seconds in which if a client has not been serviced,
// pgbouncer enables use of additional connections from reserve pool. 0 disables. Default: 5.0.
// +kubebuilder:default=5
// +optional
ReservePoolTimeoutSeconds *int64 `json:"reservePoolTimeoutSeconds,omitempty"`
// MaxDBConnections is the maximum number of connections allowed per-database. Default: 0 (unlimited).
// +kubebuilder:default=0
// +optional
MaxDBConnections *int64 `json:"maxDBConnections,omitempty"`
// MaxUserConnections is the maximum number of users allowed per-database. Default: 0 (unlimited).
// +kubebuilder:default=0
// +optional
MaxUserConnections *int64 `json:"maxUserConnections,omitempty"`
// StatsPeriodSeconds sets how often the averages shown in various SHOW commands are updated
// and how often aggregated statistics are written to the log. Default: 60
// +kubebuilder:default=60
// +optional
StatsPeriodSeconds *int64 `json:"statsPeriodSeconds,omitempty"`
// AuthType specifies how to authenticate users. Default: md5 (md5+plain text).
// +kubebuilder:default=md5
// +optional
AuthType PgBouncerClientAuthMode `json:"authType,omitempty"`
// IgnoreStartupParameters specifies comma-separated startup parameters that
// pgbouncer knows are handled by admin and it can ignore them. Default: empty
// +kubebuilder:default="empty"
// +optional
IgnoreStartupParameters string `json:"ignoreStartupParameters,omitempty"`
// AdminUsers specifies an array of users who can act as PgBouncer administrators.
Expand Down
Loading

0 comments on commit 5182394

Please sign in to comment.