github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/options.go (about)

     1  package ydb
     2  
     3  import (
     4  	"context"
     5  	"crypto/tls"
     6  	"crypto/x509"
     7  	"fmt"
     8  	"os"
     9  	"path/filepath"
    10  	"time"
    11  
    12  	"github.com/ydb-platform/ydb-go-sdk/v3/config"
    13  	"github.com/ydb-platform/ydb-go-sdk/v3/credentials"
    14  	balancerConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/balancer/config"
    15  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/certificates"
    16  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/conn"
    17  	coordinationConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/coordination/config"
    18  	discoveryConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/discovery/config"
    19  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/dsn"
    20  	queryConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/query/config"
    21  	ratelimiterConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/ratelimiter/config"
    22  	schemeConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/scheme/config"
    23  	scriptingConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/scripting/config"
    24  	tableConfig "github.com/ydb-platform/ydb-go-sdk/v3/internal/table/config"
    25  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xerrors"
    26  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/xsql"
    27  	"github.com/ydb-platform/ydb-go-sdk/v3/log"
    28  	"github.com/ydb-platform/ydb-go-sdk/v3/topic/topicoptions"
    29  	"github.com/ydb-platform/ydb-go-sdk/v3/trace"
    30  )
    31  
    32  // Option contains configuration values for Driver
    33  type Option func(ctx context.Context, c *Driver) error
    34  
    35  func WithStaticCredentials(user, password string) Option {
    36  	return func(ctx context.Context, c *Driver) error {
    37  		c.userInfo = &dsn.UserInfo{
    38  			User:     user,
    39  			Password: password,
    40  		}
    41  
    42  		return nil
    43  	}
    44  }
    45  
    46  func WithAccessTokenCredentials(accessToken string) Option {
    47  	return WithCredentials(
    48  		credentials.NewAccessTokenCredentials(
    49  			accessToken,
    50  			credentials.WithSourceInfo(
    51  				"ydb.WithAccessTokenCredentials(accessToken)", // hide access token for logs
    52  			),
    53  		),
    54  	)
    55  }
    56  
    57  // WithUserAgent add provided user agent value to all api requests
    58  func WithUserAgent(userAgent string) Option {
    59  	return func(ctx context.Context, c *Driver) error {
    60  		c.options = append(c.options, config.WithUserAgent(userAgent))
    61  
    62  		return nil
    63  	}
    64  }
    65  
    66  func WithRequestsType(requestsType string) Option {
    67  	return func(ctx context.Context, c *Driver) error {
    68  		c.options = append(c.options, config.WithRequestsType(requestsType))
    69  
    70  		return nil
    71  	}
    72  }
    73  
    74  // WithConnectionString accept Driver string like
    75  //
    76  //	grpc[s]://{endpoint}/{database}[?param=value]
    77  //
    78  // Warning: WithConnectionString will be removed at next major release
    79  //
    80  // (Driver string will be required string param of ydb.Open)
    81  func WithConnectionString(connectionString string) Option {
    82  	return func(ctx context.Context, c *Driver) error {
    83  		if connectionString == "" {
    84  			return nil
    85  		}
    86  		info, err := dsn.Parse(connectionString)
    87  		if err != nil {
    88  			return xerrors.WithStackTrace(
    89  				fmt.Errorf("parse connection string '%s' failed: %w", connectionString, err),
    90  			)
    91  		}
    92  		c.options = append(c.options, info.Options...)
    93  		c.userInfo = info.UserInfo
    94  
    95  		return nil
    96  	}
    97  }
    98  
    99  // WithConnectionTTL defines duration for parking idle connections
   100  func WithConnectionTTL(ttl time.Duration) Option {
   101  	return func(ctx context.Context, c *Driver) error {
   102  		c.options = append(c.options, config.WithConnectionTTL(ttl))
   103  
   104  		return nil
   105  	}
   106  }
   107  
   108  // WithEndpoint defines endpoint option
   109  //
   110  // Warning: use ydb.Open with required Driver string parameter instead
   111  //
   112  // For making Driver string from endpoint+database+secure - use sugar.DSN()
   113  func WithEndpoint(endpoint string) Option {
   114  	return func(ctx context.Context, c *Driver) error {
   115  		c.options = append(c.options, config.WithEndpoint(endpoint))
   116  
   117  		return nil
   118  	}
   119  }
   120  
   121  // WithDatabase defines database option
   122  //
   123  // Warning: use ydb.Open with required Driver string parameter instead
   124  //
   125  // For making Driver string from endpoint+database+secure - use sugar.DSN()
   126  func WithDatabase(database string) Option {
   127  	return func(ctx context.Context, c *Driver) error {
   128  		c.options = append(c.options, config.WithDatabase(database))
   129  
   130  		return nil
   131  	}
   132  }
   133  
   134  // WithSecure defines secure option
   135  //
   136  // Warning: use ydb.Open with required Driver string parameter instead
   137  //
   138  // For making Driver string from endpoint+database+secure - use sugar.DSN()
   139  func WithSecure(secure bool) Option {
   140  	return func(ctx context.Context, c *Driver) error {
   141  		c.options = append(c.options, config.WithSecure(secure))
   142  
   143  		return nil
   144  	}
   145  }
   146  
   147  // WithInsecure defines secure option.
   148  //
   149  // Warning: WithInsecure lost current TLS config.
   150  func WithInsecure() Option {
   151  	return func(ctx context.Context, c *Driver) error {
   152  		c.options = append(c.options, config.WithSecure(false))
   153  
   154  		return nil
   155  	}
   156  }
   157  
   158  // WithMinTLSVersion set minimum TLS version acceptable for connections
   159  func WithMinTLSVersion(minVersion uint16) Option {
   160  	return func(ctx context.Context, c *Driver) error {
   161  		c.options = append(c.options, config.WithMinTLSVersion(minVersion))
   162  
   163  		return nil
   164  	}
   165  }
   166  
   167  // WithTLSSInsecureSkipVerify applies InsecureSkipVerify flag to TLS config
   168  func WithTLSSInsecureSkipVerify() Option {
   169  	return func(ctx context.Context, c *Driver) error {
   170  		c.options = append(c.options, config.WithTLSSInsecureSkipVerify())
   171  
   172  		return nil
   173  	}
   174  }
   175  
   176  // WithLogger add enables logging for selected tracing events.
   177  //
   178  // See trace package documentation for details.
   179  func WithLogger(l log.Logger, details trace.Detailer, opts ...log.Option) Option {
   180  	return func(ctx context.Context, c *Driver) error {
   181  		c.logger = l
   182  		c.loggerOpts = opts
   183  		c.loggerDetails = details
   184  
   185  		return nil
   186  	}
   187  }
   188  
   189  // WithAnonymousCredentials force to make requests withou authentication.
   190  func WithAnonymousCredentials() Option {
   191  	return WithCredentials(
   192  		credentials.NewAnonymousCredentials(credentials.WithSourceInfo("ydb.WithAnonymousCredentials()")),
   193  	)
   194  }
   195  
   196  // WithCreateCredentialsFunc add callback funcion to provide requests credentials
   197  func WithCreateCredentialsFunc(createCredentials func(ctx context.Context) (credentials.Credentials, error)) Option {
   198  	return func(ctx context.Context, c *Driver) error {
   199  		creds, err := createCredentials(ctx)
   200  		if err != nil {
   201  			return xerrors.WithStackTrace(err)
   202  		}
   203  		c.options = append(c.options, config.WithCredentials(creds))
   204  
   205  		return nil
   206  	}
   207  }
   208  
   209  // WithCredentials in conjunction with Driver.With function prohibit reuse of conn pool.
   210  // Thus, Driver.With will effectively create totally separate Driver.
   211  func WithCredentials(c credentials.Credentials) Option {
   212  	return WithCreateCredentialsFunc(func(context.Context) (credentials.Credentials, error) {
   213  		return c, nil
   214  	})
   215  }
   216  
   217  func WithBalancer(balancer *balancerConfig.Config) Option {
   218  	return func(ctx context.Context, c *Driver) error {
   219  		c.options = append(c.options, config.WithBalancer(balancer))
   220  
   221  		return nil
   222  	}
   223  }
   224  
   225  // WithDialTimeout sets timeout for establishing new Driver to cluster
   226  //
   227  // Default dial timeout is config.DefaultDialTimeout
   228  func WithDialTimeout(timeout time.Duration) Option {
   229  	return func(ctx context.Context, c *Driver) error {
   230  		c.options = append(c.options, config.WithDialTimeout(timeout))
   231  
   232  		return nil
   233  	}
   234  }
   235  
   236  // With collects additional configuration options.
   237  //
   238  // This option does not replace collected option, instead it will append provided options.
   239  func With(options ...config.Option) Option {
   240  	return func(ctx context.Context, c *Driver) error {
   241  		c.options = append(c.options, options...)
   242  
   243  		return nil
   244  	}
   245  }
   246  
   247  // MergeOptions concatentaes provided options to one cumulative value.
   248  func MergeOptions(opts ...Option) Option {
   249  	return func(ctx context.Context, c *Driver) error {
   250  		for _, o := range opts {
   251  			if o != nil {
   252  				if err := o(ctx, c); err != nil {
   253  					return xerrors.WithStackTrace(err)
   254  				}
   255  			}
   256  		}
   257  
   258  		return nil
   259  	}
   260  }
   261  
   262  // WithDiscoveryInterval sets interval between cluster discovery calls.
   263  func WithDiscoveryInterval(discoveryInterval time.Duration) Option {
   264  	return func(ctx context.Context, c *Driver) error {
   265  		c.discoveryOptions = append(c.discoveryOptions, discoveryConfig.WithInterval(discoveryInterval))
   266  
   267  		return nil
   268  	}
   269  }
   270  
   271  // WithTraceDriver appends trace.Driver into driver traces
   272  func WithTraceDriver(t trace.Driver, opts ...trace.DriverComposeOption) Option { //nolint:gocritic
   273  	return func(ctx context.Context, c *Driver) error {
   274  		c.options = append(c.options, config.WithTrace(t, opts...))
   275  
   276  		return nil
   277  	}
   278  }
   279  
   280  // WithTraceRetry appends trace.Retry into retry traces
   281  func WithTraceRetry(t trace.Retry, opts ...trace.RetryComposeOption) Option {
   282  	return func(ctx context.Context, c *Driver) error {
   283  		c.options = append(c.options,
   284  			config.WithTraceRetry(&t, append(
   285  				[]trace.RetryComposeOption{
   286  					trace.WithRetryPanicCallback(c.panicCallback),
   287  				},
   288  				opts...,
   289  			)...),
   290  		)
   291  
   292  		return nil
   293  	}
   294  }
   295  
   296  // WithCertificate appends certificate to TLS config root certificates
   297  func WithCertificate(cert *x509.Certificate) Option {
   298  	return func(ctx context.Context, c *Driver) error {
   299  		c.options = append(c.options, config.WithCertificate(cert))
   300  
   301  		return nil
   302  	}
   303  }
   304  
   305  // WithCertificatesFromFile appends certificates by filepath to TLS config root certificates
   306  func WithCertificatesFromFile(caFile string, opts ...certificates.FromFileOption) Option {
   307  	if len(caFile) > 0 && caFile[0] == '~' {
   308  		if home, err := os.UserHomeDir(); err == nil {
   309  			caFile = filepath.Join(home, caFile[1:])
   310  		}
   311  	}
   312  	if file, err := filepath.Abs(caFile); err == nil {
   313  		caFile = file
   314  	}
   315  	if file, err := filepath.EvalSymlinks(caFile); err == nil {
   316  		caFile = file
   317  	}
   318  
   319  	return func(ctx context.Context, c *Driver) error {
   320  		certs, err := certificates.FromFile(caFile, opts...)
   321  		if err != nil {
   322  			return xerrors.WithStackTrace(err)
   323  		}
   324  		for _, cert := range certs {
   325  			if err := WithCertificate(cert)(ctx, c); err != nil {
   326  				return xerrors.WithStackTrace(err)
   327  			}
   328  		}
   329  
   330  		return nil
   331  	}
   332  }
   333  
   334  // WithTLSConfig replaces older TLS config
   335  //
   336  // Warning: all early TLS config changes (such as WithCertificate, WithCertificatesFromFile, WithCertificatesFromPem,
   337  // WithMinTLSVersion, WithTLSSInsecureSkipVerify) will be lost
   338  func WithTLSConfig(tlsConfig *tls.Config) Option {
   339  	return func(ctx context.Context, c *Driver) error {
   340  		c.options = append(c.options, config.WithTLSConfig(tlsConfig))
   341  
   342  		return nil
   343  	}
   344  }
   345  
   346  // WithCertificatesFromPem appends certificates from pem-encoded data to TLS config root certificates
   347  func WithCertificatesFromPem(bytes []byte, opts ...certificates.FromPemOption) Option {
   348  	return func(ctx context.Context, c *Driver) error {
   349  		certs, err := certificates.FromPem(bytes, opts...)
   350  		if err != nil {
   351  			return xerrors.WithStackTrace(err)
   352  		}
   353  		for _, cert := range certs {
   354  			_ = WithCertificate(cert)(ctx, c)
   355  		}
   356  
   357  		return nil
   358  	}
   359  }
   360  
   361  // WithTableConfigOption collects additional configuration options for table.Client.
   362  // This option does not replace collected option, instead it will appen provided options.
   363  func WithTableConfigOption(option tableConfig.Option) Option {
   364  	return func(ctx context.Context, c *Driver) error {
   365  		c.tableOptions = append(c.tableOptions, option)
   366  
   367  		return nil
   368  	}
   369  }
   370  
   371  // WithQueryConfigOption collects additional configuration options for query.Client.
   372  // This option does not replace collected option, instead it will appen provided options.
   373  func WithQueryConfigOption(option queryConfig.Option) Option {
   374  	return func(ctx context.Context, c *Driver) error {
   375  		c.queryOptions = append(c.queryOptions, option)
   376  
   377  		return nil
   378  	}
   379  }
   380  
   381  // WithSessionPoolSizeLimit set max size of internal sessions pool in table.Client
   382  func WithSessionPoolSizeLimit(sizeLimit int) Option {
   383  	return func(ctx context.Context, c *Driver) error {
   384  		c.tableOptions = append(c.tableOptions, tableConfig.WithSizeLimit(sizeLimit))
   385  		c.queryOptions = append(c.queryOptions, queryConfig.WithSizeLimit(sizeLimit))
   386  
   387  		return nil
   388  	}
   389  }
   390  
   391  // WithSessionPoolKeepAliveMinSize set minimum sessions should be keeped alive in table.Client
   392  //
   393  // Deprecated: table client do not supports background session keep-aliving now
   394  func WithSessionPoolKeepAliveMinSize(keepAliveMinSize int) Option {
   395  	return func(ctx context.Context, c *Driver) error { return nil }
   396  }
   397  
   398  // WithSessionPoolIdleThreshold defines interval for idle sessions
   399  func WithSessionPoolIdleThreshold(idleThreshold time.Duration) Option {
   400  	return func(ctx context.Context, c *Driver) error {
   401  		c.tableOptions = append(c.tableOptions, tableConfig.WithIdleThreshold(idleThreshold))
   402  		c.databaseSQLOptions = append(
   403  			c.databaseSQLOptions,
   404  			xsql.WithIdleThreshold(idleThreshold),
   405  		)
   406  
   407  		return nil
   408  	}
   409  }
   410  
   411  // WithSessionPoolKeepAliveTimeout set timeout of keep alive requests for session in table.Client
   412  func WithSessionPoolKeepAliveTimeout(keepAliveTimeout time.Duration) Option {
   413  	return func(ctx context.Context, c *Driver) error { return nil }
   414  }
   415  
   416  // WithSessionPoolCreateSessionTimeout set timeout for new session creation process in table.Client
   417  func WithSessionPoolCreateSessionTimeout(createSessionTimeout time.Duration) Option {
   418  	return func(ctx context.Context, c *Driver) error {
   419  		c.tableOptions = append(c.tableOptions, tableConfig.WithCreateSessionTimeout(createSessionTimeout))
   420  		c.queryOptions = append(c.queryOptions, queryConfig.WithCreateSessionTimeout(createSessionTimeout))
   421  
   422  		return nil
   423  	}
   424  }
   425  
   426  // WithSessionPoolDeleteTimeout set timeout to gracefully close deleting session in table.Client
   427  func WithSessionPoolDeleteTimeout(deleteTimeout time.Duration) Option {
   428  	return func(ctx context.Context, c *Driver) error {
   429  		c.tableOptions = append(c.tableOptions, tableConfig.WithDeleteTimeout(deleteTimeout))
   430  		c.queryOptions = append(c.queryOptions, queryConfig.WithDeleteTimeout(deleteTimeout))
   431  
   432  		return nil
   433  	}
   434  }
   435  
   436  // WithIgnoreTruncated disables errors on truncated flag
   437  func WithIgnoreTruncated() Option {
   438  	return func(ctx context.Context, c *Driver) error {
   439  		c.tableOptions = append(c.tableOptions, tableConfig.WithIgnoreTruncated())
   440  
   441  		return nil
   442  	}
   443  }
   444  
   445  // WithPanicCallback specified behavior on panic
   446  // Warning: WithPanicCallback must be defined on start of all options
   447  // (before `WithTrace{Driver,Table,Scheme,Scripting,Coordination,Ratelimiter}` and other options)
   448  // If not defined - panic would not intercept with driver
   449  func WithPanicCallback(panicCallback func(e interface{})) Option {
   450  	return func(ctx context.Context, c *Driver) error {
   451  		c.panicCallback = panicCallback
   452  		c.options = append(c.options, config.WithPanicCallback(panicCallback))
   453  
   454  		return nil
   455  	}
   456  }
   457  
   458  // WithTraceTable appends trace.Table into table traces
   459  func WithTraceTable(t trace.Table, opts ...trace.TableComposeOption) Option { //nolint:gocritic
   460  	return func(ctx context.Context, c *Driver) error {
   461  		c.tableOptions = append(
   462  			c.tableOptions,
   463  			tableConfig.WithTrace(
   464  				&t,
   465  				append(
   466  					[]trace.TableComposeOption{
   467  						trace.WithTablePanicCallback(c.panicCallback),
   468  					},
   469  					opts...,
   470  				)...,
   471  			),
   472  		)
   473  
   474  		return nil
   475  	}
   476  }
   477  
   478  // WithTraceScripting scripting trace option
   479  func WithTraceScripting(t trace.Scripting, opts ...trace.ScriptingComposeOption) Option {
   480  	return func(ctx context.Context, c *Driver) error {
   481  		c.scriptingOptions = append(
   482  			c.scriptingOptions,
   483  			scriptingConfig.WithTrace(
   484  				t,
   485  				append(
   486  					[]trace.ScriptingComposeOption{
   487  						trace.WithScriptingPanicCallback(c.panicCallback),
   488  					},
   489  					opts...,
   490  				)...,
   491  			),
   492  		)
   493  
   494  		return nil
   495  	}
   496  }
   497  
   498  // WithTraceScheme returns scheme trace option
   499  func WithTraceScheme(t trace.Scheme, opts ...trace.SchemeComposeOption) Option {
   500  	return func(ctx context.Context, c *Driver) error {
   501  		c.schemeOptions = append(
   502  			c.schemeOptions,
   503  			schemeConfig.WithTrace(
   504  				t,
   505  				append(
   506  					[]trace.SchemeComposeOption{
   507  						trace.WithSchemePanicCallback(c.panicCallback),
   508  					},
   509  					opts...,
   510  				)...,
   511  			),
   512  		)
   513  
   514  		return nil
   515  	}
   516  }
   517  
   518  // WithTraceCoordination returns coordination trace option
   519  func WithTraceCoordination(t trace.Coordination, opts ...trace.CoordinationComposeOption) Option {
   520  	return func(ctx context.Context, c *Driver) error {
   521  		c.coordinationOptions = append(
   522  			c.coordinationOptions,
   523  			coordinationConfig.WithTrace(
   524  				t,
   525  				append(
   526  					[]trace.CoordinationComposeOption{
   527  						trace.WithCoordinationPanicCallback(c.panicCallback),
   528  					},
   529  					opts...,
   530  				)...,
   531  			),
   532  		)
   533  
   534  		return nil
   535  	}
   536  }
   537  
   538  // WithTraceRatelimiter returns ratelimiter trace option
   539  func WithTraceRatelimiter(t trace.Ratelimiter, opts ...trace.RatelimiterComposeOption) Option {
   540  	return func(ctx context.Context, c *Driver) error {
   541  		c.ratelimiterOptions = append(
   542  			c.ratelimiterOptions,
   543  			ratelimiterConfig.WithTrace(
   544  				t,
   545  				append(
   546  					[]trace.RatelimiterComposeOption{
   547  						trace.WithRatelimiterPanicCallback(c.panicCallback),
   548  					},
   549  					opts...,
   550  				)...,
   551  			),
   552  		)
   553  
   554  		return nil
   555  	}
   556  }
   557  
   558  // WithRatelimiterOptions returns reatelimiter option
   559  func WithRatelimiterOptions(opts ...ratelimiterConfig.Option) Option {
   560  	return func(ctx context.Context, c *Driver) error {
   561  		c.ratelimiterOptions = append(c.ratelimiterOptions, opts...)
   562  
   563  		return nil
   564  	}
   565  }
   566  
   567  // WithTraceDiscovery adds configured discovery tracer to Driver
   568  func WithTraceDiscovery(t trace.Discovery, opts ...trace.DiscoveryComposeOption) Option {
   569  	return func(ctx context.Context, c *Driver) error {
   570  		c.discoveryOptions = append(
   571  			c.discoveryOptions,
   572  			discoveryConfig.WithTrace(
   573  				t,
   574  				append(
   575  					[]trace.DiscoveryComposeOption{
   576  						trace.WithDiscoveryPanicCallback(c.panicCallback),
   577  					},
   578  					opts...,
   579  				)...,
   580  			),
   581  		)
   582  
   583  		return nil
   584  	}
   585  }
   586  
   587  // WithTraceTopic adds configured discovery tracer to Driver
   588  func WithTraceTopic(t trace.Topic, opts ...trace.TopicComposeOption) Option { //nolint:gocritic
   589  	return func(ctx context.Context, c *Driver) error {
   590  		c.topicOptions = append(
   591  			c.topicOptions,
   592  			topicoptions.WithTrace(
   593  				t,
   594  				append(
   595  					[]trace.TopicComposeOption{
   596  						trace.WithTopicPanicCallback(c.panicCallback),
   597  					},
   598  					opts...,
   599  				)...,
   600  			),
   601  		)
   602  
   603  		return nil
   604  	}
   605  }
   606  
   607  // WithTraceDatabaseSQL adds configured discovery tracer to Driver
   608  func WithTraceDatabaseSQL(t trace.DatabaseSQL, opts ...trace.DatabaseSQLComposeOption) Option { //nolint:gocritic
   609  	return func(ctx context.Context, c *Driver) error {
   610  		c.databaseSQLOptions = append(
   611  			c.databaseSQLOptions,
   612  			xsql.WithTrace(
   613  				&t,
   614  				append(
   615  					[]trace.DatabaseSQLComposeOption{
   616  						trace.WithDatabaseSQLPanicCallback(c.panicCallback),
   617  					},
   618  					opts...,
   619  				)...,
   620  			),
   621  		)
   622  
   623  		return nil
   624  	}
   625  }
   626  
   627  // Private technical options for correct copies processing
   628  
   629  func withOnClose(onClose func(c *Driver)) Option {
   630  	return func(ctx context.Context, c *Driver) error {
   631  		c.onClose = append(c.onClose, onClose)
   632  
   633  		return nil
   634  	}
   635  }
   636  
   637  func withConnPool(pool *conn.Pool) Option {
   638  	return func(ctx context.Context, c *Driver) error {
   639  		c.pool = pool
   640  
   641  		return pool.Take(ctx)
   642  	}
   643  }