Merge pull request #343 from Icinga/config-options

Separate required and optional configuration for database and Redis
This commit is contained in:
Eric Lippmann 2021-08-10 12:33:22 +02:00 committed by GitHub
commit 0bf4f4df0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 58 deletions

View file

@ -2,8 +2,6 @@ package config
import (
"fmt"
"github.com/creasty/defaults"
"github.com/icinga/icingadb/internal"
"github.com/icinga/icingadb/pkg/driver"
"github.com/icinga/icingadb/pkg/icingadb"
"github.com/icinga/icingadb/pkg/utils"
@ -18,12 +16,12 @@ var registerDriverOnce sync.Once
// Database defines database client configuration.
type Database struct {
Host string `yaml:"host"`
Port int `yaml:"port"`
Database string `yaml:"database"`
User string `yaml:"user"`
Password string `yaml:"password"`
icingadb.Options `yaml:",inline"`
Host string `yaml:"host"`
Port int `yaml:"port"`
Database string `yaml:"database"`
User string `yaml:"user"`
Password string `yaml:"password"`
Options icingadb.Options `yaml:"options"`
}
// Open prepares the DSN string and driver configuration,
@ -42,8 +40,8 @@ func (d *Database) Open(logger *zap.SugaredLogger) (*icingadb.DB, error) {
return nil, errors.Wrap(err, "can't open database")
}
db.SetMaxIdleConns(d.MaxConnections / 3)
db.SetMaxOpenConns(d.MaxConnections)
db.SetMaxIdleConns(d.Options.MaxConnections / 3)
db.SetMaxOpenConns(d.Options.MaxConnections)
db.Mapper = reflectx.NewMapperFunc("db", func(s string) string {
return utils.Key(s, '_')
@ -51,21 +49,3 @@ func (d *Database) Open(logger *zap.SugaredLogger) (*icingadb.DB, error) {
return icingadb.NewDb(db, logger, &d.Options), nil
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (d *Database) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := defaults.Set(d); err != nil {
return errors.Wrap(err, "can't set default database config")
}
// Prevent recursion.
type self Database
if err := unmarshal((*self)(d)); err != nil {
return internal.CantUnmarshalYAML(err, d)
}
if d.MaxConnectionsPerTable < 1 {
return errors.New("max_connections_per_table must be at least 1")
}
return nil
}

View file

@ -2,9 +2,7 @@ package config
import (
"context"
"github.com/creasty/defaults"
"github.com/go-redis/redis/v8"
"github.com/icinga/icingadb/internal"
"github.com/icinga/icingadb/pkg/backoff"
"github.com/icinga/icingadb/pkg/icingaredis"
"github.com/icinga/icingadb/pkg/retry"
@ -19,9 +17,9 @@ import (
// Redis defines Redis client configuration.
type Redis struct {
Address string `yaml:"address"`
Password string `yaml:"password"`
icingaredis.Options `yaml:",inline"`
Address string `yaml:"address"`
Password string `yaml:"password"`
Options icingaredis.Options `yaml:"options"`
}
// NewClient prepares Redis client configuration,
@ -32,7 +30,7 @@ func (r *Redis) NewClient(logger *zap.SugaredLogger) (*icingaredis.Client, error
Dialer: dialWithLogging(logger),
Password: r.Password,
DB: 0, // Use default DB,
ReadTimeout: r.Timeout,
ReadTimeout: r.Options.Timeout,
})
opts := c.Options()
@ -76,27 +74,3 @@ func dialWithLogging(logger *zap.SugaredLogger) func(context.Context, string, st
return
}
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (r *Redis) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := defaults.Set(r); err != nil {
return errors.Wrapf(err, "can't set defaults %#v", r)
}
// Prevent recursion.
type self Redis
if err := unmarshal((*self)(r)); err != nil {
return internal.CantUnmarshalYAML(err, r)
}
if r.MaxHMGetConnections < 1 {
return errors.New("max_hmget_connections must be at least 1")
}
if r.HMGetCount < 1 {
return errors.New("hmget_count must be at least 1")
}
if r.HScanCount < 1 {
return errors.New("hscan_count must be at least 1")
}
return nil
}

View file

@ -4,6 +4,7 @@ import (
"context"
"database/sql/driver"
"fmt"
"github.com/creasty/defaults"
"github.com/go-sql-driver/mysql"
"github.com/icinga/icingadb/internal"
"github.com/icinga/icingadb/pkg/backoff"
@ -55,6 +56,27 @@ type Options struct {
MaxRowsPerTransaction int `yaml:"MaxRowsPerTransaction" default:"8192"`
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (o *Options) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := defaults.Set(o); err != nil {
return errors.Wrap(err, "can't set default database config")
}
// Prevent recursion.
type self Options
if err := unmarshal((*self)(o)); err != nil {
return internal.CantUnmarshalYAML(err, o)
}
if o.MaxConnections == 0 {
return errors.New("max_connections cannot be 0. Configure a value greater than zero, or use -1 for no connection limit")
}
if o.MaxConnectionsPerTable < 1 {
return errors.New("max_connections_per_table must be at least 1")
}
return nil
}
// NewDb returns a new icingadb.DB wrapper for a pre-existing *sqlx.DB.
func NewDb(db *sqlx.DB, logger *zap.SugaredLogger, options *Options) *DB {
return &DB{

View file

@ -2,7 +2,9 @@ package icingaredis
import (
"context"
"github.com/creasty/defaults"
"github.com/go-redis/redis/v8"
"github.com/icinga/icingadb/internal"
"github.com/icinga/icingadb/pkg/com"
"github.com/icinga/icingadb/pkg/common"
"github.com/icinga/icingadb/pkg/contracts"
@ -32,6 +34,33 @@ type Options struct {
HScanCount int `yaml:"hscan_count" default:"4096"`
}
// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (o *Options) UnmarshalYAML(unmarshal func(interface{}) error) error {
if err := defaults.Set(o); err != nil {
return errors.Wrapf(err, "can't set defaults %#v", o)
}
// Prevent recursion.
type self Options
if err := unmarshal((*self)(o)); err != nil {
return internal.CantUnmarshalYAML(err, o)
}
if o.Timeout == 0 {
return errors.New("timeout cannot be 0. Configure a value greater than zero, or use -1 for no timeout")
}
if o.MaxHMGetConnections < 1 {
return errors.New("max_hmget_connections must be at least 1")
}
if o.HMGetCount < 1 {
return errors.New("hmget_count must be at least 1")
}
if o.HScanCount < 1 {
return errors.New("hscan_count must be at least 1")
}
return nil
}
// NewClient returns a new icingaredis.Client wrapper for a pre-existing *redis.Client.
func NewClient(client *redis.Client, logger *zap.SugaredLogger, options *Options) *Client {
return &Client{Client: client, logger: logger, options: options}