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 }