diff --git a/lib/gat/configs/pgbouncer/config.go b/lib/gat/configs/pgbouncer/config.go index cb9abcb81e8a63d35a8097339ce1fa4306d8d2e2..008470791dace63dc004c54f53787425d79cfc36 100644 --- a/lib/gat/configs/pgbouncer/config.go +++ b/lib/gat/configs/pgbouncer/config.go @@ -44,6 +44,12 @@ const ( TLSProtocolLegacy TLSProtocol = "legacy" ) +type TLSCipher string + +type TLSECDHCurve string + +type TLSDHEParams string + type PgBouncer struct { LogFile string `ini:"logfile"` PidFile string `ini:"pidfile"` @@ -106,14 +112,66 @@ type PgBouncer struct { ClientTLSCertFile string `ini:"client_tls_cert_file"` ClientTLSCaFile string `ini:"client_tls_ca_file"` ClientTLSProtocols []TLSProtocol `ini:"client_tls_protocols"` + ClientTLSCiphers []TLSCipher `ini:"client_tls_ciphers"` + ClientTLSECDHCurve TLSECDHCurve `ini:"client_tls_ecdhcurve"` + ClientTLSDHEParams TLSDHEParams `ini:"client_tls_dheparams"` + ServerTLSSSLMode SSLMode `ini:"server_tls_sslmode"` + ServerTLSCaFile string `ini:"server_tls_ca_file"` + ServerTLSKeyFile string `ini:"server_tls_key_file"` + ServerTLSCertFile string `ini:"server_tls_cert_file"` + ServerTLSProtocols []TLSProtocol `ini:"server_tls_protocols"` + ServerTLSCiphers []TLSCipher `ini:"server_tls_ciphers"` + QueryTimeout float64 `ini:"query_timeout"` + QueryWaitTimeout float64 `ini:"query_wait_timeout"` + CancelWaitTimeout float64 `ini:"cancel_wait_timeout"` + ClientIdleTimeout float64 `ini:"client_idle_timeout"` + IdleTransactionTimeout float64 `ini:"idle_transaction_timeout"` + SuspendTimeout float64 `ini:"suspend_timeout"` + PktBuf int `ini:"pkt_buf"` + MaxPacketSize int `ini:"max_packet_size"` + ListenBacklog int `ini:"listen_backlog"` + SbufLoopcnt int `ini:"sbuf_loopcnt"` + SoReuseport int `ini:"so_reuseport"` + TcpDeferAccept int `ini:"tcp_defer_accept"` + TcpSocketBuffer int `ini:"tcp_socket_buffer"` + TcpKeepalive int `ini:"tcp_keepalive"` + TcpKeepidle int `ini:"tcp_keepidle"` + TcpKeepintvl int `ini:"tcp_keepintvl"` + TcpUserTimeout int `ini:"tcp_user_timeout"` } -type Config struct { - PgBouncer PgBouncer `ini:"pgbouncer"` - Databases map[string]string `ini:"databases"` - Users map[string]string `ini:"users"` +type Database struct { + DBName string `ini:"dbname"` + Host string `ini:"host"` + Port int `ini:"port"` + User string `ini:"user"` + Password string `ini:"password"` + AuthUser string `ini:"auth_user"` + PoolSize int `ini:"pool_size"` + MinPoolSize int `ini:"min_pool_size"` + ReservePool int `ini:"reserve_pool"` + ConnectQuery string `ini:"connect_query"` + PoolMode PoolMode `ini:"pool_mode"` + MaxDBConnections int `ini:"max_db_connections"` + ClientEncoding string `ini:"client_encoding"` + Datestyle string `ini:"datestyle"` + Timezone string `ini:"timezone"` } -func Test() { +type User struct { + PoolMode PoolMode `ini:"pool_mode"` + MaxUserConnections int `ini:"max_user_connections"` +} + +type Peer struct { + Host string `ini:"host"` + Port int `ini:"port"` + PoolSize int `ini:"pool_size"` +} +type Config struct { + PgBouncer PgBouncer `ini:"pgbouncer"` + Databases map[string]Database `ini:"databases"` + Users map[string]User `ini:"users"` + Peers map[string]Peer `ini:"peers"` } diff --git a/lib/util/ini/readfile.go b/lib/util/ini/readfile.go new file mode 100644 index 0000000000000000000000000000000000000000..555992470a01032e0e69f5ea4191b6d40deb833a --- /dev/null +++ b/lib/util/ini/readfile.go @@ -0,0 +1,45 @@ +package ini + +import ( + "bytes" + "os" +) + +func ReadFile(path string) ([]byte, error) { + lines, err := os.ReadFile(path) + if err != nil { + return nil, err + } + + var result bytes.Buffer + result.Grow(len(lines)) + + var line []byte + for { + line, lines, _ = bytes.Cut(lines, []byte{'\n'}) + line = bytes.TrimSpace(line) + if len(line) == 0 { + result.WriteByte('\n') + if len(lines) == 0 { + break + } + continue + } + + if bytes.HasPrefix(line, []byte("%include")) { + included := string(bytes.TrimSpace(bytes.TrimPrefix(line, []byte("%include")))) + b, err := ReadFile(included) + if err != nil { + return nil, err + } + result.Write(b) + result.WriteByte('\n') + continue + } + + result.Write(line) + result.WriteByte('\n') + } + + return result.Bytes(), nil +} diff --git a/lib/util/ini/unmarshal.go b/lib/util/ini/unmarshal.go index dfbc9de180059d4cdadff59bfd2dd0cef5453da0..e6a254f3ae58eb0010e4c5bc09fa3c21c789c278 100644 --- a/lib/util/ini/unmarshal.go +++ b/lib/util/ini/unmarshal.go @@ -176,6 +176,7 @@ func Unmarshal(data []byte, v any) error { var line []byte for { line, data, _ = bytes.Cut(data, []byte{'\n'}) + line = bytes.TrimSpace(line) if len(line) == 0 { if len(data) == 0 { break @@ -183,7 +184,10 @@ func Unmarshal(data []byte, v any) error { continue } - line = bytes.TrimSpace(line) + // %include + if bytes.HasPrefix(line, []byte("%include")) { + return errors.New("%include directive found. Use ReadFile instead") + } // comment if bytes.HasPrefix(line, []byte{';'}) || bytes.HasPrefix(line, []byte{'#'}) { diff --git a/lib/util/ini/unmarshal_test.go b/lib/util/ini/unmarshal_test.go index 9a0af8a9ecb6d6a1ec682307278ad715264e2262..8fe22676da9c0ec567700b31c23ab9c0e200f076 100644 --- a/lib/util/ini/unmarshal_test.go +++ b/lib/util/ini/unmarshal_test.go @@ -7,7 +7,7 @@ import ( type Database struct { Host string `ini:"host"` - Port string `ini:"port"` + Port uint16 `ini:"port"` User string `ini:"user"` Password string `ini:"password"` ClientEncoding string `ini:"client_encoding"` @@ -149,7 +149,7 @@ forcedb = host=localhost port=300 user=baz password=foo client_encoding=UNICODE }, "forcedb": { Host: "localhost", - Port: "300", + Port: 300, User: "baz", Password: "foo", ClientEncoding: "UNICODE",