internal/conf/config.go (178 lines of code) (raw):
package conf
import (
"errors"
"github.com/BurntSushi/toml"
"github.com/aliyun/alibabacloud-kms-agent/internal/model"
"strings"
)
var (
DefaultHttpPort = 2025
DefaultDisableSSRFToken = false
DefaultSSRFHeaders = []string{"X-KMS-Token", "X-Vault-Token"}
DefaultSSRFEnvVariables = []string{"KMS_TOKEN", "KMS_SESSION_TOKEN", "KMS_CONTAINER_AUTHORIZATION_TOKEN"}
DefaultPathPrefix = "/v1/"
DefaultMaxConnections = 800
DefaultResponseType = 0
DefaultIgnoreTransientErrors = true
DefaultRegion = "cn-hangzhou"
DefaultEndpoint = ""
DefaultCaPathFile = ""
DefaultCache = "InMemory"
DefaultTtlSeconds = 300
DefaultCacheSize = 1000
DefaultEnableLRU = false
DefaultLogLevel = "Debug"
DefaultLogPath = "./logs/"
DefaultLogSize = 200 // MB
DefaultLogBackups = 3
InvalidConfigErrMsg = "invalid config error"
InvalidHttpPortErrMsg = "invalid HTTP port"
InvalidTtlSecondsErrMsg = "invalid TTL seconds"
InvalidCacheSizeErrMsg = "invalid cache size"
InvalidMaxConnectionErrMsg = "invalid max connections"
InvalidPathPrefixErrMsg = "invalid prefix"
EmptySSRFHeadersErrMsg = "empty ssrf headers"
EmptySSRFEnvVariablesErrMsg = "empty ssrf envs"
InvalidResponseType = "invalid response type"
)
type Config struct {
Server ServerConfig `toml:"Server"`
Kms KmsConfig `toml:"Kms"`
Cache CacheConfig `toml:"Cache"`
Log LogConfig `toml:"Log"`
}
type ServerConfig struct {
HttpPort *int `toml:"HttpPort,omitempty"`
DisableSSRFToken *bool `toml:"DisableSSRFToken,omitempty"`
SSRFHeaders *[]string `toml:"SSRFHeaders,omitempty"`
SSRFEnvVariables *[]string `toml:"SSRFEnvVariables,omitempty"`
PathPrefix *string `toml:"PathPrefix,omitempty"`
MaxConn *int `toml:"MaxConn,omitempty"`
ResponseType *int `toml:"ResponseType,omitempty"`
IgnoreTransientErrors *bool `toml:"IgnoreTransientErrors,omitempty"`
}
type KmsConfig struct {
Region *string `toml:"Region,omitempty"`
Endpoint *string `toml:"Endpoint,omitempty"`
CaFilePath *string `toml:"CaFilePath,omitempty"`
}
type CacheConfig struct {
CacheType *string `toml:"CacheType,omitempty"`
TtlSeconds *int `toml:"TtlSeconds,omitempty"`
CacheSize *int `toml:"CacheSize,omitempty"`
EnableLRU *bool `toml:"EnableLRU,omitempty"`
}
type LogConfig struct {
LogLevel *string `toml:"LogLevel,omitempty"`
LogPath *string `toml:"LogPath,omitempty"`
MaxSize *int `toml:"MaxSize,omitempty"`
MaxBackups *int `toml:"MaxBackups,omitempty"`
}
func LoadConfigFormFile(configPath string) (Config, error) {
var cfg = Config{}
_, err := toml.DecodeFile(configPath, &cfg)
if err != nil {
return Config{}, errors.New(InvalidConfigErrMsg)
}
setDefaults(&cfg)
err = validateConfig(cfg)
if err != nil {
return Config{}, err
}
return cfg, nil
}
func DefaultConfig() Config {
c := Config{}
setDefaults(&c)
return c
}
func setDefaults(c *Config) {
// server
if c.Server.HttpPort == nil {
c.Server.HttpPort = &DefaultHttpPort
}
if c.Server.DisableSSRFToken == nil {
c.Server.DisableSSRFToken = &DefaultDisableSSRFToken
}
if c.Server.SSRFHeaders == nil {
c.Server.SSRFHeaders = &DefaultSSRFHeaders
}
if c.Server.SSRFEnvVariables == nil {
c.Server.SSRFEnvVariables = &DefaultSSRFEnvVariables
}
if c.Server.PathPrefix == nil {
c.Server.PathPrefix = &DefaultPathPrefix
}
if c.Server.MaxConn == nil {
c.Server.MaxConn = &DefaultMaxConnections
}
if c.Server.ResponseType == nil {
c.Server.ResponseType = &DefaultResponseType
}
if c.Server.IgnoreTransientErrors == nil {
c.Server.IgnoreTransientErrors = &DefaultIgnoreTransientErrors
}
// kms
if c.Kms.Region == nil {
c.Kms.Region = &DefaultRegion
}
if c.Kms.Endpoint == nil {
c.Kms.Endpoint = &DefaultEndpoint
}
if c.Kms.CaFilePath == nil {
c.Kms.CaFilePath = &DefaultCaPathFile
}
// cache
if c.Cache.CacheType == nil {
c.Cache.CacheType = &DefaultCache
}
if c.Cache.TtlSeconds == nil || *c.Cache.TtlSeconds == 0 {
c.Cache.TtlSeconds = &DefaultTtlSeconds
}
if c.Cache.CacheSize == nil {
c.Cache.CacheSize = &DefaultCacheSize
}
if c.Cache.EnableLRU == nil {
c.Cache.EnableLRU = &DefaultEnableLRU
}
// log
if c.Log.LogLevel == nil {
c.Log.LogLevel = &DefaultLogLevel
}
if c.Log.LogPath == nil {
c.Log.LogPath = &DefaultLogPath
}
if c.Log.MaxSize == nil {
c.Log.MaxSize = &DefaultLogSize
}
if c.Log.MaxBackups == nil {
c.Log.MaxBackups = &DefaultLogBackups
}
}
func validateConfig(c Config) (err error) {
// server
if *c.Server.HttpPort <= 0 || *c.Server.HttpPort > 65535 {
return errors.New(InvalidHttpPortErrMsg)
}
if !*c.Server.DisableSSRFToken {
if len(*c.Server.SSRFHeaders) == 0 {
return errors.New(EmptySSRFHeadersErrMsg)
}
if len(*c.Server.SSRFEnvVariables) == 0 {
return errors.New(EmptySSRFEnvVariablesErrMsg)
}
}
if !strings.HasPrefix(*c.Server.PathPrefix, "/") {
return errors.New(InvalidPathPrefixErrMsg)
}
if *c.Server.MaxConn <= 0 || *c.Server.MaxConn > 1000 {
return errors.New(InvalidMaxConnectionErrMsg)
}
if model.ResponseType(*c.Server.ResponseType) != model.ResponseTypeForAliyunKMS &&
model.ResponseType(*c.Server.ResponseType) != model.ResponseTypeForAWSSecretManager &&
model.ResponseType(*c.Server.ResponseType) != model.ResponseTypeForVaultKvSecret {
return errors.New(InvalidResponseType)
}
// cache
if *c.Cache.TtlSeconds < 0 {
return errors.New(InvalidTtlSecondsErrMsg)
}
if *c.Cache.CacheSize < 0 || *c.Cache.CacheSize > 1000 {
return errors.New(InvalidCacheSizeErrMsg)
}
return nil
}