in go/adbc/driver/flightsql/flightsql_adbc.go [199:378]
func (d *database) SetOptions(cnOptions map[string]string) error {
var tlsConfig tls.Config
mtlsCert := cnOptions[OptionMTLSCertChain]
mtlsKey := cnOptions[OptionMTLSPrivateKey]
switch {
case mtlsCert != "" && mtlsKey != "":
cert, err := tls.X509KeyPair([]byte(mtlsCert), []byte(mtlsKey))
if err != nil {
return adbc.Error{
Msg: fmt.Sprintf("Invalid mTLS certificate: %#v", err),
Code: adbc.StatusInvalidArgument,
}
}
tlsConfig.Certificates = []tls.Certificate{cert}
delete(cnOptions, OptionMTLSCertChain)
delete(cnOptions, OptionMTLSPrivateKey)
case mtlsCert != "":
return adbc.Error{
Msg: fmt.Sprintf("Must provide both '%s' and '%s', only provided '%s'", OptionMTLSCertChain, OptionMTLSPrivateKey, OptionMTLSCertChain),
Code: adbc.StatusInvalidArgument,
}
case mtlsKey != "":
return adbc.Error{
Msg: fmt.Sprintf("Must provide both '%s' and '%s', only provided '%s'", OptionMTLSCertChain, OptionMTLSPrivateKey, OptionMTLSPrivateKey),
Code: adbc.StatusInvalidArgument,
}
}
if hostname, ok := cnOptions[OptionSSLOverrideHostname]; ok {
tlsConfig.ServerName = hostname
delete(cnOptions, OptionSSLOverrideHostname)
}
if val, ok := cnOptions[OptionSSLSkipVerify]; ok {
if val == adbc.OptionValueEnabled {
tlsConfig.InsecureSkipVerify = true
} else if val == adbc.OptionValueDisabled {
tlsConfig.InsecureSkipVerify = false
} else {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionSSLSkipVerify, val),
Code: adbc.StatusInvalidArgument,
}
}
delete(cnOptions, OptionSSLSkipVerify)
}
if cert, ok := cnOptions[OptionSSLRootCerts]; ok {
cp := x509.NewCertPool()
if !cp.AppendCertsFromPEM([]byte(cert)) {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': failed to append certificates", OptionSSLRootCerts),
Code: adbc.StatusInvalidArgument,
}
}
tlsConfig.RootCAs = cp
delete(cnOptions, OptionSSLRootCerts)
}
d.creds = credentials.NewTLS(&tlsConfig)
if auth, ok := cnOptions[OptionAuthorizationHeader]; ok {
d.hdrs.Set("authorization", auth)
delete(cnOptions, OptionAuthorizationHeader)
}
if u, ok := cnOptions[adbc.OptionKeyUsername]; ok {
if d.hdrs.Len() > 0 {
return adbc.Error{
Msg: "Authorization header already provided, do not provide user/pass also",
Code: adbc.StatusInvalidArgument,
}
}
d.user = u
delete(cnOptions, adbc.OptionKeyUsername)
}
if p, ok := cnOptions[adbc.OptionKeyPassword]; ok {
if d.hdrs.Len() > 0 {
return adbc.Error{
Msg: "Authorization header already provided, do not provide user/pass also",
Code: adbc.StatusInvalidArgument,
}
}
d.pass = p
delete(cnOptions, adbc.OptionKeyPassword)
}
var err error
if tv, ok := cnOptions[OptionTimeoutFetch]; ok {
if d.timeout.fetchTimeout, err = getTimeoutOptionValue(tv); err != nil {
return adbc.Error{
Msg: fmt.Sprintf("invalid timeout option value %s = %s : %s",
OptionTimeoutFetch, tv, err.Error()),
Code: adbc.StatusInvalidArgument,
}
}
}
if tv, ok := cnOptions[OptionTimeoutQuery]; ok {
if d.timeout.queryTimeout, err = getTimeoutOptionValue(tv); err != nil {
return adbc.Error{
Msg: fmt.Sprintf("invalid timeout option value %s = %s : %s",
OptionTimeoutQuery, tv, err.Error()),
Code: adbc.StatusInvalidArgument,
}
}
}
if tv, ok := cnOptions[OptionTimeoutUpdate]; ok {
if d.timeout.updateTimeout, err = getTimeoutOptionValue(tv); err != nil {
return adbc.Error{
Msg: fmt.Sprintf("invalid timeout option value %s = %s : %s",
OptionTimeoutUpdate, tv, err.Error()),
Code: adbc.StatusInvalidArgument,
}
}
}
if val, ok := cnOptions[OptionWithBlock]; ok {
if val == adbc.OptionValueEnabled {
d.dialOpts.block = true
} else if val == adbc.OptionValueDisabled {
d.dialOpts.block = false
} else {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionWithBlock, val),
Code: adbc.StatusInvalidArgument,
}
}
delete(cnOptions, OptionWithBlock)
}
if val, ok := cnOptions[OptionWithMaxMsgSize]; ok {
var err error
var size int
if size, err = strconv.Atoi(val); err != nil {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s' is not a positive integer", OptionWithMaxMsgSize, val),
Code: adbc.StatusInvalidArgument,
}
} else if size <= 0 {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s' is not a positive integer", OptionWithMaxMsgSize, val),
Code: adbc.StatusInvalidArgument,
}
}
d.dialOpts.maxMsgSize = size
delete(cnOptions, OptionWithMaxMsgSize)
}
d.dialOpts.rebuild()
if val, ok := cnOptions[OptionCookieMiddleware]; ok {
if val == adbc.OptionValueEnabled {
d.enableCookies = true
} else if val == adbc.OptionValueDisabled {
d.enableCookies = false
} else {
return adbc.Error{
Msg: fmt.Sprintf("Invalid value for database option '%s': '%s'", OptionCookieMiddleware, val),
Code: adbc.StatusInvalidArgument,
}
}
delete(cnOptions, OptionCookieMiddleware)
}
for key, val := range cnOptions {
if strings.HasPrefix(key, OptionRPCCallHeaderPrefix) {
d.hdrs.Append(strings.TrimPrefix(key, OptionRPCCallHeaderPrefix), val)
continue
}
return adbc.Error{
Msg: fmt.Sprintf("Unknown database option '%s'", key),
Code: adbc.StatusInvalidArgument,
}
}
return nil
}