in go/adbc/driver/snowflake/snowflake_database.go [182:460]
func (d *databaseImpl) SetOptionInternal(k string, v string, cnOptions *map[string]string) error {
var err error
var ok bool
switch k {
case adbc.OptionKeyUsername:
d.cfg.User = v
case adbc.OptionKeyPassword:
d.cfg.Password = v
case OptionDatabase:
d.cfg.Database = v
case OptionSchema:
d.cfg.Schema = v
case OptionWarehouse:
d.cfg.Warehouse = v
case OptionRole:
d.cfg.Role = v
case OptionRegion:
d.cfg.Region = v
case OptionAccount:
d.cfg.Account = v
case OptionProtocol:
d.cfg.Protocol = v
case OptionHost:
d.cfg.Host = v
case OptionPort:
d.cfg.Port, err = strconv.Atoi(v)
if err != nil {
return adbc.Error{
Msg: "error encountered parsing Port option: " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
case OptionAuthType:
d.cfg.Authenticator, ok = authTypeMap[v]
if !ok {
return adbc.Error{
Msg: "invalid option value for " + OptionAuthType + ": '" + v + "'",
Code: adbc.StatusInvalidArgument,
}
}
case OptionLoginTimeout:
dur, err := time.ParseDuration(v)
if err != nil {
return adbc.Error{
Msg: "could not parse duration for '" + OptionLoginTimeout + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
if dur < 0 {
dur = -dur
}
d.cfg.LoginTimeout = dur
case OptionRequestTimeout:
dur, err := time.ParseDuration(v)
if err != nil {
return adbc.Error{
Msg: "could not parse duration for '" + OptionRequestTimeout + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
if dur < 0 {
dur = -dur
}
d.cfg.RequestTimeout = dur
case OptionJwtExpireTimeout:
dur, err := time.ParseDuration(v)
if err != nil {
return adbc.Error{
Msg: "could not parse duration for '" + OptionJwtExpireTimeout + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
if dur < 0 {
dur = -dur
}
d.cfg.JWTExpireTimeout = dur
case OptionClientTimeout:
dur, err := time.ParseDuration(v)
if err != nil {
return adbc.Error{
Msg: "could not parse duration for '" + OptionClientTimeout + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
if dur < 0 {
dur = -dur
}
d.cfg.ClientTimeout = dur
case OptionApplicationName:
if !strings.HasPrefix(v, "[ADBC]") {
v = d.defaultAppName + v
}
d.cfg.Application = v
case OptionSSLSkipVerify:
switch v {
case adbc.OptionValueEnabled:
d.cfg.DisableOCSPChecks = true
case adbc.OptionValueDisabled:
d.cfg.DisableOCSPChecks = false
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionOCSPFailOpenMode:
switch v {
case adbc.OptionValueEnabled:
d.cfg.OCSPFailOpen = gosnowflake.OCSPFailOpenTrue
case adbc.OptionValueDisabled:
d.cfg.OCSPFailOpen = gosnowflake.OCSPFailOpenFalse
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionAuthToken:
d.cfg.Token = v
case OptionAuthOktaUrl:
d.cfg.OktaURL, err = url.Parse(v)
if err != nil {
return adbc.Error{
Msg: fmt.Sprintf("error parsing URL for database option '%s': '%s'", k, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionKeepSessionAlive:
switch v {
case adbc.OptionValueEnabled:
d.cfg.KeepSessionAlive = true
case adbc.OptionValueDisabled:
d.cfg.KeepSessionAlive = false
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionDisableTelemetry:
switch v {
case adbc.OptionValueEnabled:
d.cfg.DisableTelemetry = true
case adbc.OptionValueDisabled:
d.cfg.DisableTelemetry = false
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionJwtPrivateKey:
data, err := os.ReadFile(v)
if err != nil {
return adbc.Error{
Msg: "could not read private key file '" + v + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
var block []byte
if strings.Contains(string(data), "PRIVATE KEY") {
b, _ := pem.Decode(data)
block = b.Bytes
} else {
block = data
}
var key *rsa.PrivateKey
key, err = x509.ParsePKCS1PrivateKey(block)
if err != nil && strings.Contains(err.Error(), "use ParsePKCS8PrivateKey instead") {
var pkcs8Key any
pkcs8Key, err = x509.ParsePKCS8PrivateKey(block)
key, ok = pkcs8Key.(*rsa.PrivateKey)
if !ok {
err = errors.New("file does not contain an RSA private key")
}
}
if err != nil {
return adbc.Error{
Msg: "failed parsing private key file '" + v + "': " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
d.cfg.PrivateKey = key
case OptionJwtPrivateKeyPkcs8Value:
block, _ := pem.Decode([]byte(v))
if block == nil {
return adbc.Error{
Msg: "Failed to parse PEM block containing the private key",
Code: adbc.StatusInvalidArgument,
}
}
var parsedKey any
switch block.Type {
case "ENCRYPTED PRIVATE KEY":
if cnOptions == nil {
return adbc.Error{
Msg: "[Snowflake] unable to set private key post initialization",
Code: adbc.StatusInvalidArgument,
}
}
passcode, ok := (*cnOptions)[OptionJwtPrivateKeyPkcs8Password]
if ok {
parsedKey, err = pkcs8.ParsePKCS8PrivateKey(block.Bytes, []byte(passcode))
} else {
return adbc.Error{
Msg: OptionJwtPrivateKeyPkcs8Password + " is not configured",
Code: adbc.StatusInvalidArgument,
}
}
case "PRIVATE KEY":
parsedKey, err = pkcs8.ParsePKCS8PrivateKey(block.Bytes)
default:
return adbc.Error{
Msg: block.Type + " is not supported",
Code: adbc.StatusInvalidArgument,
}
}
if err != nil {
return adbc.Error{
Msg: "[Snowflake] failed parsing PKCS8 private key: " + err.Error(),
Code: adbc.StatusInvalidArgument,
}
}
d.cfg.PrivateKey = parsedKey.(*rsa.PrivateKey)
case OptionClientRequestMFAToken:
switch v {
case adbc.OptionValueEnabled:
d.cfg.ClientRequestMfaToken = gosnowflake.ConfigBoolTrue
case adbc.OptionValueDisabled:
d.cfg.ClientRequestMfaToken = gosnowflake.ConfigBoolFalse
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionClientStoreTempCred:
switch v {
case adbc.OptionValueEnabled:
d.cfg.ClientStoreTemporaryCredential = gosnowflake.ConfigBoolTrue
case adbc.OptionValueDisabled:
d.cfg.ClientStoreTemporaryCredential = gosnowflake.ConfigBoolFalse
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, v),
Code: adbc.StatusInvalidArgument,
}
}
case OptionLogTracing:
d.cfg.Tracing = v
case OptionClientConfigFile:
d.cfg.ClientConfigFile = v
case OptionUseHighPrecision:
switch v {
case adbc.OptionValueEnabled:
d.useHighPrecision = true
case adbc.OptionValueDisabled:
d.useHighPrecision = false
default:
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionUseHighPrecision, v),
Code: adbc.StatusInvalidArgument,
}
}
default:
d.cfg.Params[k] = &v
}
return nil
}