Skip to content

Commit

Permalink
feat: add iam authentication for postgres (#1134)
Browse files Browse the repository at this point in the history
  • Loading branch information
gfyrag authored Jan 19, 2024
1 parent 1d58454 commit cc3aef7
Show file tree
Hide file tree
Showing 68 changed files with 1,058 additions and 677 deletions.
16 changes: 13 additions & 3 deletions components/ledger/cmd/buckets.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package cmd

import (
"github.com/formancehq/ledger/internal/storage"
"github.com/formancehq/ledger/internal/storage/driver"
"github.com/formancehq/stack/libs/go-libs/bun/bunconnect"
"github.com/formancehq/stack/libs/go-libs/logging"
"github.com/formancehq/stack/libs/go-libs/service"
"github.com/spf13/cobra"
Expand All @@ -23,7 +23,12 @@ func NewBucketUpgrade() *cobra.Command {
SilenceUsage: true,
RunE: func(cmd *cobra.Command, args []string) error {

driver := driver.New(storage.ConnectionOptionsFromFlags(viper.GetViper(), cmd.OutOrStdout(), viper.GetBool(service.DebugFlag)))
connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(viper.GetViper(), cmd.OutOrStdout(), viper.GetBool(service.DebugFlag))
if err != nil {
return err
}

driver := driver.New(*connectionOptions)
if err := driver.Initialize(cmd.Context()); err != nil {
return err
}
Expand Down Expand Up @@ -56,7 +61,12 @@ func NewBucketUpgradeAll() *cobra.Command {
logger := service.GetDefaultLogger(cmd.OutOrStdout(), viper.GetBool(service.DebugFlag), false)
ctx := logging.ContextWithLogger(cmd.Context(), logger)

driver := driver.New(storage.ConnectionOptionsFromFlags(viper.GetViper(), cmd.OutOrStdout(), viper.GetBool(service.DebugFlag)))
connectionOptions, err := bunconnect.ConnectionOptionsFromFlags(viper.GetViper(), cmd.OutOrStdout(), viper.GetBool(service.DebugFlag))
if err != nil {
return err
}

driver := driver.New(*connectionOptions)
defer func() {
_ = driver.Close()
}()
Expand Down
7 changes: 5 additions & 2 deletions components/ledger/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import (
"fmt"
"os"

"github.com/formancehq/stack/libs/go-libs/aws/iam"
"github.com/formancehq/stack/libs/go-libs/bun/bunconnect"

"github.com/formancehq/ledger/cmd/internal"
"github.com/formancehq/ledger/internal/storage/driver"
"github.com/formancehq/stack/libs/go-libs/auth"
"github.com/formancehq/stack/libs/go-libs/otlp/otlpmetrics"
"github.com/formancehq/stack/libs/go-libs/otlp/otlptraces"
Expand Down Expand Up @@ -57,7 +59,8 @@ func NewRootCommand() *cobra.Command {
auth.InitAuthFlags(root.PersistentFlags())
internal.InitAnalyticsFlags(root, DefaultSegmentWriteKey)
publish.InitCLIFlags(root)
driver.InitCLIFlags(root)
bunconnect.InitFlags(root.PersistentFlags())
iam.InitFlags(root.PersistentFlags())

if err := viper.BindPFlags(root.PersistentFlags()); err != nil {
panic(err)
Expand Down
16 changes: 16 additions & 0 deletions components/ledger/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@ require (
github.com/ThreeDotsLabs/watermill-kafka/v2 v2.2.2 // indirect
github.com/ThreeDotsLabs/watermill-nats/v2 v2.0.0 // indirect
github.com/ajg/form v1.5.1 // indirect
github.com/aws/aws-sdk-go-v2 v1.24.1 // indirect
github.com/aws/aws-sdk-go-v2/config v1.26.4 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.16.15 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 // indirect
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.3.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 // indirect
github.com/aws/smithy-go v1.19.0 // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/containerd/continuity v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
Expand All @@ -60,6 +74,7 @@ require (
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-sql-driver/mysql v1.6.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect
Expand Down Expand Up @@ -129,6 +144,7 @@ require (
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/xo/dburl v0.20.2 // indirect
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c // indirect
github.com/yusufpapurcu/wmi v1.2.2 // indirect
github.com/zitadel/oidc/v2 v2.11.0 // indirect
Expand Down
31 changes: 31 additions & 0 deletions components/ledger/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,34 @@ github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 h1:yL7+Jz0jTC6yykIK/Wh74gnTJnrGr5AyrNMXuA0gves=
github.com/antlr/antlr4/runtime/Go/antlr v1.4.10/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY=
github.com/aws/aws-sdk-go-v2 v1.24.1 h1:xAojnj+ktS95YZlDf0zxWBkbFtymPeDP+rvUQIH3uAU=
github.com/aws/aws-sdk-go-v2 v1.24.1/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4=
github.com/aws/aws-sdk-go-v2/config v1.26.4 h1:Juj7LhtxNudNUlfX22K5AnLafO+v4eq9PA3VWSCIQs4=
github.com/aws/aws-sdk-go-v2/config v1.26.4/go.mod h1:tioqQ7wvxMYnTDpoTTLHhV3Zh+z261i/f2oz+ds8eNI=
github.com/aws/aws-sdk-go-v2/credentials v1.16.15 h1:P0/m1LU08MF2kRzx4P//+7lNjiJod1z4xI2WpWhdpTQ=
github.com/aws/aws-sdk-go-v2/credentials v1.16.15/go.mod h1:pgtMCf7Dx4GWw5EpHOTc2Sy17LIP0A0N2C9nQ83pQ/0=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11 h1:c5I5iH+DZcH3xOIMlz3/tCKJDaHFwYEmxvlh2fAcFo8=
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.11/go.mod h1:cRrYDYAMUohBJUtUnOhydaMHtiK/1NZ0Otc9lIb6O0Y=
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.3.10 h1:z6fAXB4HSuYjrE/P8RU3NdCaN+EPaeq/+80aisCjuF8=
github.com/aws/aws-sdk-go-v2/feature/rds/auth v1.3.10/go.mod h1:PoPjOi7j+/DtKIGC58HRfcdWKBPYYXwdKnRG+po+hzo=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10 h1:vF+Zgd9s+H4vOXd5BMaPWykta2a6Ih0AKLq/X6NYKn4=
github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.10/go.mod h1:6BkRjejp/GR4411UGqkX8+wFMbFbqsUIimfK4XjOKR4=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10 h1:nYPe006ktcqUji8S2mqXf9c/7NdiKriOwMvWQHgYztw=
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.10/go.mod h1:6UV4SZkVvmODfXKql4LCbaZUpF7HO2BX38FgBf9ZOLw=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM=
github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw=
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10 h1:DBYTXwIGQSGs9w4jKm60F5dmCQ3EEruxdc0MFh+3EY4=
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.10/go.mod h1:wohMUQiFdzo0NtxbBg0mSRGZ4vL3n0dKjLTINdcIino=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6 h1:dGrs+Q/WzhsiUKh82SfTVN66QzyulXuMDTV/G8ZxOac=
github.com/aws/aws-sdk-go-v2/service/sso v1.18.6/go.mod h1:+mJNDdF+qiUlNKNC3fxn74WWNN+sOiGOEImje+3ScPM=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7 h1:QPMJf+Jw8E1l7zqhZmMlFw6w1NmfkfiSK8mS4zOx3BA=
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.7/go.mod h1:ykf3COxYI0UJmxcfcxcVuz7b6uADi1FkiUz6Eb7AgM8=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7 h1:NzO4Vrau795RkUdSHKEwiR01FaGzGOH1EETJ+5QHnm0=
github.com/aws/aws-sdk-go-v2/service/sts v1.26.7/go.mod h1:6h2YuIoxaMSCFf5fi1EgZAwdfkGMgDY+DVfa61uLe4U=
github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM=
github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE=
github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
Expand Down Expand Up @@ -164,6 +192,7 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
Expand Down Expand Up @@ -492,6 +521,8 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
github.com/xo/dburl v0.20.2 h1:59zqIzahtfQ/X9E6fyp1ziHwjYEFy65opjpyQPmZC7w=
github.com/xo/dburl v0.20.2/go.mod h1:B7/G9FGungw6ighV8xJNwWYQPMfn3gsi2sn5SE8Bzco=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c h1:3lbZUMbMiGUW/LMkfsEABsc5zNT9+b1CvsJx47JzJ8g=
github.com/xtgo/uuid v0.0.0-20140804021211-a0b114877d4c/go.mod h1:UrdRz5enIKZ63MEE3IF9l2/ebyx59GyGgPi+tICQdmM=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
25 changes: 4 additions & 21 deletions components/ledger/internal/storage/driver/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,26 @@ package driver
import (
"context"
"io"
"time"

"github.com/formancehq/stack/libs/go-libs/bun/bunconnect"

storage "github.com/formancehq/ledger/internal/storage"
"github.com/formancehq/stack/libs/go-libs/logging"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"go.uber.org/fx"
)

// TODO(gfyrag): maybe move flag handling inside cmd/internal (as telemetry flags)
// Or make the inverse (move analytics flags to pkg/analytics)
// IMO, flags are more easily discoverable if located inside cmd/
func InitCLIFlags(cmd *cobra.Command) {
cmd.PersistentFlags().Int(storage.StoreWorkerMaxPendingSize, 0, "Max pending size for store worker")
cmd.PersistentFlags().Int(storage.StoreWorkerMaxWriteChanSize, 1024, "Max write channel size for store worker")
cmd.PersistentFlags().String(storage.StoragePostgresConnectionStringFlag, "postgresql://localhost/postgres", "Postgres connection string")
cmd.PersistentFlags().Int(storage.StoragePostgresMaxIdleConnsFlag, 0, "Max idle connections to database")
cmd.PersistentFlags().Duration(storage.StoragePostgresConnMaxIdleTimeFlag, time.Minute, "Max idle time of idle connections")
cmd.PersistentFlags().Int(storage.StoragePostgresMaxOpenConns, 20, "Max open connections")
}

type PostgresConfig struct {
ConnString string
}

func CLIModule(v *viper.Viper, output io.Writer, debug bool) fx.Option {

options := make([]fx.Option, 0)
options = append(options, fx.Provide(func(logger logging.Logger) bunconnect.ConnectionOptions {
connectionOptions := storage.ConnectionOptionsFromFlags(v, output, debug)
logger.WithField("config", connectionOptions).Infof("Opening connection to database...")
return connectionOptions
options = append(options, fx.Provide(func() (*bunconnect.ConnectionOptions, error) {
return bunconnect.ConnectionOptionsFromFlags(v, output, debug)
}))
options = append(options, fx.Provide(func(connectionOptions bunconnect.ConnectionOptions) (*Driver, error) {
return New(connectionOptions), nil
options = append(options, fx.Provide(func(connectionOptions *bunconnect.ConnectionOptions) (*Driver, error) {
return New(*connectionOptions), nil
}))

options = append(options, fx.Invoke(func(driver *Driver, lifecycle fx.Lifecycle, logger logging.Logger) error {
Expand Down
29 changes: 0 additions & 29 deletions components/ledger/internal/storage/flags.go

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ func (store *Store) GetTransactionByReference(ctx context.Context, ref string) (
}

func (store *Store) GetLastTransaction(ctx context.Context) (*ledger.ExpandedTransaction, error) {

ret, err := fetch[*ExpandedTransaction](store, ctx,
func(query *bun.SelectQuery) *bun.SelectQuery {
return query.
Expand Down
44 changes: 44 additions & 0 deletions components/ledger/libs/aws/iam/load.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package iam

import (
"context"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/spf13/pflag"
"github.com/spf13/viper"
)

const (
AWSRegionFlag = "aws-region"
AWSAccessKeyIDFlag = "aws-access-key-id"
AWSSecretAccessKeyFlag = "aws-secret-access-key"
AWSSessionTokenFlag = "aws-session-token"
AWSProfileFlag = "aws-profile"
)

func InitFlags(flags *pflag.FlagSet) {
flags.String(AWSRegionFlag, "", "Specify AWS region")
flags.String(AWSAccessKeyIDFlag, "", "AWS access key id")
flags.String(AWSSecretAccessKeyFlag, "", "AWS secret access key")
flags.String(AWSSessionTokenFlag, "", "AWS session token")
flags.String(AWSProfileFlag, "", "AWS profile")
}

func LoadOptionFromViper(v *viper.Viper) func(opts *config.LoadOptions) error {
return func(opts *config.LoadOptions) error {
if v.GetString(AWSAccessKeyIDFlag) != "" {
opts.Credentials = aws.CredentialsProviderFunc(func(ctx context.Context) (aws.Credentials, error) {
return aws.Credentials{
AccessKeyID: v.GetString(AWSAccessKeyIDFlag),
SecretAccessKey: v.GetString(AWSSecretAccessKeyFlag),
SessionToken: v.GetString(AWSSessionTokenFlag),
Source: "flags",
}, nil
})
}
opts.Region = v.GetString(AWSRegionFlag)
opts.SharedConfigProfile = v.GetString(AWSProfileFlag)

return nil
}
}
20 changes: 17 additions & 3 deletions components/ledger/libs/bun/bunconnect/connect.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package bunconnect

import (
"database/sql"
"database/sql/driver"
"fmt"
"io"
"net/url"
Expand All @@ -20,6 +21,7 @@ type ConnectionOptions struct {
MaxIdleConns int
MaxOpenConns int
ConnMaxIdleTime time.Duration
Connector func(dsn string) (driver.Connector, error) `json:",omitempty"`
}

func (opts ConnectionOptions) String() string {
Expand All @@ -28,9 +30,21 @@ func (opts ConnectionOptions) String() string {
}

func OpenSQLDB(options ConnectionOptions, hooks ...bun.QueryHook) (*bun.DB, error) {
sqldb, err := sql.Open("postgres", options.DatabaseSourceName)
if err != nil {
return nil, err
var (
sqldb *sql.DB
err error
)
if options.Connector == nil {
sqldb, err = sql.Open("postgres", options.DatabaseSourceName)
if err != nil {
return nil, err
}
} else {
connector, err := options.Connector(options.DatabaseSourceName)
if err != nil {
return nil, err
}
sqldb = sql.OpenDB(connector)
}
if options.MaxIdleConns != 0 {
sqldb.SetMaxIdleConns(options.MaxIdleConns)
Expand Down
61 changes: 61 additions & 0 deletions components/ledger/libs/bun/bunconnect/flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package bunconnect

import (
"context"
"database/sql/driver"
"github.com/aws/aws-sdk-go-v2/config"
"github.com/formancehq/stack/libs/go-libs/aws/iam"
"github.com/lib/pq"
"github.com/spf13/pflag"
"github.com/spf13/viper"
"io"
"time"
)

const (
PostgresURIFlag = "postgres-uri"
PostgresAWSEnableIAMFlag = "postgres-aws-enable-iam"
PostgresMaxIdleConnsFlag = "postgres-max-idle-conns"
PostgresMaxOpenConnsFlag = "postgres-max-open-conns"
PostgresConnMaxIdleTimeFlag = "postgres-conn-max-idle-time"
)

func InitFlags(flags *pflag.FlagSet) {
flags.String(PostgresURIFlag, "", "Postgres URI")
flags.Bool(PostgresAWSEnableIAMFlag, false, "Enable AWS IAM authentication")
flags.Int(PostgresMaxIdleConnsFlag, 0, "Max Idle connections")
flags.Duration(PostgresConnMaxIdleTimeFlag, time.Minute, "Max Idle time for connections")
flags.Int(PostgresMaxOpenConnsFlag, 20, "Max opened connections")
}

func ConnectionOptionsFromFlags(v *viper.Viper, output io.Writer, debug bool) (*ConnectionOptions, error) {
var connector func(string) (driver.Connector, error)
if v.GetBool(PostgresAWSEnableIAMFlag) {
cfg, err := config.LoadDefaultConfig(context.Background(), iam.LoadOptionFromViper(v))
if err != nil {
return nil, err
}

connector = func(s string) (driver.Connector, error) {
return &iamConnector{
dsn: s,
driver: &iamDriver{
awsConfig: cfg,
},
}, nil
}
} else {
connector = func(dsn string) (driver.Connector, error) {
return pq.NewConnector(dsn)
}
}
return &ConnectionOptions{
DatabaseSourceName: v.GetString(PostgresURIFlag),
Debug: debug,
Writer: output,
MaxIdleConns: v.GetInt(PostgresMaxIdleConnsFlag),
ConnMaxIdleTime: v.GetDuration(PostgresConnMaxIdleTimeFlag),
MaxOpenConns: v.GetInt(PostgresMaxOpenConnsFlag),
Connector: connector,
}, nil
}
Loading

0 comments on commit cc3aef7

Please sign in to comment.