From 94b945e16d53850fedf38b5cbe6acb9596e16a29 Mon Sep 17 00:00:00 2001 From: Andrew Dunstall Date: Fri, 28 Jun 2024 06:01:49 +0100 Subject: [PATCH] config: add config defaults Adds 'config.Default()' to set default configuration rather than adding defaults to cobra flags. --- agent/config/config.go | 28 +++++++++--- cli/agent/command.go | 10 ++--- cli/forward/command.go | 8 ++-- cli/server/command.go | 6 +-- cli/workload/requests.go | 4 +- cli/workload/upstreams.go | 4 +- forward/config/config.go | 15 +++++-- pkg/gossip/config.go | 8 ++-- pkg/log/config.go | 4 +- server/auth/config.go | 10 ++--- server/config/config.go | 83 +++++++++++++++++++++++++----------- server/config/tls.go | 6 +-- workload/config/requests.go | 22 +++++++--- workload/config/upstreams.go | 24 ++++++++--- 14 files changed, 159 insertions(+), 73 deletions(-) diff --git a/agent/config/config.go b/agent/config/config.go index 17ad129..1cbbc1e 100644 --- a/agent/config/config.go +++ b/agent/config/config.go @@ -129,7 +129,7 @@ func (c *TLSConfig) RegisterFlags(fs *pflag.FlagSet, prefix string) { fs.StringVar( &c.RootCAs, prefix+"root-cas", - "", + c.RootCAs, ` A path to a certificate PEM file containing root certificiate authorities to validate the TLS connection to the Piko server. @@ -190,7 +190,7 @@ func (c *ConnectConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.URL, "connect.url", - "http://localhost:8001", + c.URL, ` The Piko server URL to connect to. Note this must be configured to use the Piko server 'upstream' port.`, @@ -199,7 +199,7 @@ Piko server 'upstream' port.`, fs.StringVar( &c.Token, "connect.token", - "", + c.Token, ` Token is a token to authenticate with the Piko server.`, ) @@ -207,7 +207,7 @@ Token is a token to authenticate with the Piko server.`, fs.DurationVar( &c.Timeout, "connect.timeout", - time.Second*30, + c.Timeout, ` Timeout attempting to connect to the Piko server on boot. Note if the agent is disconnected after the initial connection succeeds it will keep trying to @@ -233,7 +233,7 @@ func (c *ServerConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.BindAddr, "server.bind-addr", - ":5000", + c.BindAddr, ` The host/port to bind the server to. @@ -257,6 +257,22 @@ type Config struct { GracePeriod time.Duration `json:"grace_period" yaml:"grace_period"` } +func Default() *Config { + return &Config{ + Connect: ConnectConfig{ + URL: "http://localhost:8001", + Timeout: time.Second * 30, + }, + Server: ServerConfig{ + BindAddr: ":5000", + }, + Log: log.Config{ + Level: "info", + }, + GracePeriod: time.Minute, + } +} + func (c *Config) Validate() error { // Note don't validate the number of listeners, as some commands don't // require any. @@ -296,7 +312,7 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { fs.DurationVar( &c.GracePeriod, "grace-period", - time.Minute, + c.GracePeriod, ` Maximum duration after a shutdown signal is received (SIGTERM or SIGINT) to gracefully shutdown each listener. diff --git a/cli/agent/command.go b/cli/agent/command.go index 738ee52..57ecd9f 100644 --- a/cli/agent/command.go +++ b/cli/agent/command.go @@ -61,7 +61,7 @@ Examples: `, } - var conf config.Config + conf := config.Default() var loadConf pikoconfig.Config // Register flags and set default values. @@ -69,7 +69,7 @@ Examples: loadConf.RegisterFlags(cmd.PersistentFlags()) cmd.PersistentPreRun = func(_ *cobra.Command, _ []string) { - if err := loadConf.Load(&conf); err != nil { + if err := loadConf.Load(conf); err != nil { fmt.Println(err.Error()) os.Exit(1) } @@ -87,9 +87,9 @@ Examples: } } - cmd.AddCommand(newStartCommand(&conf)) - cmd.AddCommand(newHTTPCommand(&conf)) - cmd.AddCommand(newTCPCommand(&conf)) + cmd.AddCommand(newStartCommand(conf)) + cmd.AddCommand(newHTTPCommand(conf)) + cmd.AddCommand(newTCPCommand(conf)) return cmd } diff --git a/cli/forward/command.go b/cli/forward/command.go index ff3f122..b472529 100644 --- a/cli/forward/command.go +++ b/cli/forward/command.go @@ -42,7 +42,7 @@ Examples: `, } - var conf config.Config + conf := config.Default() var loadConf pikoconfig.Config // Register flags and set default values. @@ -50,7 +50,7 @@ Examples: loadConf.RegisterFlags(cmd.PersistentFlags()) cmd.PersistentPreRun = func(_ *cobra.Command, _ []string) { - if err := loadConf.Load(&conf); err != nil { + if err := loadConf.Load(conf); err != nil { fmt.Println(err.Error()) os.Exit(1) } @@ -61,8 +61,8 @@ Examples: } } - cmd.AddCommand(newStartCommand(&conf)) - cmd.AddCommand(newTCPCommand(&conf)) + cmd.AddCommand(newStartCommand(conf)) + cmd.AddCommand(newTCPCommand(conf)) return cmd } diff --git a/cli/server/command.go b/cli/server/command.go index c4ee3f5..deafa6f 100644 --- a/cli/server/command.go +++ b/cli/server/command.go @@ -71,7 +71,7 @@ Examples: `, } - var conf config.Config + conf := config.Default() var loadConf pikoconfig.Config // Register flags and set default values. @@ -81,7 +81,7 @@ Examples: var logger log.Logger cmd.PreRun = func(_ *cobra.Command, _ []string) { - if err := loadConf.Load(&conf); err != nil { + if err := loadConf.Load(conf); err != nil { fmt.Println(err.Error()) os.Exit(1) } @@ -135,7 +135,7 @@ Examples: } cmd.Run = func(_ *cobra.Command, _ []string) { - if err := runServer(&conf, logger); err != nil { + if err := runServer(conf, logger); err != nil { logger.Error("failed to run agent", zap.Error(err)) os.Exit(1) } diff --git a/cli/workload/requests.go b/cli/workload/requests.go index 0aa1b27..44c7574 100644 --- a/cli/workload/requests.go +++ b/cli/workload/requests.go @@ -50,7 +50,7 @@ Examples: `, } - var conf config.RequestsConfig + conf := config.DefaultRequestsConfig() // Register flags and set default values. conf.RegisterFlags(cmd.Flags()) @@ -67,7 +67,7 @@ Examples: os.Exit(1) } - if err := runRequests(&conf, logger); err != nil { + if err := runRequests(conf, logger); err != nil { logger.Error("failed to run server", zap.Error(err)) os.Exit(1) } diff --git a/cli/workload/upstreams.go b/cli/workload/upstreams.go index fa47060..47c77c0 100644 --- a/cli/workload/upstreams.go +++ b/cli/workload/upstreams.go @@ -45,7 +45,7 @@ Examples: `, } - var conf config.UpstreamsConfig + conf := config.DefaultUpstreamsConfig() // Register flags and set default values. conf.RegisterFlags(cmd.Flags()) @@ -62,7 +62,7 @@ Examples: os.Exit(1) } - if err := runUpstreams(&conf, logger); err != nil { + if err := runUpstreams(conf, logger); err != nil { logger.Error("failed to run server", zap.Error(err)) os.Exit(1) } diff --git a/forward/config/config.go b/forward/config/config.go index 6052bd2..9131570 100644 --- a/forward/config/config.go +++ b/forward/config/config.go @@ -68,7 +68,7 @@ func (c *TLSConfig) RegisterFlags(fs *pflag.FlagSet, prefix string) { fs.StringVar( &c.RootCAs, prefix+"root-cas", - "", + c.RootCAs, ` A path to a certificate PEM file containing root certificiate authorities to validate the TLS connection to the Piko server. @@ -125,7 +125,7 @@ func (c *ConnectConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.URL, "connect.url", - "http://localhost:8000", + c.URL, ` The Piko server URL to connect to. Note this must be configured to use the Piko server 'proxy' port.`, @@ -134,7 +134,7 @@ Piko server 'proxy' port.`, fs.DurationVar( &c.Timeout, "connect.timeout", - time.Second*30, + c.Timeout, ` Timeout attempting to connect to the Piko server.`, ) @@ -150,6 +150,15 @@ type Config struct { Log log.Config `json:"log" yaml:"log"` } +func Default() *Config { + return &Config{ + Connect: ConnectConfig{ + URL: "http://localhost:8000", + Timeout: time.Second * 30, + }, + } +} + func (c *Config) Validate() error { // Note don't validate the number of ports, as some commands don't // require any. diff --git a/pkg/gossip/config.go b/pkg/gossip/config.go index e16c058..bdd6a41 100644 --- a/pkg/gossip/config.go +++ b/pkg/gossip/config.go @@ -38,7 +38,7 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.BindAddr, "gossip.bind-addr", - ":8003", + c.BindAddr, ` The host/port to listen for inter-node gossip traffic. @@ -49,7 +49,7 @@ If the host is unspecified it defaults to all listeners, such as fs.StringVar( &c.AdvertiseAddr, "gossip.advertise-addr", - "", + c.AdvertiseAddr, ` Gossip listen address to advertise to other nodes in the cluster. This is the address other nodes will used to gossip with the node. @@ -66,7 +66,7 @@ advertise address of '10.26.104.14:8003'.`, fs.DurationVar( &c.Interval, "gossip.interval", - time.Millisecond*500, + c.Interval, ` The interval to initiate rounds of gossip. @@ -76,7 +76,7 @@ Each gossip round selects another known node to synchronize with.`, fs.IntVar( &c.MaxPacketSize, "gossip.max-packet-size", - 1400, + c.MaxPacketSize, ` The maximum size of any packet sent. diff --git a/pkg/log/config.go b/pkg/log/config.go index f940bff..134034b 100644 --- a/pkg/log/config.go +++ b/pkg/log/config.go @@ -30,7 +30,7 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.Level, "log.level", - "info", + c.Level, ` Minimum log level to output. @@ -39,7 +39,7 @@ The available levels are 'debug', 'info', 'warn' and 'error'.`, fs.StringSliceVar( &c.Subsystems, "log.subsystems", - nil, + c.Subsystems, ` Each log has a 'subsystem' field where the log occured. diff --git a/server/auth/config.go b/server/auth/config.go index 538a50f..9c5e35f 100644 --- a/server/auth/config.go +++ b/server/auth/config.go @@ -36,28 +36,28 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.TokenHMACSecretKey, "auth.token-hmac-secret-key", - "", + c.TokenHMACSecretKey, ` Secret key to authenticate HMAC endpoint connection JWTs.`, ) fs.StringVar( &c.TokenRSAPublicKey, "auth.token-rsa-public-key", - "", + c.TokenRSAPublicKey, ` Public key to authenticate RSA endpoint connection JWTs.`, ) fs.StringVar( &c.TokenECDSAPublicKey, "auth.token-ecdsa-public-key", - "", + c.TokenECDSAPublicKey, ` Public key to authenticate ECDSA endpoint connection JWTs.`, ) fs.StringVar( &c.TokenAudience, "auth.token-audience", - "", + c.TokenAudience, ` Audience of endpoint connection JWT token to verify. @@ -67,7 +67,7 @@ is ignored.`, fs.StringVar( &c.TokenIssuer, "auth.token-issuer", - "", + c.TokenIssuer, ` Issuer of endpoint connection JWT token to verify. diff --git a/server/config/config.go b/server/config/config.go index 635e25c..00915b1 100644 --- a/server/config/config.go +++ b/server/config/config.go @@ -36,7 +36,7 @@ func (c *ClusterConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.NodeID, "cluster.node-id", - "", + c.NodeID, ` A unique identifier for the node in the cluster. @@ -46,7 +46,7 @@ By default a random ID will be generated for the node.`, fs.StringVar( &c.NodeIDPrefix, "cluster.node-id-prefix", - "", + c.NodeIDPrefix, ` A prefix for the node ID. @@ -60,7 +60,7 @@ identifier to ensure the node ID is unique across restarts.`, fs.StringSliceVar( &c.Join, "cluster.join", - nil, + c.Join, ` A list of addresses of members in the cluster to join. @@ -79,7 +79,7 @@ so the initial set of configured members only needs to be a subset of nodes.`, fs.BoolVar( &c.AbortIfJoinFails, "cluster.abort-if-join-fails", - true, + c.AbortIfJoinFails, ` Whether the server node should abort if it is configured with more than one node to join (excluding itself) but fails to join any members.`, @@ -121,7 +121,7 @@ func (c *HTTPConfig) RegisterFlags(fs *pflag.FlagSet, prefix string) { fs.DurationVar( &c.ReadTimeout, prefix+"read-timeout", - time.Second*10, + c.ReadTimeout, ` The maximum duration for reading the entire request, including the body. A zero or negative value means there will be no timeout.`, @@ -129,7 +129,7 @@ zero or negative value means there will be no timeout.`, fs.DurationVar( &c.ReadHeaderTimeout, prefix+"read-header-timeout", - time.Second*10, + c.ReadHeaderTimeout, ` The maximum duration for reading the request headers. If zero, http.read-timeout is used.`, @@ -137,14 +137,14 @@ http.read-timeout is used.`, fs.DurationVar( &c.WriteTimeout, prefix+"write-timeout", - time.Second*10, + c.WriteTimeout, ` The maximum duration before timing out writes of the response.`, ) fs.DurationVar( &c.IdleTimeout, prefix+"idle-timeout", - time.Minute*5, + c.IdleTimeout, ` The maximum amount of time to wait for the next request when keep-alives are enabled.`, @@ -152,7 +152,7 @@ enabled.`, fs.IntVar( &c.MaxHeaderBytes, prefix+"max-header-bytes", - 1<<20, + c.MaxHeaderBytes, ` The maximum number of bytes the server will read parsing the request header's keys and values, including the request line.`, @@ -195,7 +195,7 @@ func (c *ProxyConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.BindAddr, "proxy.bind-addr", - ":8000", + c.BindAddr, ` The host/port to listen for incoming proxy connections. @@ -206,7 +206,7 @@ If the host is unspecified it defaults to all listeners, such as fs.StringVar( &c.AdvertiseAddr, "proxy.advertise-addr", - "", + c.AdvertiseAddr, ` Proxy to advertise to other nodes in the cluster. This is the address other nodes will used to forward proxy connections. @@ -223,7 +223,7 @@ advertise address of '10.26.104.14:8000'.`, fs.DurationVar( &c.Timeout, "proxy.timeout", - time.Second*30, + c.Timeout, ` Timeout when forwarding incoming requests to the upstream.`, ) @@ -231,7 +231,7 @@ Timeout when forwarding incoming requests to the upstream.`, fs.BoolVar( &c.AccessLog, "proxy.access-log", - true, + c.AccessLog, ` Whether to log all incoming connections and requests.`, ) @@ -262,7 +262,7 @@ func (c *UpstreamConfig) RegisterFlags(fs *pflag.FlagSet) { fs.StringVar( &c.BindAddr, "upstream.bind-addr", - ":8001", + c.BindAddr, ` The host/port to listen for incoming upstream connections. @@ -333,7 +333,7 @@ func (c *UsageConfig) RegisterFlags(fs *pflag.FlagSet) { fs.BoolVar( &c.Disable, "usage.disable", - false, + c.Disable, ` Whether to disable anonymous usage tracking. @@ -350,10 +350,10 @@ type Config struct { Upstream UpstreamConfig `json:"upstream" yaml:"upstream"` - Gossip gossip.Config `json:"gossip" yaml:"gossip"` - Admin AdminConfig `json:"admin" yaml:"admin"` + Gossip gossip.Config `json:"gossip" yaml:"gossip"` + Auth auth.Config `json:"auth" yaml:"auth"` Usage UsageConfig `json:"usage" yaml:"usage"` @@ -366,6 +366,41 @@ type Config struct { GracePeriod time.Duration `json:"grace_period" yaml:"grace_period"` } +func Default() *Config { + return &Config{ + Cluster: ClusterConfig{ + AbortIfJoinFails: true, + }, + Proxy: ProxyConfig{ + BindAddr: ":8000", + Timeout: time.Second * 30, + AccessLog: true, + HTTP: HTTPConfig{ + ReadTimeout: time.Second * 10, + ReadHeaderTimeout: time.Second * 10, + WriteTimeout: time.Second * 10, + IdleTimeout: time.Minute * 5, + MaxHeaderBytes: 1 << 20, + }, + }, + Upstream: UpstreamConfig{ + BindAddr: ":8001", + }, + Admin: AdminConfig{ + BindAddr: "8002", + }, + Gossip: gossip.Config{ + BindAddr: ":8003", + Interval: time.Millisecond * 500, + MaxPacketSize: 1400, + }, + Log: log.Config{ + Level: "info", + }, + GracePeriod: time.Minute, + } +} + func (c *Config) Validate() error { if err := c.Cluster.Validate(); err != nil { return fmt.Errorf("cluster: %w", err) @@ -379,14 +414,14 @@ func (c *Config) Validate() error { return fmt.Errorf("upstream: %w", err) } - if err := c.Gossip.Validate(); err != nil { - return fmt.Errorf("gossip: %w", err) - } - if err := c.Admin.Validate(); err != nil { return fmt.Errorf("admin: %w", err) } + if err := c.Gossip.Validate(); err != nil { + return fmt.Errorf("gossip: %w", err) + } + if err := c.Log.Validate(); err != nil { return fmt.Errorf("log: %w", err) } @@ -405,10 +440,10 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { c.Upstream.RegisterFlags(fs) - c.Gossip.RegisterFlags(fs) - c.Admin.RegisterFlags(fs) + c.Gossip.RegisterFlags(fs) + c.Auth.RegisterFlags(fs) c.Usage.RegisterFlags(fs) @@ -418,7 +453,7 @@ func (c *Config) RegisterFlags(fs *pflag.FlagSet) { fs.DurationVar( &c.GracePeriod, "grace-period", - time.Minute, + c.GracePeriod, ` Maximum duration after a shutdown signal is received (SIGTERM or SIGINT) to gracefully shutdown the server node before terminating. diff --git a/server/config/tls.go b/server/config/tls.go index edf8039..f242ed1 100644 --- a/server/config/tls.go +++ b/server/config/tls.go @@ -33,7 +33,7 @@ func (c *TLSConfig) RegisterFlags(fs *pflag.FlagSet, prefix string) { fs.BoolVar( &c.Enabled, prefix+"enabled", - false, + c.Enabled, ` Whether to enable TLS on the listener. @@ -42,14 +42,14 @@ If enabled must configure the cert and key.`, fs.StringVar( &c.Cert, prefix+"cert", - "", + c.Cert, ` Path to the PEM encoded certificate file.`, ) fs.StringVar( &c.Key, prefix+"key", - "", + c.Key, ` Path to the PEM encoded key file.`, ) diff --git a/workload/config/requests.go b/workload/config/requests.go index 6a8a176..568caf0 100644 --- a/workload/config/requests.go +++ b/workload/config/requests.go @@ -24,6 +24,18 @@ type RequestsConfig struct { Log log.Config `json:"log" yaml:"log"` } +func DefaultRequestsConfig() *RequestsConfig { + return &RequestsConfig{ + Clients: 50, + Rate: 10, + Endpoints: 100, + RequestSize: 1024, + Server: ServerConfig{ + URL: "http://localhost:8000", + }, + } +} + func (c *RequestsConfig) Validate() error { if c.Clients == 0 { return fmt.Errorf("missing clients") @@ -48,7 +60,7 @@ func (c *RequestsConfig) RegisterFlags(fs *pflag.FlagSet) { fs.IntVar( &c.Clients, "clients", - 50, + c.Clients, ` The number of clients to run.`, ) @@ -56,7 +68,7 @@ The number of clients to run.`, fs.IntVar( &c.Rate, "rate", - 10, + c.Rate, ` The number of requests per second per client to send.`, ) @@ -64,7 +76,7 @@ The number of requests per second per client to send.`, fs.IntVar( &c.Endpoints, "endpoints", - 100, + c.Endpoints, ` The number of available endpoint IDs to send requests to. @@ -75,7 +87,7 @@ On each request, the client selects a random endpoint ID from 0 to fs.IntVar( &c.RequestSize, "request-size", - 1024, + c.RequestSize, ` The size of each request. As the upstream echos the response body, the response will have the same size.`, @@ -84,7 +96,7 @@ will have the same size.`, fs.StringVar( &c.Server.URL, "server.url", - "http://localhost:8000", + c.Server.URL, ` Piko server proxy URL.`, ) diff --git a/workload/config/upstreams.go b/workload/config/upstreams.go index 8020523..20d52f8 100644 --- a/workload/config/upstreams.go +++ b/workload/config/upstreams.go @@ -37,7 +37,7 @@ func (c *ChurnConfig) RegisterFlags(fs *pflag.FlagSet) { fs.DurationVar( &c.Interval, "churn.interval", - 0, + c.Interval, ` How often each upstream should 'churn' (disconnect and reconnect).`, ) @@ -45,7 +45,7 @@ How often each upstream should 'churn' (disconnect and reconnect).`, fs.DurationVar( &c.Delay, "churn.delay", - 0, + c.Delay, ` Duration to wait before reconnecting when an upstream churns.`, ) @@ -65,6 +65,20 @@ type UpstreamsConfig struct { Log log.Config `json:"log" yaml:"log"` } +func DefaultUpstreamsConfig() *UpstreamsConfig { + return &UpstreamsConfig{ + Upstreams: 1000, + Endpoints: 100, + Churn: ChurnConfig{ + Interval: 0, + Delay: 0, + }, + Server: ServerConfig{ + URL: "http://localhost:8001", + }, + } +} + func (c *UpstreamsConfig) Validate() error { if c.Upstreams == 0 { return fmt.Errorf("missing upstreams") @@ -89,7 +103,7 @@ func (c *UpstreamsConfig) RegisterFlags(fs *pflag.FlagSet) { fs.IntVar( &c.Upstreams, "upstreams", - 1000, + c.Upstreams, ` The number of upstream servers to register. @@ -100,7 +114,7 @@ the number endpoints to register.`, fs.IntVar( &c.Endpoints, "endpoints", - 100, + c.Endpoints, ` The number of available endpoint IDs to register. @@ -116,7 +130,7 @@ Therefore 'endpoints' must be greater than or equal to 'upstreams'.`, fs.StringVar( &c.Server.URL, "server.url", - "http://localhost:8001", + c.Server.URL, ` Piko server URL.