frostfs-s3-gw/cmd/s3-gw/app-settings.go

268 lines
6.8 KiB
Go
Raw Normal View History

2020-07-06 09:18:16 +00:00
package main
import (
"fmt"
"io"
"os"
"sort"
2020-07-06 09:18:16 +00:00
"strconv"
"strings"
"time"
"github.com/nspcc-dev/neofs-s3-gw/internal/version"
"github.com/nspcc-dev/neofs-sdk-go/pkg/pool"
2020-07-06 09:18:16 +00:00
"github.com/spf13/pflag"
"github.com/spf13/viper"
"go.uber.org/zap"
)
const (
devNull = empty(0)
2020-07-06 09:18:16 +00:00
minimumTTLInMinutes = 5
defaultTTL = minimumTTLInMinutes * time.Minute
2020-07-12 23:00:47 +00:00
defaultRebalanceTimer = 15 * time.Second
defaultRequestTimeout = 15 * time.Second
defaultConnectTimeout = 30 * time.Second
defaultShutdownTimeout = 15 * time.Second
2020-07-06 09:18:16 +00:00
defaultKeepaliveTime = 10 * time.Second
defaultKeepaliveTimeout = 10 * time.Second
defaultMaxClientsCount = 100
defaultMaxClientsDeadline = time.Second * 30
2020-07-06 09:18:16 +00:00
)
2021-05-13 19:25:32 +00:00
const ( // Settings.
// Logger.
2020-07-07 11:25:13 +00:00
cfgLoggerLevel = "logger.level"
cfgLoggerFormat = "logger.format"
cfgLoggerTraceLevel = "logger.trace_level"
cfgLoggerNoCaller = "logger.no_caller"
2020-07-07 11:25:13 +00:00
cfgLoggerNoDisclaimer = "logger.no_disclaimer"
cfgLoggerSamplingInitial = "logger.sampling.initial"
cfgLoggerSamplingThereafter = "logger.sampling.thereafter"
2021-05-13 19:25:32 +00:00
// Keys.
cfgNeoFSPrivateKey = "neofs-key"
cfgGateAuthPrivateKey = "auth-key"
2021-05-13 19:25:32 +00:00
// HTTPS/TLS.
cfgTLSKeyFile = "tls.key_file"
cfgTLSCertFile = "tls.cert_file"
2021-05-13 19:25:32 +00:00
// Timeouts.
2020-07-07 11:25:13 +00:00
cfgConnectionTTL = "con_ttl"
cfgConnectTimeout = "connect_timeout"
cfgRequestTimeout = "request_timeout"
cfgRebalanceTimer = "rebalance_timer"
2021-05-13 19:25:32 +00:00
// MaxClients.
cfgMaxClientsCount = "max_clients_count"
cfgMaxClientsDeadline = "max_clients_deadline"
2021-05-13 19:25:32 +00:00
// gRPC.
cfgGRPCVerbose = "verbose"
2020-07-07 11:25:13 +00:00
2021-05-13 19:25:32 +00:00
// Metrics / Profiler / Web.
2020-07-07 11:25:13 +00:00
cfgEnableMetrics = "metrics"
cfgEnableProfiler = "pprof"
cfgListenAddress = "listen_address"
cfgListenDomains = "listen_domains"
2020-07-07 11:25:13 +00:00
2021-05-13 19:25:32 +00:00
// Peers.
cfgPeers = "peers"
2021-05-13 19:25:32 +00:00
// Application.
2020-07-07 11:25:13 +00:00
cfgApplicationName = "app.name"
cfgApplicationVersion = "app.version"
cfgApplicationBuildTime = "app.build_time"
2021-05-13 19:25:32 +00:00
// Command line args.
cmdHelp = "help"
cmdVersion = "version"
// applicationName is gateway name.
applicationName = "neofs-s3-gw"
// envPrefix is environment variables prefix used for configuration.
envPrefix = "S3_GW"
2020-07-07 11:25:13 +00:00
)
type empty int
var ignore = map[string]struct{}{
cfgApplicationName: {},
cfgApplicationVersion: {},
cfgApplicationBuildTime: {},
cfgPeers: {},
cmdHelp: {},
cmdVersion: {},
}
2020-07-06 09:18:16 +00:00
func (empty) Read([]byte) (int, error) { return 0, io.EOF }
func fetchPeers(l *zap.Logger, v *viper.Viper) *pool.Builder {
pb := new(pool.Builder)
2020-07-07 11:25:13 +00:00
for i := 0; ; i++ {
key := cfgPeers + "." + strconv.Itoa(i) + "."
2020-07-07 11:25:13 +00:00
address := v.GetString(key + "address")
weight := v.GetFloat64(key + "weight")
if address == "" {
l.Warn("skip, empty address")
break
}
if weight <= 0 { // unspecified or wrong
weight = 1
}
pb.AddNode(address, weight)
2020-07-07 11:25:13 +00:00
l.Info("added connection peer",
zap.String("address", address),
zap.Float64("weight", weight))
2020-07-07 11:25:13 +00:00
}
return pb
2020-07-07 11:25:13 +00:00
}
func fetchDomains(v *viper.Viper) []string {
cnt := v.GetInt(cfgListenDomains + ".count")
res := make([]string, 0, cnt)
for i := 0; ; i++ {
domain := v.GetString(cfgListenDomains + "." + strconv.Itoa(i))
if domain == "" {
break
}
res = append(res, domain)
}
return res
}
2020-07-06 09:18:16 +00:00
func newSettings() *viper.Viper {
v := viper.New()
v.AutomaticEnv()
v.SetEnvPrefix(envPrefix)
2020-07-06 09:18:16 +00:00
v.SetConfigType("yaml")
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
// flags setup:
flags := pflag.NewFlagSet("commandline", pflag.ExitOnError)
flags.SetOutput(os.Stdout)
2020-07-06 09:18:16 +00:00
flags.SortFlags = false
2020-07-07 11:25:13 +00:00
flags.Bool(cfgEnableProfiler, false, "enable pprof")
flags.Bool(cfgEnableMetrics, false, "enable prometheus metrics")
2020-07-06 09:18:16 +00:00
help := flags.BoolP(cmdHelp, "h", false, "show help")
versionFlag := flags.BoolP(cmdVersion, "v", false, "show version")
2020-07-06 09:18:16 +00:00
flags.String(cfgNeoFSPrivateKey, "", "set value to hex string, WIF string, or path to NeoFS private key file")
flags.String(cfgGateAuthPrivateKey, "", "set path to file with auth (curve25519) private key to use in auth scheme")
2020-07-06 09:18:16 +00:00
flags.Bool(cfgGRPCVerbose, false, "set debug mode of gRPC connections")
flags.Duration(cfgRequestTimeout, defaultRequestTimeout, "set gRPC request timeout")
flags.Duration(cfgConnectTimeout, defaultConnectTimeout, "set gRPC connect timeout")
flags.Duration(cfgRebalanceTimer, defaultRebalanceTimer, "set gRPC connection rebalance timer")
2020-07-06 09:18:16 +00:00
flags.Int(cfgMaxClientsCount, defaultMaxClientsCount, "set max-clients count")
flags.Duration(cfgMaxClientsDeadline, defaultMaxClientsDeadline, "set max-clients deadline")
ttl := flags.DurationP(cfgConnectionTTL, "t", defaultTTL, "set gRPC connection time to live")
2020-07-06 09:18:16 +00:00
flags.String(cfgListenAddress, "0.0.0.0:8080", "set address to listen")
flags.String(cfgTLSCertFile, "", "TLS certificate file to use")
flags.String(cfgTLSKeyFile, "", "TLS key file to use")
peers := flags.StringArrayP(cfgPeers, "p", nil, "set NeoFS nodes")
2020-07-06 09:18:16 +00:00
domains := flags.StringArrayP(cfgListenDomains, "d", nil, "set domains to be listened")
2020-07-06 09:18:16 +00:00
// set prefers:
v.Set(cfgApplicationName, applicationName)
v.Set(cfgApplicationVersion, version.Version)
2020-07-06 09:18:16 +00:00
// set defaults:
// logger:
2020-07-07 11:25:13 +00:00
v.SetDefault(cfgLoggerLevel, "debug")
v.SetDefault(cfgLoggerFormat, "console")
2020-07-24 16:10:41 +00:00
v.SetDefault(cfgLoggerTraceLevel, "panic")
v.SetDefault(cfgLoggerNoCaller, false)
2020-07-07 11:25:13 +00:00
v.SetDefault(cfgLoggerNoDisclaimer, true)
v.SetDefault(cfgLoggerSamplingInitial, 1000)
v.SetDefault(cfgLoggerSamplingThereafter, 1000)
2020-07-06 09:18:16 +00:00
if err := v.BindPFlags(flags); err != nil {
panic(err)
}
if err := v.ReadConfig(devNull); err != nil {
panic(err)
}
if err := flags.Parse(os.Args); err != nil {
panic(err)
}
if peers != nil && len(*peers) > 0 {
for i := range *peers {
v.SetDefault(cfgPeers+"."+strconv.Itoa(i)+".address", (*peers)[i])
v.SetDefault(cfgPeers+"."+strconv.Itoa(i)+".weight", 1)
}
}
if domains != nil && len(*domains) > 0 {
for i := range *domains {
v.SetDefault(cfgListenDomains+"."+strconv.Itoa(i), (*domains)[i])
}
v.SetDefault(cfgListenDomains+".count", len(*domains))
}
2020-07-06 09:18:16 +00:00
switch {
case help != nil && *help:
fmt.Printf("NeoFS S3 gateway %s\n", version.Version)
2020-07-06 09:18:16 +00:00
flags.PrintDefaults()
fmt.Println()
fmt.Println("Default environments:")
fmt.Println()
keys := v.AllKeys()
sort.Strings(keys)
for i := range keys {
if _, ok := ignore[keys[i]]; ok {
continue
}
k := strings.Replace(keys[i], ".", "_", -1)
fmt.Printf("%s_%s = %v\n", envPrefix, strings.ToUpper(k), v.Get(keys[i]))
}
fmt.Println()
fmt.Println("Peers preset:")
fmt.Println()
fmt.Printf("%s_%s_[N]_ADDRESS = string\n", envPrefix, strings.ToUpper(cfgPeers))
fmt.Printf("%s_%s_[N]_WEIGHT = 0..1 (float)\n", envPrefix, strings.ToUpper(cfgPeers))
2020-07-06 09:18:16 +00:00
os.Exit(0)
case versionFlag != nil && *versionFlag:
fmt.Printf("NeoFS S3 gateway %s\n", version.Version)
2020-07-06 09:18:16 +00:00
os.Exit(0)
case ttl != nil && ttl.Minutes() < minimumTTLInMinutes:
fmt.Printf("connection ttl should not be less than %s", defaultTTL)
}
return v
}