Better validation of all config file fields (#6090)

Add Validate() to serverConfig to call it at server
startup and in Admin SetConfig handler to minimize
errors scenario after server restart.
This commit is contained in:
Anis Elleuch
2018-07-18 20:22:29 +02:00
committed by kannappanr
parent 758a80e39b
commit e8a008f5b5
14 changed files with 375 additions and 54 deletions

View File

@@ -43,6 +43,17 @@ type AMQPArgs struct {
AutoDeleted bool `json:"autoDeleted"`
}
// Validate AMQP arguments
func (a *AMQPArgs) Validate() error {
if !a.Enable {
return nil
}
if _, err := amqp.ParseURI(a.URL.String()); err != nil {
return err
}
return nil
}
// AMQPTarget - AMQP target
type AMQPTarget struct {
id event.TargetID

View File

@@ -18,8 +18,10 @@ package target
import (
"context"
"errors"
"fmt"
"net/url"
"strings"
"time"
"github.com/minio/minio/pkg/event"
@@ -36,6 +38,26 @@ type ElasticsearchArgs struct {
Index string `json:"index"`
}
// Validate ElasticsearchArgs fields
func (a ElasticsearchArgs) Validate() error {
if !a.Enable {
return nil
}
if a.URL.IsEmpty() {
return errors.New("empty URL")
}
if a.Format != "" {
f := strings.ToLower(a.Format)
if f != event.NamespaceFormat && f != event.AccessFormat {
return errors.New("format value unrecognized")
}
}
if a.Index == "" {
return errors.New("empty index value")
}
return nil
}
// ElasticsearchTarget - Elasticsearch target.
type ElasticsearchTarget struct {
id event.TargetID

View File

@@ -18,6 +18,7 @@ package target
import (
"encoding/json"
"errors"
"net/url"
"github.com/minio/minio/pkg/event"
@@ -33,6 +34,22 @@ type KafkaArgs struct {
Topic string `json:"topic"`
}
// Validate KafkaArgs fields
func (k KafkaArgs) Validate() error {
if !k.Enable {
return nil
}
if len(k.Brokers) == 0 {
return errors.New("no broker address found")
}
for _, b := range k.Brokers {
if _, err := xnet.ParseHost(b.String()); err != nil {
return err
}
}
return nil
}
// KafkaTarget - Kafka target.
type KafkaTarget struct {
id event.TargetID

View File

@@ -20,6 +20,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"net/url"
"time"
@@ -42,6 +43,23 @@ type MQTTArgs struct {
RootCAs *x509.CertPool `json:"-"`
}
// Validate MQTTArgs fields
func (m MQTTArgs) Validate() error {
if !m.Enable {
return nil
}
u, err := xnet.ParseURL(m.Broker.String())
if err != nil {
return err
}
switch u.Scheme {
case "ws", "wss", "tcp", "ssl", "tls", "tcps":
default:
return errors.New("unknown protocol in broker address")
}
return nil
}
// MQTTTarget - MQTT target.
type MQTTTarget struct {
id event.TargetID

View File

@@ -58,6 +58,8 @@ import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
"time"
"github.com/go-sql-driver/mysql"
@@ -88,6 +90,42 @@ type MySQLArgs struct {
Database string `json:"database"`
}
// Validate MySQLArgs fields
func (m MySQLArgs) Validate() error {
if !m.Enable {
return nil
}
if m.Format != "" {
f := strings.ToLower(m.Format)
if f != event.NamespaceFormat && f != event.AccessFormat {
return fmt.Errorf("unrecognized format")
}
}
if m.Table == "" {
return fmt.Errorf("table unspecified")
}
if m.DSN != "" {
if _, err := mysql.ParseDSN(m.DSN); err != nil {
return err
}
} else {
// Some fields need to be specified when DSN is unspecified
if m.Port == "" {
return fmt.Errorf("unspecified port")
}
if _, err := strconv.Atoi(m.Port); err != nil {
return fmt.Errorf("invalid port")
}
if m.Database == "" {
return fmt.Errorf("database unspecified")
}
}
return nil
}
// MySQLTarget - MySQL target.
type MySQLTarget struct {
id event.TargetID

View File

@@ -18,6 +18,7 @@ package target
import (
"encoding/json"
"errors"
"net/url"
"github.com/minio/minio/pkg/event"
@@ -45,6 +46,32 @@ type NATSArgs struct {
} `json:"streaming"`
}
// Validate NATSArgs fields
func (n NATSArgs) Validate() error {
if !n.Enable {
return nil
}
if n.Address.IsEmpty() {
return errors.New("empty address")
}
if n.Subject == "" {
return errors.New("empty subject")
}
if n.Streaming.Enable {
if n.Streaming.ClusterID == "" {
return errors.New("empty cluster id")
}
if n.Streaming.ClientID == "" {
return errors.New("empty client id")
}
}
return nil
}
// NATSTarget - NATS target.
type NATSTarget struct {
id event.TargetID

View File

@@ -58,10 +58,11 @@ import (
"encoding/json"
"fmt"
"net/url"
"strconv"
"strings"
"time"
_ "github.com/lib/pq" // Register postgres driver
"github.com/lib/pq" // Register postgres driver
"github.com/minio/minio/pkg/event"
xnet "github.com/minio/minio/pkg/net"
)
@@ -89,6 +90,41 @@ type PostgreSQLArgs struct {
Database string `json:"database"` // default: same as user
}
// Validate PostgreSQLArgs fields
func (p PostgreSQLArgs) Validate() error {
if !p.Enable {
return nil
}
if p.Table == "" {
return fmt.Errorf("empty table name")
}
if p.Format != "" {
f := strings.ToLower(p.Format)
if f != event.NamespaceFormat && f != event.AccessFormat {
return fmt.Errorf("unrecognized format value")
}
}
if p.ConnectionString != "" {
if _, err := pq.ParseURL(p.ConnectionString); err != nil {
return err
}
} else {
// Some fields need to be specified when ConnectionString is unspecified
if p.Port == "" {
return fmt.Errorf("unspecified port")
}
if _, err := strconv.Atoi(p.Port); err != nil {
return fmt.Errorf("invalid port")
}
if p.Database == "" {
return fmt.Errorf("database unspecified")
}
}
return nil
}
// PostgreSQLTarget - PostgreSQL target.
type PostgreSQLTarget struct {
id event.TargetID

View File

@@ -20,6 +20,7 @@ import (
"encoding/json"
"fmt"
"net/url"
"strings"
"time"
"github.com/garyburd/redigo/redis"
@@ -36,6 +37,26 @@ type RedisArgs struct {
Key string `json:"key"`
}
// Validate RedisArgs fields
func (r RedisArgs) Validate() error {
if !r.Enable {
return nil
}
if r.Format != "" {
f := strings.ToLower(r.Format)
if f != event.NamespaceFormat && f != event.AccessFormat {
return fmt.Errorf("unrecognized format")
}
}
if r.Key == "" {
return fmt.Errorf("empty key")
}
return nil
}
// RedisTarget - Redis target.
type RedisTarget struct {
id event.TargetID

View File

@@ -21,6 +21,7 @@ import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"errors"
"fmt"
"net"
"net/http"
@@ -38,6 +39,17 @@ type WebhookArgs struct {
RootCAs *x509.CertPool `json:"-"`
}
// Validate WebhookArgs fields
func (w WebhookArgs) Validate() error {
if !w.Enable {
return nil
}
if w.Endpoint.IsEmpty() {
return errors.New("endpoint empty")
}
return nil
}
// WebhookTarget - Webhook target.
type WebhookTarget struct {
id event.TargetID