diff options
author | Valery Piashchynski <[email protected]> | 2021-01-21 13:25:36 +0300 |
---|---|---|
committer | Valery Piashchynski <[email protected]> | 2021-01-21 13:25:36 +0300 |
commit | 7da6c78449776e1f3c6716250bca0b712a0423a4 (patch) | |
tree | f3512de66aca2bba408485a0ea2fc936c0e4fb9b /plugins | |
parent | 0ff05b2732b4fd0783f959c94c54d7e39169f979 (diff) |
Uniform all configs
Add debug server
Check nil's for all plugin intialization
Diffstat (limited to 'plugins')
32 files changed, 260 insertions, 195 deletions
diff --git a/plugins/checker/plugin.go b/plugins/checker/plugin.go index ef184b02..407cb2fa 100644 --- a/plugins/checker/plugin.go +++ b/plugins/checker/plugin.go @@ -27,15 +27,14 @@ type Plugin struct { func (c *Plugin) Init(log logger.Logger, cfg config.Configurer) error { const op = errors.Op("checker_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(PluginName, &c.cfg) if err != nil { return errors.E(op, errors.Disabled, err) } - if c.cfg == nil { - return errors.E(errors.Disabled) - } - c.registry = make(map[string]Checker) c.log = log return nil diff --git a/plugins/gzip/plugin.go b/plugins/gzip/plugin.go index e5b9e4f5..eee6c1d3 100644 --- a/plugins/gzip/plugin.go +++ b/plugins/gzip/plugin.go @@ -10,6 +10,7 @@ const PluginName = "gzip" type Gzip struct{} +// needed for the Endure func (g *Gzip) Init() error { return nil } diff --git a/plugins/headers/plugin.go b/plugins/headers/plugin.go index 3f25a1ed..84194d7e 100644 --- a/plugins/headers/plugin.go +++ b/plugins/headers/plugin.go @@ -22,6 +22,9 @@ type Plugin struct { // misconfiguration. Services must not be used without proper configuration pushed first. func (s *Plugin) Init(cfg config.Configurer) error { const op = errors.Op("headers_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(RootPluginName, &s.cfg) if err != nil { return errors.E(op, errors.Disabled, err) diff --git a/plugins/http/config/fcgi.go b/plugins/http/config/fcgi.go new file mode 100644 index 00000000..3d4acbe1 --- /dev/null +++ b/plugins/http/config/fcgi.go @@ -0,0 +1,7 @@ +package config + +// FCGI for FastCGI server. +type FCGI struct { + // Address and port to handle as http server. + Address string +} diff --git a/plugins/http/config.go b/plugins/http/config/http.go index e272e550..76547fde 100644 --- a/plugins/http/config.go +++ b/plugins/http/config/http.go @@ -1,4 +1,4 @@ -package http +package config import ( "net" @@ -11,42 +11,19 @@ import ( poolImpl "github.com/spiral/roadrunner/v2/pkg/pool" ) -// Cidrs is a slice of IPNet addresses -type Cidrs []*net.IPNet - -// IsTrusted checks if the ip address exists in the provided in the config addresses -func (c *Cidrs) IsTrusted(ip string) bool { - if len(*c) == 0 { - return false - } - - i := net.ParseIP(ip) - if i == nil { - return false - } - - for _, cird := range *c { - if cird.Contains(i) { - return true - } - } - - return false -} - -// Config configures RoadRunner HTTP server. -type Config struct { +// HTTP configures RoadRunner HTTP server. +type HTTP struct { // Port and port to handle as http server. Address string - // SSL defines https server options. - SSL *SSLConfig + // SSLConfig defines https server options. + SSLConfig *SSL `mapstructure:"ssl"` - // FCGI configuration. You can use FastCGI without HTTP server. - FCGI *FCGIConfig + // FCGIConfig configuration. You can use FastCGI without HTTP server. + FCGIConfig *FCGI `mapstructure:"fcgi"` - // HTTP2 configuration - HTTP2 *HTTP2Config + // HTTP2Config configuration + HTTP2Config *HTTP2 `mapstructure:"http2"` // MaxRequestSize specified max size for payload body in megabytes, set 0 to unlimited. MaxRequestSize uint64 `mapstructure:"max_request_size"` @@ -55,7 +32,7 @@ type Config struct { TrustedSubnets []string `mapstructure:"trusted_subnets"` // Uploads configures uploads configuration. - Uploads *UploadsConfig + Uploads *Uploads `mapstructure:"uploads"` // Pool configures worker pool. Pool *poolImpl.Config `mapstructure:"pool"` @@ -67,80 +44,31 @@ type Config struct { Middleware []string // slice of net.IPNet - cidrs Cidrs -} - -// FCGIConfig for FastCGI server. -type FCGIConfig struct { - // Address and port to handle as http server. - Address string -} - -// HTTP2Config HTTP/2 server customizations. -type HTTP2Config struct { - // Enable or disable HTTP/2 extension, default enable. - Enabled bool - - // H2C enables HTTP/2 over TCP - H2C bool - - // MaxConcurrentStreams defaults to 128. - MaxConcurrentStreams uint32 `mapstructure:"max_concurrent_streams"` -} - -// InitDefaults sets default values for HTTP/2 configuration. -func (cfg *HTTP2Config) InitDefaults() error { - cfg.Enabled = true - cfg.MaxConcurrentStreams = 128 - - return nil -} - -// SSLConfig defines https server configuration. -type SSLConfig struct { - // Port to listen as HTTPS server, defaults to 443. - Port int - - // Redirect when enabled forces all http connections to switch to https. - Redirect bool - - // Key defined private server key. - Key string - - // Cert is https certificate. - Cert string - - // Root CA file - RootCA string + Cidrs Cidrs } // EnableHTTP is true when http server must run. -func (c *Config) EnableHTTP() bool { +func (c *HTTP) EnableHTTP() bool { return c.Address != "" } // EnableTLS returns true if pool must listen TLS connections. -func (c *Config) EnableTLS() bool { - return c.SSL.Key != "" || c.SSL.Cert != "" || c.SSL.RootCA != "" -} - -// EnableHTTP2 when HTTP/2 extension must be enabled (only with TSL). -func (c *Config) EnableHTTP2() bool { - return c.HTTP2.Enabled +func (c *HTTP) EnableTLS() bool { + return c.SSLConfig.Key != "" || c.SSLConfig.Cert != "" || c.SSLConfig.RootCA != "" } // EnableH2C when HTTP/2 extension must be enabled on TCP. -func (c *Config) EnableH2C() bool { - return c.HTTP2.H2C +func (c *HTTP) EnableH2C() bool { + return c.HTTP2Config.H2C } // EnableFCGI is true when FastCGI server must be enabled. -func (c *Config) EnableFCGI() bool { - return c.FCGI.Address != "" +func (c *HTTP) EnableFCGI() bool { + return c.FCGIConfig.Address != "" } -// InitDefaults must populate Config values using given Config source. Must return error if Config is not valid. -func (c *Config) InitDefaults() error { +// InitDefaults must populate HTTP values using given HTTP source. Must return error if HTTP is not valid. +func (c *HTTP) InitDefaults() error { if c.Pool == nil { // default pool c.Pool = &poolImpl.Config{ @@ -153,27 +81,27 @@ func (c *Config) InitDefaults() error { } } - if c.HTTP2 == nil { - c.HTTP2 = &HTTP2Config{} + if c.HTTP2Config == nil { + c.HTTP2Config = &HTTP2{} } - if c.FCGI == nil { - c.FCGI = &FCGIConfig{} + if c.FCGIConfig == nil { + c.FCGIConfig = &FCGI{} } if c.Uploads == nil { - c.Uploads = &UploadsConfig{} + c.Uploads = &Uploads{} } - if c.SSL == nil { - c.SSL = &SSLConfig{} + if c.SSLConfig == nil { + c.SSLConfig = &SSL{} } - if c.SSL.Port == 0 { - c.SSL.Port = 443 + if c.SSLConfig.Port == 0 { + c.SSLConfig.Port = 443 } - err := c.HTTP2.InitDefaults() + err := c.HTTP2Config.InitDefaults() if err != nil { return err } @@ -199,7 +127,7 @@ func (c *Config) InitDefaults() error { if err != nil { return err } - c.cidrs = cidrs + c.Cidrs = cidrs return c.Valid() } @@ -220,8 +148,8 @@ func ParseCIDRs(subnets []string) (Cidrs, error) { } // IsTrusted if api can be trusted to use X-Real-Ip, X-Forwarded-For -func (c *Config) IsTrusted(ip string) bool { - if c.cidrs == nil { +func (c *HTTP) IsTrusted(ip string) bool { + if c.Cidrs == nil { return false } @@ -230,7 +158,7 @@ func (c *Config) IsTrusted(ip string) bool { return false } - for _, cird := range c.cidrs { + for _, cird := range c.Cidrs { if cird.Contains(i) { return true } @@ -240,13 +168,13 @@ func (c *Config) IsTrusted(ip string) bool { } // Valid validates the configuration. -func (c *Config) Valid() error { +func (c *HTTP) Valid() error { const op = errors.Op("validation") if c.Uploads == nil { return errors.E(op, errors.Str("malformed uploads config")) } - if c.HTTP2 == nil { + if c.HTTP2Config == nil { return errors.E(op, errors.Str("malformed http2 config")) } @@ -263,27 +191,27 @@ func (c *Config) Valid() error { } if c.EnableTLS() { - if _, err := os.Stat(c.SSL.Key); err != nil { + if _, err := os.Stat(c.SSLConfig.Key); err != nil { if os.IsNotExist(err) { - return errors.E(op, errors.Errorf("key file '%s' does not exists", c.SSL.Key)) + return errors.E(op, errors.Errorf("key file '%s' does not exists", c.SSLConfig.Key)) } return err } - if _, err := os.Stat(c.SSL.Cert); err != nil { + if _, err := os.Stat(c.SSLConfig.Cert); err != nil { if os.IsNotExist(err) { - return errors.E(op, errors.Errorf("cert file '%s' does not exists", c.SSL.Cert)) + return errors.E(op, errors.Errorf("cert file '%s' does not exists", c.SSLConfig.Cert)) } return err } // RootCA is optional, but if provided - check it - if c.SSL.RootCA != "" { - if _, err := os.Stat(c.SSL.RootCA); err != nil { + if c.SSLConfig.RootCA != "" { + if _, err := os.Stat(c.SSLConfig.RootCA); err != nil { if os.IsNotExist(err) { - return errors.E(op, errors.Errorf("root ca path provided, but path '%s' does not exists", c.SSL.RootCA)) + return errors.E(op, errors.Errorf("root ca path provided, but path '%s' does not exists", c.SSLConfig.RootCA)) } return err } diff --git a/plugins/http/config/http2.go b/plugins/http/config/http2.go new file mode 100644 index 00000000..b1e109e9 --- /dev/null +++ b/plugins/http/config/http2.go @@ -0,0 +1,28 @@ +package config + +// HTTP2 HTTP/2 server customizations. +type HTTP2 struct { + // h2cHandler is a Handler which implements h2c by hijacking the HTTP/1 traffic + // that should be h2c traffic. There are two ways to begin a h2c connection + // (RFC 7540 Section 3.2 and 3.4): (1) Starting with Prior Knowledge - this + // works by starting an h2c connection with a string of bytes that is valid + // HTTP/1, but unlikely to occur in practice and (2) Upgrading from HTTP/1 to + // h2c - this works by using the HTTP/1 Upgrade header to request an upgrade to + // h2c. When either of those situations occur we hijack the HTTP/1 connection, + // convert it to a HTTP/2 connection and pass the net.Conn to http2.ServeConn. + + // H2C enables HTTP/2 over TCP + H2C bool + + // MaxConcurrentStreams defaults to 128. + MaxConcurrentStreams uint32 `mapstructure:"max_concurrent_streams"` +} + +// InitDefaults sets default values for HTTP/2 configuration. +func (cfg *HTTP2) InitDefaults() error { + if cfg.MaxConcurrentStreams == 0 { + cfg.MaxConcurrentStreams = 128 + } + + return nil +} diff --git a/plugins/http/config/ip.go b/plugins/http/config/ip.go new file mode 100644 index 00000000..c4981f74 --- /dev/null +++ b/plugins/http/config/ip.go @@ -0,0 +1,26 @@ +package config + +import "net" + +// Cidrs is a slice of IPNet addresses +type Cidrs []*net.IPNet + +// IsTrusted checks if the ip address exists in the provided in the config addresses +func (c *Cidrs) IsTrusted(ip string) bool { + if len(*c) == 0 { + return false + } + + i := net.ParseIP(ip) + if i == nil { + return false + } + + for _, cird := range *c { + if cird.Contains(i) { + return true + } + } + + return false +} diff --git a/plugins/http/config/ssl.go b/plugins/http/config/ssl.go new file mode 100644 index 00000000..aae6e920 --- /dev/null +++ b/plugins/http/config/ssl.go @@ -0,0 +1,19 @@ +package config + +// SSL defines https server configuration. +type SSL struct { + // Port to listen as HTTPS server, defaults to 443. + Port int + + // Redirect when enabled forces all http connections to switch to https. + Redirect bool + + // Key defined private server key. + Key string + + // Cert is https certificate. + Cert string + + // Root CA file + RootCA string +} diff --git a/plugins/http/uploads_config.go b/plugins/http/config/uploads_config.go index 4c20c8e8..5edb0ab7 100644 --- a/plugins/http/uploads_config.go +++ b/plugins/http/config/uploads_config.go @@ -1,4 +1,4 @@ -package http +package config import ( "os" @@ -6,8 +6,8 @@ import ( "strings" ) -// UploadsConfig describes file location and controls access to them. -type UploadsConfig struct { +// Uploads describes file location and controls access to them. +type Uploads struct { // Dir contains name of directory to control access to. Dir string @@ -17,14 +17,14 @@ type UploadsConfig struct { } // InitDefaults sets missing values to their default values. -func (cfg *UploadsConfig) InitDefaults() error { +func (cfg *Uploads) InitDefaults() error { cfg.Forbid = []string{".php", ".exe", ".bat"} cfg.Dir = os.TempDir() return nil } // TmpDir returns temporary directory. -func (cfg *UploadsConfig) TmpDir() string { +func (cfg *Uploads) TmpDir() string { if cfg.Dir != "" { return cfg.Dir } @@ -33,7 +33,7 @@ func (cfg *UploadsConfig) TmpDir() string { } // Forbids must return true if file extension is not allowed for the upload. -func (cfg *UploadsConfig) Forbids(filename string) bool { +func (cfg *Uploads) Forbids(filename string) bool { ext := strings.ToLower(path.Ext(filename)) for _, v := range cfg.Forbid { diff --git a/plugins/http/handler.go b/plugins/http/handler.go index 3e21ab2b..ecdcb2c0 100644 --- a/plugins/http/handler.go +++ b/plugins/http/handler.go @@ -12,17 +12,10 @@ import ( "github.com/spiral/errors" "github.com/spiral/roadrunner/v2/interfaces/events" "github.com/spiral/roadrunner/v2/interfaces/pool" + "github.com/spiral/roadrunner/v2/plugins/http/config" "github.com/spiral/roadrunner/v2/plugins/logger" ) -const ( - // EventResponse thrown after the request been processed. See ErrorEvent as payload. - EventResponse = iota + 500 - - // EventError thrown on any non job error provided by road runner server. - EventError -) - // MB is 1024 bytes const MB uint64 = 1024 * 1024 @@ -66,8 +59,8 @@ func (e *ResponseEvent) Elapsed() time.Duration { // parsed files and query, payload will include parsed form dataTree (if any). type Handler struct { maxRequestSize uint64 - uploads UploadsConfig - trusted Cidrs + uploads config.Uploads + trusted config.Cidrs log logger.Logger pool pool.Pool mul sync.Mutex @@ -75,7 +68,7 @@ type Handler struct { } // NewHandler return handle interface implementation -func NewHandler(maxReqSize uint64, uploads UploadsConfig, trusted Cidrs, pool pool.Pool) (*Handler, error) { +func NewHandler(maxReqSize uint64, uploads config.Uploads, trusted config.Cidrs, pool pool.Pool) (*Handler, error) { if pool == nil { return nil, errors.E(errors.Str("pool should be initialized")) } diff --git a/plugins/http/parse.go b/plugins/http/parse.go index d4a1604b..780e1279 100644 --- a/plugins/http/parse.go +++ b/plugins/http/parse.go @@ -2,6 +2,8 @@ package http import ( "net/http" + + "github.com/spiral/roadrunner/v2/plugins/http/config" ) // MaxLevel defines maximum tree depth for incoming request data and files. @@ -60,7 +62,7 @@ func (d dataTree) mount(i []string, v []string) { } // parse incoming dataTree request into JSON (including contentMultipart form dataTree) -func parseUploads(r *http.Request, cfg UploadsConfig) *Uploads { +func parseUploads(r *http.Request, cfg config.Uploads) *Uploads { u := &Uploads{ cfg: cfg, tree: make(fileTree), diff --git a/plugins/http/plugin.go b/plugins/http/plugin.go index d9c1729e..35acd2b7 100644 --- a/plugins/http/plugin.go +++ b/plugins/http/plugin.go @@ -21,6 +21,7 @@ import ( "github.com/spiral/roadrunner/v2/plugins/checker" "github.com/spiral/roadrunner/v2/plugins/config" "github.com/spiral/roadrunner/v2/plugins/http/attributes" + httpConfig "github.com/spiral/roadrunner/v2/plugins/http/config" "github.com/spiral/roadrunner/v2/plugins/logger" "github.com/spiral/roadrunner/v2/plugins/server" "github.com/spiral/roadrunner/v2/utils" @@ -52,7 +53,7 @@ type Plugin struct { server server.Server log logger.Logger - cfg *Config `mapstructure:"http"` + cfg *httpConfig.HTTP `mapstructure:"http"` // middlewares to chain mdwr middleware @@ -72,16 +73,15 @@ type Plugin struct { // misconfiguration. Services must not be used without proper configuration pushed first. func (s *Plugin) Init(cfg config.Configurer, log logger.Logger, server server.Server) error { const op = errors.Op("http_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } + err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { return errors.E(op, err) } - // if no HTTP section in config - disable HTTP - if s.cfg == nil { - return errors.E(op, errors.Disabled) - } - err = s.cfg.InitDefaults() if err != nil { return errors.E(op, err) @@ -142,7 +142,7 @@ func (s *Plugin) Serve() chan error { s.handler, err = NewHandler( s.cfg.MaxRequestSize, *s.cfg.Uploads, - s.cfg.cidrs, + s.cfg.Cidrs, s.pool, ) if err != nil { @@ -162,7 +162,7 @@ func (s *Plugin) Serve() chan error { if s.cfg.EnableTLS() { s.https = s.initSSL() - if s.cfg.SSL.RootCA != "" { + if s.cfg.SSLConfig.RootCA != "" { err = s.appendRootCa() if err != nil { errCh <- errors.E(op, err) @@ -170,7 +170,8 @@ func (s *Plugin) Serve() chan error { } } - if s.cfg.EnableHTTP2() { + // if HTTP2Config not nil + if s.cfg.HTTP2Config != nil { if err := s.initHTTP2(); err != nil { errCh <- errors.E(op, err) return errCh @@ -200,8 +201,8 @@ func (s *Plugin) Serve() chan error { if s.https != nil { go func() { httpErr := s.https.ListenAndServeTLS( - s.cfg.SSL.Cert, - s.cfg.SSL.Key, + s.cfg.SSLConfig.Cert, + s.cfg.SSLConfig.Key, ) if httpErr != nil && httpErr != http.ErrServerClosed { @@ -322,7 +323,7 @@ func (s *Plugin) Reset() error { s.handler, err = NewHandler( s.cfg.MaxRequestSize, *s.cfg.Uploads, - s.cfg.cidrs, + s.cfg.Cidrs, s.pool, ) if err != nil { @@ -362,7 +363,7 @@ func (s *Plugin) Status() checker.Status { } func (s *Plugin) redirect(w http.ResponseWriter, r *http.Request) bool { - if s.https != nil && r.TLS == nil && s.cfg.SSL.Redirect { + if s.https != nil && r.TLS == nil && s.cfg.SSLConfig.Redirect { target := &url.URL{ Scheme: "https", Host: s.tlsAddr(r.Host, false), @@ -396,7 +397,7 @@ func (s *Plugin) appendRootCa() error { rootCAs = x509.NewCertPool() } - CA, err := ioutil.ReadFile(s.cfg.SSL.RootCA) + CA, err := ioutil.ReadFile(s.cfg.SSLConfig.RootCA) if err != nil { return err } @@ -489,13 +490,13 @@ func (s *Plugin) initSSL() *http.Server { // init http/2 server func (s *Plugin) initHTTP2() error { return http2.ConfigureServer(s.https, &http2.Server{ - MaxConcurrentStreams: s.cfg.HTTP2.MaxConcurrentStreams, + MaxConcurrentStreams: s.cfg.HTTP2Config.MaxConcurrentStreams, }) } // serveFCGI starts FastCGI server. func (s *Plugin) serveFCGI() error { - l, err := utils.CreateListener(s.cfg.FCGI.Address) + l, err := utils.CreateListener(s.cfg.FCGIConfig.Address) if err != nil { return err } @@ -508,13 +509,13 @@ func (s *Plugin) serveFCGI() error { return nil } -// tlsAddr replaces listen or host port with port configured by SSL config. +// tlsAddr replaces listen or host port with port configured by SSLConfig config. func (s *Plugin) tlsAddr(host string, forcePort bool) string { // remove current forcePort first host = strings.Split(host, ":")[0] - if forcePort || s.cfg.SSL.Port != 443 { - host = fmt.Sprintf("%s:%v", host, s.cfg.SSL.Port) + if forcePort || s.cfg.SSLConfig.Port != 443 { + host = fmt.Sprintf("%s:%v", host, s.cfg.SSLConfig.Port) } return host diff --git a/plugins/http/request.go b/plugins/http/request.go index 3983fdde..a1398819 100644 --- a/plugins/http/request.go +++ b/plugins/http/request.go @@ -11,6 +11,7 @@ import ( j "github.com/json-iterator/go" "github.com/spiral/roadrunner/v2/pkg/payload" "github.com/spiral/roadrunner/v2/plugins/http/attributes" + "github.com/spiral/roadrunner/v2/plugins/http/config" "github.com/spiral/roadrunner/v2/plugins/logger" ) @@ -70,7 +71,7 @@ func fetchIP(pair string) string { } // NewRequest creates new PSR7 compatible request using net/http request. -func NewRequest(r *http.Request, cfg UploadsConfig) (*Request, error) { +func NewRequest(r *http.Request, cfg config.Uploads) (*Request, error) { req := &Request{ RemoteAddr: fetchIP(r.RemoteAddr), Protocol: r.Proto, diff --git a/plugins/http/uploads.go b/plugins/http/uploads.go index d5196844..f9f8e1c8 100644 --- a/plugins/http/uploads.go +++ b/plugins/http/uploads.go @@ -1,6 +1,7 @@ package http import ( + "github.com/spiral/roadrunner/v2/plugins/http/config" "github.com/spiral/roadrunner/v2/plugins/logger" "io" @@ -30,7 +31,7 @@ const ( // Uploads tree manages uploaded files tree and temporary files. type Uploads struct { // associated temp directory and forbidden extensions. - cfg UploadsConfig + cfg config.Uploads // pre processed data tree for Uploads. tree fileTree @@ -112,7 +113,7 @@ func NewUpload(f *multipart.FileHeader) *FileUpload { // STACK // DEFER FILE CLOSE (2) // DEFER TMP CLOSE (1) -func (f *FileUpload) Open(cfg UploadsConfig) (err error) { +func (f *FileUpload) Open(cfg config.Uploads) (err error) { if cfg.Forbids(f.Name) { f.Error = UploadErrorExtension return nil diff --git a/plugins/kv/boltdb/config.go b/plugins/kv/boltdb/config.go index ea0e3375..ebe73c25 100644 --- a/plugins/kv/boltdb/config.go +++ b/plugins/kv/boltdb/config.go @@ -16,9 +16,22 @@ type Config struct { // InitDefaults initializes default values for the boltdb func (s *Config) InitDefaults() { - s.Dir = "." // current dir - s.Bucket = "rr" // default bucket name - s.File = "rr.db" // default file name - s.Permissions = 0777 // free for all - s.Interval = 60 // default is 60 seconds timeout + if s.Dir == "" { + s.Dir = "." // current dir + } + if s.Bucket == "" { + s.Bucket = "rr" // default bucket name + } + + if s.File == "" { + s.File = "rr.db" // default file name + } + + if s.Permissions == 0 { + s.Permissions = 777 // free for all + } + + if s.Interval == 0 { + s.Interval = 60 // default is 60 seconds timeout + } } diff --git a/plugins/kv/boltdb/plugin.go b/plugins/kv/boltdb/plugin.go index 683d6fc5..1e3d2c34 100644 --- a/plugins/kv/boltdb/plugin.go +++ b/plugins/kv/boltdb/plugin.go @@ -42,15 +42,19 @@ type Plugin struct { func (s *Plugin) Init(log logger.Logger, cfg config.Configurer) error { const op = errors.Op("boltdb_plugin_init") - s.cfg = &Config{} - s.cfg.InitDefaults() + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { return errors.E(op, errors.Disabled, err) } + // add default values + s.cfg.InitDefaults() + // set the logger s.log = log diff --git a/plugins/kv/memcached/config.go b/plugins/kv/memcached/config.go index 62f29ef2..7aad53b6 100644 --- a/plugins/kv/memcached/config.go +++ b/plugins/kv/memcached/config.go @@ -6,5 +6,7 @@ type Config struct { } func (s *Config) InitDefaults() { - s.Addr = []string{"localhost:11211"} // default url for memcached // init logger + if s.Addr == nil { + s.Addr = []string{"localhost:11211"} // default url for memcached + } } diff --git a/plugins/kv/memcached/plugin.go b/plugins/kv/memcached/plugin.go index e8b05567..181b8a49 100644 --- a/plugins/kv/memcached/plugin.go +++ b/plugins/kv/memcached/plugin.go @@ -36,12 +36,16 @@ func NewMemcachedClient(url string) kv.Storage { func (s *Plugin) Init(log logger.Logger, cfg config.Configurer) error { const op = errors.Op("memcached_plugin_init") - s.cfg = &Config{} - s.cfg.InitDefaults() + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { return errors.E(op, err) } + + s.cfg.InitDefaults() + s.log = log return nil } diff --git a/plugins/kv/memory/config.go b/plugins/kv/memory/config.go index 0816f734..e51d09c5 100644 --- a/plugins/kv/memory/config.go +++ b/plugins/kv/memory/config.go @@ -2,14 +2,13 @@ package memory // Config is default config for the in-memory driver type Config struct { - // Enabled or disabled (true or false) - Enabled bool // Interval for the check Interval int } // InitDefaults by default driver is turned off func (c *Config) InitDefaults() { - c.Enabled = false - c.Interval = 60 // seconds + if c.Interval == 0 { + c.Interval = 60 // seconds + } } diff --git a/plugins/kv/memory/plugin.go b/plugins/kv/memory/plugin.go index ddcf88a9..4201a1c0 100644 --- a/plugins/kv/memory/plugin.go +++ b/plugins/kv/memory/plugin.go @@ -25,13 +25,15 @@ type Plugin struct { func (s *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("in_memory_plugin_init") - s.cfg = &Config{} - s.cfg.InitDefaults() - + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { return errors.E(op, err) } + + s.cfg.InitDefaults() s.log = log s.stop = make(chan struct{}, 1) diff --git a/plugins/kv/memory/plugin_unit_test.go b/plugins/kv/memory/plugin_unit_test.go index 6daa0795..1965a696 100644 --- a/plugins/kv/memory/plugin_unit_test.go +++ b/plugins/kv/memory/plugin_unit_test.go @@ -17,7 +17,6 @@ func initStorage() kv.Storage { stop: make(chan struct{}), } p.cfg = &Config{ - Enabled: true, Interval: 1, } diff --git a/plugins/logger/plugin.go b/plugins/logger/plugin.go index 250127b0..719770c0 100644 --- a/plugins/logger/plugin.go +++ b/plugins/logger/plugin.go @@ -13,13 +13,17 @@ const PluginName = "logs" // ZapLogger manages zap logger. type ZapLogger struct { base *zap.Logger - cfg Config + cfg *Config channels ChannelConfig } // Init logger service. func (z *ZapLogger) Init(cfg config.Configurer) error { - const op = errors.Op("zap logger init") + const op = errors.Op("config_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } + err := cfg.UnmarshalKey(PluginName, &z.cfg) if err != nil { return errors.E(op, errors.Disabled, err) diff --git a/plugins/metrics/config.go b/plugins/metrics/config.go index 9459bc9b..dd36005e 100644 --- a/plugins/metrics/config.go +++ b/plugins/metrics/config.go @@ -134,5 +134,7 @@ func (c *Config) getCollectors() (map[string]prometheus.Collector, error) { } func (c *Config) InitDefaults() { - + if c.Address == "" { + c.Address = "localhost:2112" + } } diff --git a/plugins/metrics/plugin.go b/plugins/metrics/plugin.go index 5ed1054e..859f3d24 100644 --- a/plugins/metrics/plugin.go +++ b/plugins/metrics/plugin.go @@ -30,7 +30,7 @@ type statsProvider struct { // Plugin to manage application metrics using Prometheus. type Plugin struct { - cfg Config + cfg *Config log logger.Logger mu sync.Mutex // all receivers are pointers http *http.Server @@ -41,12 +41,15 @@ type Plugin struct { // Init service. func (m *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("metrics_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } + err := cfg.UnmarshalKey(PluginName, &m.cfg) if err != nil { return errors.E(op, errors.Disabled, err) } - // TODO figure out what is Init m.cfg.InitDefaults() m.log = log diff --git a/plugins/redis/config.go b/plugins/redis/config.go index 58766293..41348236 100644 --- a/plugins/redis/config.go +++ b/plugins/redis/config.go @@ -28,5 +28,7 @@ type Config struct { // InitDefaults initializing fill config with default values func (s *Config) InitDefaults() { - s.Addrs = []string{"localhost:6379"} // default addr is pointing to local storage + if s.Addrs == nil { + s.Addrs = []string{"localhost:6379"} // default addr is pointing to local storage + } } diff --git a/plugins/redis/plugin.go b/plugins/redis/plugin.go index 06158b43..204abd17 100644 --- a/plugins/redis/plugin.go +++ b/plugins/redis/plugin.go @@ -24,14 +24,17 @@ func (s *Plugin) GetClient() redis.UniversalClient { func (s *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("redis_plugin_init") - s.cfg = &Config{} - s.cfg.InitDefaults() + + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { return errors.E(op, errors.Disabled, err) } + s.cfg.InitDefaults() s.log = log s.universalClient = redis.NewUniversalClient(&redis.UniversalOptions{ diff --git a/plugins/reload/config.go b/plugins/reload/config.go index 9bce6b25..6fd3af70 100644 --- a/plugins/reload/config.go +++ b/plugins/reload/config.go @@ -36,9 +36,13 @@ type ServiceConfig struct { } // InitDefaults sets missing values to their default values. -func InitDefaults(c *Config) { - c.Interval = time.Second - c.Patterns = []string{".php"} +func (c *Config) InitDefaults() { + if c.Interval == 0 { + c.Interval = time.Second + } + if c.Patterns == nil { + c.Patterns = []string{".php"} + } } // Valid validates the configuration. diff --git a/plugins/reload/plugin.go b/plugins/reload/plugin.go index 93760b8a..d76fb0a4 100644 --- a/plugins/reload/plugin.go +++ b/plugins/reload/plugin.go @@ -27,14 +27,18 @@ type Plugin struct { // Init controller service func (s *Plugin) Init(cfg config.Configurer, log logger.Logger, res resetter.Resetter) error { const op = errors.Op("reload_plugin_init") - s.cfg = &Config{} - InitDefaults(s.cfg) + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } + err := cfg.UnmarshalKey(PluginName, &s.cfg) if err != nil { // disable plugin in case of error return errors.E(op, errors.Disabled, err) } + s.cfg.InitDefaults() + s.log = log s.res = res s.stopc = make(chan struct{}, 1) @@ -101,7 +105,7 @@ func (s *Plugin) Serve() chan error { } }() - // map with configs by services + // map with config by services updated := make(map[string]ServiceConfig, len(s.cfg.Services)) go func() { diff --git a/plugins/rpc/plugin.go b/plugins/rpc/plugin.go index c5813e7b..84ebb3d0 100644 --- a/plugins/rpc/plugin.go +++ b/plugins/rpc/plugin.go @@ -33,7 +33,7 @@ type Plugin struct { // Init rpc service. Must return true if service is enabled. func (s *Plugin) Init(cfg config.Configurer, log logger.Logger) error { - const op = errors.Op("rpc plugin init") + const op = errors.Op("rpc_plugin_init") if !cfg.Has(PluginName) { return errors.E(op, errors.Disabled) } @@ -54,7 +54,7 @@ func (s *Plugin) Init(cfg config.Configurer, log logger.Logger) error { // Serve serves the service. func (s *Plugin) Serve() chan error { - const op = errors.Op("serve rpc plugin") + const op = errors.Op("rpc_plugin_serve") errCh := make(chan error, 1) s.rpc = rpc.NewServer() @@ -105,11 +105,12 @@ func (s *Plugin) Serve() chan error { // Stop stops the service. func (s *Plugin) Stop() error { + const op = errors.Op("rpc_plugin_stop") // store closed state atomic.StoreUint32(s.closed, 1) err := s.listener.Close() if err != nil { - return errors.E(errors.Op("stop RPC socket"), err) + return errors.E(op, err) } return nil } diff --git a/plugins/server/plugin.go b/plugins/server/plugin.go index e4f7c577..0c9c49ea 100644 --- a/plugins/server/plugin.go +++ b/plugins/server/plugin.go @@ -39,6 +39,9 @@ type Plugin struct { // Init application provider. func (server *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("server_plugin_init") + if !cfg.Has(PluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.Unmarshal(&server.cfg) if err != nil { return errors.E(op, errors.Init, err) diff --git a/plugins/static/config.go b/plugins/static/config.go index 17a82cfd..90efea76 100644 --- a/plugins/static/config.go +++ b/plugins/static/config.go @@ -10,7 +10,7 @@ import ( // Config describes file location and controls access to them. type Config struct { - Static struct { + Static *struct { // Dir contains name of directory to control access to. Dir string diff --git a/plugins/static/plugin.go b/plugins/static/plugin.go index 6331037c..fa2bcfbe 100644 --- a/plugins/static/plugin.go +++ b/plugins/static/plugin.go @@ -29,11 +29,18 @@ type Plugin struct { // misconfiguration. Services must not be used without proper configuration pushed first. func (s *Plugin) Init(cfg config.Configurer, log logger.Logger) error { const op = errors.Op("static_plugin_init") + if !cfg.Has(RootPluginName) { + return errors.E(op, errors.Disabled) + } err := cfg.UnmarshalKey(RootPluginName, &s.cfg) if err != nil { return errors.E(op, errors.Disabled, err) } + if s.cfg.Static == nil { + return errors.E(op, errors.Disabled) + } + s.log = log s.root = http.Dir(s.cfg.Static.Dir) |