1
0
mirror of https://github.com/quay/quay.git synced 2026-01-26 06:21:37 +03:00
Files
Michaela Lang 2c24975dbb federationuser(ldap): fixing keepalive settings for LDAP connections (PROJQUAY-5137) (#2440)
fixed field names for keepalive attributes.

* scenario1: config-tool empty configuration
** expectation: empty config for DB_CONNECTION_ARGS
```
$ curl -s http://localhost/api/v1/config | jq -r '."config.yaml".DB_CONNECTION_ARGS'
{}
```

* scenario2: config-tool with populated DB_CONNECTION_ARGS
** expectation: values are returned in DB_CONNECTION_ARGS
```
$ curl -s http://localhost/api/v1/config | jq -r '."config.yaml".DB_CONNECTION_ARGS'
{
  "autorollback": true,
  "keepalives": 1,
  "keepalives_count": 5,
  "keepalives_idle": 3,
  "keepalives_interval": 4,
  "max_connections": 30,
  "sslcompression": 1,
  "stale_timeout": 300,
  "tcp_user_timeout": 1000
}
```

* scenario3: config-tool with populated DB_CONNECTION_ARGS wrong type
** expectation: config-tool validate will bailout the wrong type in the
parameter
```
$ podman run -ti --rm --name config-tool -v config.yaml:/tmp/config.yaml config-tool:latest validate --configDir /tmp -m online
FATA[0000] An error occurred during validation. Process could not marshal config.yaml. This is most likely due to an incorrect type.
More info: keepalives must be of type int
```
2023-11-07 16:58:30 +01:00

247 lines
8.6 KiB
Go

package database
import (
"errors"
"github.com/creasty/defaults"
)
// DatabaseFieldGroup represents the DatabaseFieldGroup config fields
type DatabaseFieldGroup struct {
DbConnectionArgs *DbConnectionArgsStruct `default:"{}" json:"DB_CONNECTION_ARGS,omitempty" yaml:"DB_CONNECTION_ARGS,omitempty"`
DbUri string `default:"" validate:"" json:"DB_URI,omitempty" yaml:"DB_URI,omitempty"`
}
// DbConnectionArgsStruct represents the DbConnectionArgsStruct config fields
type DbConnectionArgsStruct struct {
// MySQL arguments
Ssl *SslStruct `default:"" json:"ssl,omitempty" yaml:"ssl,omitempty"`
Threadlocals bool `default:"" json:"threadlocals,omitempty" yaml:"threadlocals,omitempty"`
Autorollback bool `default:"" json:"autorollback,omitempty" yaml:"autorollback,omitempty"`
// Postgres arguments
SslRootCert string `default:"" json:"sslrootcert,omitempty" yaml:"sslrootcert,omitempty"`
SslMode string `default:"" json:"sslmode,omitempty" yaml:"sslmode,omitempty"`
SslCert string `default:"" json:"sslcert,omitempty" yaml:"sslcert,omitempty"`
SslKey string `default:"" json:"sslkey,omitempty" yaml:"sslkey,omitempty"`
SslSni string `default:"" json:"sslsni,omitempty" yaml:"sslsni,omitempty"`
SslMinProtocolVersion string `default:"" json:"ssl_min_protocol_version,omitempty" yaml:"ssl_min_protocol_version,omitempty"`
SslMaxProtocolVersion string `default:"" json:"ssl_max_protocol_version,omitempty" yaml:"ssl_max_protocol_version,omitempty"`
SslCrl string `default:"" json:"sslcrl,omitempty" yaml:"sslcrl,omitempty"`
SslCrlDir string `default:"" json:"sslcrldir,omitempty" yaml:"sslcrldir,omitempty"`
SslCompression *int `default:"" json:"sslcompression,omitempty" yaml:"sslcompression,omitempty"`
// Network arguments
Keepalives *int `default:"" json:"keepalives,omitempty" yaml:"keepalives,omitempty"`
Keepalives_Idle *int `default:"" json:"keepalives_idle,omitempty" yaml:"keepalives_idle,omitempty"`
Keepalives_Interval *int `default:"" json:"keepalives_interval,omitempty" yaml:"keepalives_interval,omitempty"`
Keepalives_Count *int `default:"" json:"keepalives_count,omitempty" yaml:"keepalives_count,omitempty"`
Tcp_User_Timeout *int `default:"" json:"tcp_user_timeout,omitempty" yaml:"tcp_user_timeout,omitempty"`
}
// SslStruct represents the SslStruct config fields
type SslStruct struct {
Ca string `default:"" validate:"" json:"ca,omitempty" yaml:"ca,omitempty"`
}
// NewDatabaseFieldGroup creates a new DatabaseFieldGroup
func NewDatabaseFieldGroup(fullConfig map[string]interface{}) (*DatabaseFieldGroup, error) {
newDatabaseFieldGroup := &DatabaseFieldGroup{}
defaults.Set(newDatabaseFieldGroup)
if value, ok := fullConfig["DB_CONNECTION_ARGS"]; ok {
var err error
value := value.(map[string]interface{})
newDatabaseFieldGroup.DbConnectionArgs, err = NewDbConnectionArgsStruct(value)
if err != nil {
return newDatabaseFieldGroup, err
}
}
if value, ok := fullConfig["DB_URI"]; ok {
newDatabaseFieldGroup.DbUri, ok = value.(string)
if !ok {
return newDatabaseFieldGroup, errors.New("DB_URI must be of type string")
}
}
return newDatabaseFieldGroup, nil
}
// function to ensure supported TLS versions are used in Postgres connection URI
func IsValidTLS(version string) bool {
switch version {
case
"TLSv1",
"TLSv1.1",
"TLSv1.2",
"TLSv1.3":
return true
}
return false
}
// NewDbConnectionArgsStruct creates a new DbConnectionArgsStruct
func NewDbConnectionArgsStruct(fullConfig map[string]interface{}) (*DbConnectionArgsStruct, error) {
newDbConnectionArgsStruct := &DbConnectionArgsStruct{}
defaults.Set(newDbConnectionArgsStruct)
if value, ok := fullConfig["ssl"]; ok {
var err error
value := value.(map[string]interface{})
newDbConnectionArgsStruct.Ssl, err = NewSslStruct(value)
if err != nil {
return newDbConnectionArgsStruct, err
}
}
if value, ok := fullConfig["threadlocals"]; ok {
newDbConnectionArgsStruct.Threadlocals, ok = value.(bool)
if !ok {
return newDbConnectionArgsStruct, errors.New("threadlocals must be of type bool")
}
}
if value, ok := fullConfig["autorollback"]; ok {
newDbConnectionArgsStruct.Autorollback, ok = value.(bool)
if !ok {
return newDbConnectionArgsStruct, errors.New("autorollback must be of type bool")
}
}
if value, ok := fullConfig["sslmode"]; ok {
newDbConnectionArgsStruct.SslMode, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslmode must be of type string")
}
}
if value, ok := fullConfig["sslrootcert"]; ok {
newDbConnectionArgsStruct.SslRootCert, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslrootcert must be of type string")
}
}
if value, ok := fullConfig["sslcert"]; ok {
newDbConnectionArgsStruct.SslCert, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcert must be of type string")
}
}
if value, ok := fullConfig["sslkey"]; ok {
newDbConnectionArgsStruct.SslKey, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslkey must be of type string")
}
}
if value, ok := fullConfig["sslsni"]; ok {
newDbConnectionArgsStruct.SslSni, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslsni must be of type string")
}
}
if value, ok := fullConfig["ssl_min_protocolversion"]; ok {
newDbConnectionArgsStruct.SslMinProtocolVersion, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("ssl_min_protoclversion must be of type string")
}
if !IsValidTLS(value.(string)) {
return newDbConnectionArgsStruct, errors.New("ssl_min_protoclversion invalid value (supported TLSv1,TLSv1.1-TLSv1.3)")
}
}
if value, ok := fullConfig["ssl_max_protocolversion"]; ok {
newDbConnectionArgsStruct.SslMaxProtocolVersion, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("ssl_max_protoclversion must be of type string")
}
if !IsValidTLS(value.(string)) {
return newDbConnectionArgsStruct, errors.New("ssl_max_protoclversion invalid value (supported TLSv1,TLSv1.1-TLSv1.3)")
}
}
if value, ok := fullConfig["sslcrl"]; ok {
newDbConnectionArgsStruct.SslCrl, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcrl must be of type string")
}
}
if value, ok := fullConfig["sslcrldir"]; ok {
newDbConnectionArgsStruct.SslCrlDir, ok = value.(string)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcrldir must be of type string")
}
}
if value, ok := fullConfig["sslcompression"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("sslcompression must be of type int")
}
}
newDbConnectionArgsStruct.SslCompression = &val
}
if value, ok := fullConfig["keepalives"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives = &val
}
if value, ok := fullConfig["keepalives_idle"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_idle must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Idle = &val
}
if value, ok := fullConfig["keepalives_interval"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_interval must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Interval = &val
}
if value, ok := fullConfig["keepalives_count"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("keepalives_count must be of type int")
}
}
newDbConnectionArgsStruct.Keepalives_Count = &val
}
if value, ok := fullConfig["tcp_user_timeout"]; ok {
val, ok := value.(int)
if !ok {
_, ok = value.(int)
if !ok {
return newDbConnectionArgsStruct, errors.New("tcp_user_timeout must be of type int")
}
}
newDbConnectionArgsStruct.Tcp_User_Timeout = &val
}
return newDbConnectionArgsStruct, nil
}
// NewSslStruct creates a new SslStruct
func NewSslStruct(fullConfig map[string]interface{}) (*SslStruct, error) {
newSslStruct := &SslStruct{}
defaults.Set(newSslStruct)
if value, ok := fullConfig["ca"]; ok {
newSslStruct.Ca, ok = value.(string)
if !ok {
return newSslStruct, errors.New("ca must be of type string")
}
}
return newSslStruct, nil
}