package config import ( "errors" "fmt" "os" "gopkg.in/yaml.v2" ) const ( RaftDir = "raft" RaftPort = 7001 ) func ParseFile(file string) (cfg *Config, err error) { if file == "" { return nil, errors.New("missing config file") } f, err := os.Open(file) if err != nil { return } defer f.Close() cfg = new(Config) err = yaml.NewDecoder(f).Decode(cfg) if err != nil { return } err = Validate(cfg) return } func Validate(c *Config) error { if len(c.VirtualIPs) == 0 { return errors.New("missing virtualIPs config") } raft := c.Cluster.Raft if raft != nil { if raft.Dir == "" { raft.Dir = RaftDir } if raft.Level == "" { raft.Level = "off" } if raft.ID == "" { return errors.New("missing raft.id config") } if raft.Address == "" { return errors.New("missing raft.address config") } if len(raft.Peers) < 2 { return errors.New("minimum number of remote peers: 2") } for i, v := range raft.Peers { if v.ID == "" { return fmt.Errorf("missing raft.peers[%d].id config", i) } if v.Address == "" { return fmt.Errorf("missing raft.peers[%d].address config", i) } } } etcd := c.Cluster.Etcd if etcd != nil { } if raft == nil && etcd == nil { return errors.New("missing cluster config: raft or etcd") } if raft != nil && etcd != nil { return errors.New("only one cluster config allowed: raft or etcd") } return nil } type Config struct { VirtualIPs []string `yaml:"virtualIPs"` Interface string `yaml:"interface,omitempty"` IPLabel string `yaml:"label,omitempty"` LeaderHook string `yaml:"leaderHook,omitempty"` FollowerHook string `yaml:"followerHook,omitempty"` Cluster Cluster `yaml:"cluster"` } type Cluster struct { Raft *Raft `yaml:"raft,omitempty"` Etcd *Etcd `yaml:"etcd,omitempty"` } type Raft struct { Dir string `yaml:"dir,omitempty"` ID string `yaml:"id"` Address string `yaml:"address"` Level string `yaml:"level"` Peers []RaftPeer `yaml:"peers"` TLS *TLS `yaml:"tls,omitempty"` } type TLS struct { Cert string `yaml:"cert"` Key string `yaml:"key"` CA string `yaml:"ca,omitempty"` Insecure bool `yaml:"insecure,omitempty"` } // RaftPeer details the configuration of all cluster peers type RaftPeer struct { ID string `yaml:"id"` Address string `yaml:"address"` } type Etcd struct { Endpoints []string `yaml:"endpoints"` Prefix string `yaml:"prefix"` ClusterName string `yaml:"clusterName"` }