added netbox allocator
This commit is contained in:
parent
fef86deac8
commit
cef74df3e8
10 changed files with 195 additions and 53 deletions
8
TODO
8
TODO
|
|
@ -1,7 +1 @@
|
||||||
VIP for haproxy-lb
|
add logger to vip package?
|
||||||
* take from pool?
|
|
||||||
* extra config?
|
|
||||||
|
|
||||||
cleanup pkg/vip
|
|
||||||
|
|
||||||
test api in followers
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ func main() {
|
||||||
log.Info("creating cluster", "mode", "etcd")
|
log.Info("creating cluster", "mode", "etcd")
|
||||||
c = etcd.NewCluster(logfmtr.New().WithName("etcd"))
|
c = etcd.NewCluster(logfmtr.New().WithName("etcd"))
|
||||||
}
|
}
|
||||||
log.Info("starting api server", "address", cfg.Server.Listen, "tls", cfg.Server.TLS != nil)
|
log.Info("starting api server", "address", cfg.APIServer.Listen, "tls", cfg.APIServer.TLS != nil)
|
||||||
srv, err := api.NewServer(cfg, logfmtr.New().WithName("api"))
|
srv, err := api.NewServer(cfg, logfmtr.New().WithName("api"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err, "init failed")
|
fatal(err, "init failed")
|
||||||
|
|
|
||||||
58
config.yaml
Normal file
58
config.yaml
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
#leaderHook: "/bin/leader_hook.sh"
|
||||||
|
#followerHook: "/bin/follower_hook.sh"
|
||||||
|
#haproxyConfig: "/etc/haproxy/haproxy.cfg"
|
||||||
|
#haproxyService: haproxy
|
||||||
|
#failover:
|
||||||
|
# ip: "192.168.1.1/32"
|
||||||
|
# interface: eth0
|
||||||
|
vip:
|
||||||
|
prefix: "192.168.101.0/24"
|
||||||
|
store:
|
||||||
|
local: {}
|
||||||
|
# netbox:
|
||||||
|
# endpoint: "https://your.net.box"
|
||||||
|
# token: asdf
|
||||||
|
# insecure: false
|
||||||
|
# interface: eth1
|
||||||
|
# label: LB
|
||||||
|
cluster:
|
||||||
|
# raft:
|
||||||
|
# dir: raft
|
||||||
|
# id: node1
|
||||||
|
# listen: 192.168.1.2:7001
|
||||||
|
# peers:
|
||||||
|
# - id: node2
|
||||||
|
# address: 192.168.1.3:7002
|
||||||
|
# - id: node3
|
||||||
|
# address: 192.168.1.4:7003
|
||||||
|
# tls:
|
||||||
|
# cert: cert.pem
|
||||||
|
# key: key.pem
|
||||||
|
# ca: cert.pem
|
||||||
|
# insecure: false
|
||||||
|
# logLevel: off
|
||||||
|
etcd:
|
||||||
|
endpoints:
|
||||||
|
- "http://127.0.0.1:2379"
|
||||||
|
clusterName: "lb"
|
||||||
|
# prefix: "/haproxy-lb"
|
||||||
|
# username: user
|
||||||
|
# password: password
|
||||||
|
# tls:
|
||||||
|
# cert: cert.pem
|
||||||
|
# key: key.pem
|
||||||
|
# ca: cert.pem
|
||||||
|
# insecure: false
|
||||||
|
# logLevel: error
|
||||||
|
apiServer:
|
||||||
|
listen: "127.0.0.1:8001"
|
||||||
|
# tls:
|
||||||
|
# cert: cert.pem
|
||||||
|
# key: key.pem
|
||||||
|
# ca: cert.pem
|
||||||
|
# insecure: false
|
||||||
|
basicAuth:
|
||||||
|
- user: admin
|
||||||
|
# 123456
|
||||||
|
hash: $2b$10$zNfGTAQ94vifj2wtGsv1W.yZRe4/rDBzQixpB6FbrTed4BnHuNqBS
|
||||||
|
prefix: /
|
||||||
3
go.mod
3
go.mod
|
|
@ -3,7 +3,7 @@ module git.giftfish.de/ston1th/haproxy-lb
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
git.giftfish.de/ston1th/netalloc v0.0.0-20210926174801-c39acaee43a5
|
git.giftfish.de/ston1th/netalloc v0.0.0-20211010134723-1daa3f8e0e64
|
||||||
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0
|
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0
|
||||||
github.com/armon/go-metrics v0.3.6 // indirect
|
github.com/armon/go-metrics v0.3.6 // indirect
|
||||||
github.com/fatih/color v1.10.0 // indirect
|
github.com/fatih/color v1.10.0 // indirect
|
||||||
|
|
@ -17,6 +17,7 @@ require (
|
||||||
github.com/iand/logfmtr v0.2.1
|
github.com/iand/logfmtr v0.2.1
|
||||||
github.com/mdlayher/arp v0.0.0-20191213142603-f72070a231fc
|
github.com/mdlayher/arp v0.0.0-20191213142603-f72070a231fc
|
||||||
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
|
github.com/mdlayher/ethernet v0.0.0-20190606142754-0394541c37b7
|
||||||
|
github.com/netbox-community/go-netbox v0.0.0-20210916100335-c6261e6b3c39 // indirect
|
||||||
github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink v1.1.0
|
||||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect
|
||||||
go.etcd.io/etcd/client/v3 v3.5.0
|
go.etcd.io/etcd/client/v3 v3.5.0
|
||||||
|
|
|
||||||
2
go.sum
2
go.sum
|
|
@ -2,6 +2,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
git.giftfish.de/ston1th/netalloc v0.0.0-20210926174801-c39acaee43a5 h1:DQzBQS2lYd4FrHHvVnqIEEfKUEXfbj/NwAAq+vRC4dg=
|
git.giftfish.de/ston1th/netalloc v0.0.0-20210926174801-c39acaee43a5 h1:DQzBQS2lYd4FrHHvVnqIEEfKUEXfbj/NwAAq+vRC4dg=
|
||||||
git.giftfish.de/ston1th/netalloc v0.0.0-20210926174801-c39acaee43a5/go.mod h1:ECRm6vIqNEDXBgJmKyXaBAWucdCzCVH5FG9Hfk6QX0E=
|
git.giftfish.de/ston1th/netalloc v0.0.0-20210926174801-c39acaee43a5/go.mod h1:ECRm6vIqNEDXBgJmKyXaBAWucdCzCVH5FG9Hfk6QX0E=
|
||||||
|
git.giftfish.de/ston1th/netalloc v0.0.0-20211010134723-1daa3f8e0e64 h1:YOJZsnU7JwiVureMZ04LeZYW1i/qId75No8m0F0w29Q=
|
||||||
|
git.giftfish.de/ston1th/netalloc v0.0.0-20211010134723-1daa3f8e0e64/go.mod h1:/+hsFsLucNK49c3N4YPFnseyUIJOiGvNKCjObeBQvqY=
|
||||||
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0 h1:DU0PVdA2EHz2LFGEdkwgJopL9HQh5nFC9GJ7oqzZ300=
|
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0 h1:DU0PVdA2EHz2LFGEdkwgJopL9HQh5nFC9GJ7oqzZ300=
|
||||||
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0/go.mod h1:9dF/aHYkXts6/6oVyJ+vzXCn7NURDaoREaanX0aspx0=
|
git.giftfish.de/ston1th/raftbbolt v0.0.0-20201114165203-b85c94bfc9b0/go.mod h1:9dF/aHYkXts6/6oVyJ+vzXCn7NURDaoREaanX0aspx0=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"git.giftfish.de/ston1th/haproxy-lb/pkg/db"
|
"git.giftfish.de/ston1th/haproxy-lb/pkg/db"
|
||||||
|
|
||||||
"git.giftfish.de/ston1th/netalloc"
|
"git.giftfish.de/ston1th/netalloc"
|
||||||
|
"git.giftfish.de/ston1th/netalloc/netbox"
|
||||||
|
|
||||||
"github.com/go-logr/logr"
|
"github.com/go-logr/logr"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
@ -25,7 +26,6 @@ type Server struct {
|
||||||
log logr.Logger
|
log logr.Logger
|
||||||
|
|
||||||
Data *types.ContextData
|
Data *types.ContextData
|
||||||
cidr string
|
|
||||||
|
|
||||||
init chan struct{}
|
init chan struct{}
|
||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
|
|
@ -33,6 +33,9 @@ type Server struct {
|
||||||
|
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
listen net.Listener
|
listen net.Listener
|
||||||
|
|
||||||
|
prefix string
|
||||||
|
store config.Store
|
||||||
}
|
}
|
||||||
|
|
||||||
type notFoundHandler struct {
|
type notFoundHandler struct {
|
||||||
|
|
@ -48,17 +51,19 @@ func NewServer(c *config.Config, log logr.Logger) (*Server, error) {
|
||||||
s := &Server{
|
s := &Server{
|
||||||
mux: mux.NewRouter(),
|
mux: mux.NewRouter(),
|
||||||
log: log,
|
log: log,
|
||||||
cidr: c.VIP.Prefix,
|
|
||||||
Data: &types.ContextData{},
|
Data: &types.ContextData{},
|
||||||
|
|
||||||
init: make(chan struct{}),
|
init: make(chan struct{}),
|
||||||
stop: make(chan struct{}),
|
stop: make(chan struct{}),
|
||||||
stopKeyReset: make(chan struct{}),
|
stopKeyReset: make(chan struct{}),
|
||||||
}
|
|
||||||
s.Data.Auth = types.NewAuth(c.Server.BasicAuth)
|
|
||||||
|
|
||||||
if c.Server.TLS != nil {
|
prefix: c.VIP.Prefix,
|
||||||
cert, err := tls.LoadX509KeyPair(c.Server.TLS.Cert, c.Server.TLS.Key)
|
store: c.VIP.Store,
|
||||||
|
}
|
||||||
|
s.Data.Auth = types.NewAuth(c.APIServer.BasicAuth)
|
||||||
|
|
||||||
|
if c.APIServer.TLS != nil {
|
||||||
|
cert, err := tls.LoadX509KeyPair(c.APIServer.TLS.Cert, c.APIServer.TLS.Key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -83,13 +88,13 @@ func NewServer(c *config.Config, log logr.Logger) (*Server, error) {
|
||||||
PreferServerCipherSuites: true,
|
PreferServerCipherSuites: true,
|
||||||
Certificates: []tls.Certificate{cert},
|
Certificates: []tls.Certificate{cert},
|
||||||
}
|
}
|
||||||
l, err := tls.Listen("tcp", c.Server.Listen, s.tlsConfig)
|
l, err := tls.Listen("tcp", c.APIServer.Listen, s.tlsConfig)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
s.listen = l
|
s.listen = l
|
||||||
} else {
|
} else {
|
||||||
l, err := net.Listen("tcp", c.Server.Listen)
|
l, err := net.Listen("tcp", c.APIServer.Listen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -107,15 +112,32 @@ func NewServer(c *config.Config, log logr.Logger) (*Server, error) {
|
||||||
func (s *Server) UpdateDB(db *db.DB, leader bool) error {
|
func (s *Server) UpdateDB(db *db.DB, leader bool) error {
|
||||||
s.Data.DB = db
|
s.Data.DB = db
|
||||||
s.Data.Leader = leader
|
s.Data.Leader = leader
|
||||||
if s.Data.Net == nil {
|
if s.store.Local != nil {
|
||||||
na, err := netalloc.NewGenericAlloc(db, s.cidr)
|
if s.Data.Net == nil {
|
||||||
if err != nil {
|
na, err := netalloc.NewGenericAlloc(db, s.prefix)
|
||||||
return err
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Data.Net = na
|
||||||
|
close(s.init)
|
||||||
|
} else {
|
||||||
|
s.Data.Net.SetStore(db)
|
||||||
}
|
}
|
||||||
s.Data.Net = na
|
|
||||||
close(s.init)
|
|
||||||
} else {
|
} else {
|
||||||
s.Data.Net.SetStore(db)
|
if s.Data.Net == nil {
|
||||||
|
nb := s.store.Netbox
|
||||||
|
na, err := netbox.NewAllocator(
|
||||||
|
netbox.WithEndpoint(nb.Endpoint),
|
||||||
|
netbox.WithToken(nb.Token),
|
||||||
|
netbox.WithPrefix(s.prefix),
|
||||||
|
netbox.WithInsecureClient(nb.Insecure),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
s.Data.Net = na
|
||||||
|
close(s.init)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package config
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -13,7 +14,7 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
RaftDir = "raft"
|
RaftDir = "raft"
|
||||||
RaftPort = 7001
|
RaftListen = ":7001"
|
||||||
RaftLogLevel = "off"
|
RaftLogLevel = "off"
|
||||||
|
|
||||||
EtcdLogLevel = "error"
|
EtcdLogLevel = "error"
|
||||||
|
|
@ -48,9 +49,19 @@ func Validate(c *Config) error {
|
||||||
if c.HAProxyService == "" {
|
if c.HAProxyService == "" {
|
||||||
c.HAProxyService = HAProxyService
|
c.HAProxyService = HAProxyService
|
||||||
}
|
}
|
||||||
if c.VIP.Prefix == "" {
|
|
||||||
return errors.New("missing server.prefix config")
|
failover := c.Failover
|
||||||
|
if failover != nil {
|
||||||
|
if failover.IP == "" {
|
||||||
|
return errors.New("missing failover.ip config")
|
||||||
|
|
||||||
|
}
|
||||||
|
_, _, err := net.ParseCIDR(failover.IP)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to parse failover.ip: %w", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if c.LeaderHook != "" {
|
if c.LeaderHook != "" {
|
||||||
if !filepath.IsAbs(c.LeaderHook) {
|
if !filepath.IsAbs(c.LeaderHook) {
|
||||||
return errors.New("leaderHook path must be absolute")
|
return errors.New("leaderHook path must be absolute")
|
||||||
|
|
@ -61,6 +72,28 @@ func Validate(c *Config) error {
|
||||||
return errors.New("followerHook path must be absolute")
|
return errors.New("followerHook path must be absolute")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vip := c.VIP
|
||||||
|
if vip.Prefix == "" {
|
||||||
|
return errors.New("missing vip.prefix config")
|
||||||
|
}
|
||||||
|
local := vip.Store.Local
|
||||||
|
netbox := vip.Store.Netbox
|
||||||
|
if local == nil && netbox == nil {
|
||||||
|
return errors.New("missing vip.store config: local or netbox")
|
||||||
|
}
|
||||||
|
if local != nil && netbox != nil {
|
||||||
|
return errors.New("only one vip.store config allowed: local or netbox")
|
||||||
|
}
|
||||||
|
if netbox != nil {
|
||||||
|
if netbox.Endpoint == "" {
|
||||||
|
return errors.New("missing vip.store.netbox.endpoint config")
|
||||||
|
}
|
||||||
|
if netbox.Token == "" {
|
||||||
|
return errors.New("missing vip.store.netbox.token config")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
raft := c.Cluster.Raft
|
raft := c.Cluster.Raft
|
||||||
if raft != nil {
|
if raft != nil {
|
||||||
if raft.LogLevel == "" {
|
if raft.LogLevel == "" {
|
||||||
|
|
@ -72,8 +105,8 @@ func Validate(c *Config) error {
|
||||||
if raft.ID == "" {
|
if raft.ID == "" {
|
||||||
return errors.New("missing raft.id config")
|
return errors.New("missing raft.id config")
|
||||||
}
|
}
|
||||||
if raft.Address == "" {
|
if raft.Listen == "" {
|
||||||
return errors.New("missing raft.address config")
|
return errors.New("missing raft.listen config")
|
||||||
}
|
}
|
||||||
if len(raft.Peers) < 2 {
|
if len(raft.Peers) < 2 {
|
||||||
return errors.New("minimum number of remote peers: 2")
|
return errors.New("minimum number of remote peers: 2")
|
||||||
|
|
@ -119,10 +152,10 @@ func Validate(c *Config) error {
|
||||||
if raft != nil && etcd != nil {
|
if raft != nil && etcd != nil {
|
||||||
return errors.New("only one cluster config allowed: raft or etcd")
|
return errors.New("only one cluster config allowed: raft or etcd")
|
||||||
}
|
}
|
||||||
if len(c.Server.BasicAuth) == 0 {
|
if len(c.APIServer.BasicAuth) == 0 {
|
||||||
return errors.New("missing basic auth configuration for api users")
|
return errors.New("missing basic auth configuration for api users")
|
||||||
}
|
}
|
||||||
for _, u := range c.Server.BasicAuth {
|
for _, u := range c.APIServer.BasicAuth {
|
||||||
if u.User == "" {
|
if u.User == "" {
|
||||||
return errors.New("basic auth username can not be empty")
|
return errors.New("basic auth username can not be empty")
|
||||||
}
|
}
|
||||||
|
|
@ -135,31 +168,37 @@ func Validate(c *Config) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
LeaderHook string `yaml:"leaderHook,omitempty"`
|
LeaderHook string `yaml:"leaderHook,omitempty"`
|
||||||
FollowerHook string `yaml:"followerHook,omitempty"`
|
FollowerHook string `yaml:"followerHook,omitempty"`
|
||||||
HAProxyConfig string `yaml:"haproxyConfig,omitempty"`
|
HAProxyConfig string `yaml:"haproxyConfig,omitempty"`
|
||||||
HAProxyService string `yaml:"haproxyService,omitempty"`
|
HAProxyService string `yaml:"haproxyService,omitempty"`
|
||||||
VIP VIP `yaml:"vip"`
|
Failover *Failover `yaml:"failover"`
|
||||||
Cluster Cluster `yaml:"cluster"`
|
VIP VIP `yaml:"vip"`
|
||||||
Server Server `yaml:"server"`
|
Cluster Cluster `yaml:"cluster"`
|
||||||
|
APIServer APIServer `yaml:"apiServer"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Server struct {
|
type Failover struct {
|
||||||
Listen string `yaml:"listen"`
|
IP string `yaml:"ip"`
|
||||||
TLS *TLS `yaml:"tls"`
|
Interface string `yaml:"interface"`
|
||||||
BasicAuth []BasicAuth `yaml:"basicAuth"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type VIP struct {
|
type VIP struct {
|
||||||
Prefix string `yaml:"prefix"`
|
Prefix string `yaml:"prefix"`
|
||||||
|
Store Store `yaml:"store"`
|
||||||
Interface string `yaml:"interface,omitempty"`
|
Interface string `yaml:"interface,omitempty"`
|
||||||
Label string `yaml:"label,omitempty"`
|
Label string `yaml:"label,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type BasicAuth struct {
|
type Store struct {
|
||||||
User string `yaml:"user"`
|
Local *struct{} `yaml:"local"`
|
||||||
Hash string `yaml:"hash"`
|
Netbox *Netbox `yaml:"netbox"`
|
||||||
Prefix string `yaml:"prefix"`
|
}
|
||||||
|
|
||||||
|
type Netbox struct {
|
||||||
|
Endpoint string `yaml:"endpoint"`
|
||||||
|
Token string `yaml:"token"`
|
||||||
|
Insecure bool `yaml:"insecure,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Cluster struct {
|
type Cluster struct {
|
||||||
|
|
@ -170,7 +209,7 @@ type Cluster struct {
|
||||||
type Raft struct {
|
type Raft struct {
|
||||||
Dir string `yaml:"dir,omitempty"`
|
Dir string `yaml:"dir,omitempty"`
|
||||||
ID string `yaml:"id"`
|
ID string `yaml:"id"`
|
||||||
Address string `yaml:"address"`
|
Listen string `yaml:"listen"`
|
||||||
Peers []RaftPeer `yaml:"peers"`
|
Peers []RaftPeer `yaml:"peers"`
|
||||||
TLS *TLS `yaml:"tls,omitempty"`
|
TLS *TLS `yaml:"tls,omitempty"`
|
||||||
LogLevel string `yaml:"logLevel,omitempty"`
|
LogLevel string `yaml:"logLevel,omitempty"`
|
||||||
|
|
@ -191,10 +230,22 @@ type RaftPeer struct {
|
||||||
|
|
||||||
type Etcd struct {
|
type Etcd struct {
|
||||||
Endpoints []string `yaml:"endpoints"`
|
Endpoints []string `yaml:"endpoints"`
|
||||||
Prefix string `yaml:"prefix"`
|
|
||||||
ClusterName string `yaml:"clusterName"`
|
ClusterName string `yaml:"clusterName"`
|
||||||
|
Prefix string `yaml:"prefix,omitempty"`
|
||||||
Username string `yaml:"username,omitempty"`
|
Username string `yaml:"username,omitempty"`
|
||||||
Password string `yaml:"password,omitempty"`
|
Password string `yaml:"password,omitempty"`
|
||||||
TLS *TLS `yaml:"tls,omitempty"`
|
TLS *TLS `yaml:"tls,omitempty"`
|
||||||
LogLevel string `yaml:"logLevel,omitempty"`
|
LogLevel string `yaml:"logLevel,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type APIServer struct {
|
||||||
|
Listen string `yaml:"listen"`
|
||||||
|
TLS *TLS `yaml:"tls"`
|
||||||
|
BasicAuth []BasicAuth `yaml:"basicAuth"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BasicAuth struct {
|
||||||
|
User string `yaml:"user"`
|
||||||
|
Hash string `yaml:"hash"`
|
||||||
|
Prefix string `yaml:"prefix"`
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewLBController(cfg *config.Config, srv *api.Server, log logr.Logger) (callbacks cluster.Callbacks, err error) {
|
func NewLBController(cfg *config.Config, srv *api.Server, log logr.Logger) (callbacks cluster.Callbacks, err error) {
|
||||||
|
var fo *vip.Network
|
||||||
|
if cfg.Failover != nil {
|
||||||
|
fo, err = vip.NewNetwork(cfg.Failover.Interface)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
n, err := vip.NewNetworkWithLabel(cfg.VIP.Interface, cfg.VIP.Label)
|
n, err := vip.NewNetworkWithLabel(cfg.VIP.Interface, cfg.VIP.Label)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
|
@ -57,6 +65,9 @@ func NewLBController(cfg *config.Config, srv *api.Server, log logr.Logger) (call
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
log.Info("leading", "id", cc.ID())
|
log.Info("leading", "id", cc.ID())
|
||||||
|
if cfg.Failover != nil {
|
||||||
|
addIPs(log, fo, []string{cfg.Failover.IP})
|
||||||
|
}
|
||||||
ips, err := db.GetDeletedIPs()
|
ips, err := db.GetDeletedIPs()
|
||||||
if err != nil && err != cluster.ErrPrefixNotFound {
|
if err != nil && err != cluster.ErrPrefixNotFound {
|
||||||
log.Error(err, "error reading deleted ips list")
|
log.Error(err, "error reading deleted ips list")
|
||||||
|
|
@ -150,6 +161,9 @@ func NewLBController(cfg *config.Config, srv *api.Server, log logr.Logger) (call
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Cleanup: func(ctx context.Context, cc cluster.CallbackContext) {
|
Cleanup: func(ctx context.Context, cc cluster.CallbackContext) {
|
||||||
|
if cfg.Failover != nil {
|
||||||
|
deleteIPs(log, fo, fo.GetIPs())
|
||||||
|
}
|
||||||
deleteIPs(log, n, n.GetIPs())
|
deleteIPs(log, n, n.GetIPs())
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@ func (c *Cluster) Start(raftcfg *config.Config) error {
|
||||||
transport = raft.NewNetworkTransportWithLogger(s, pool, timeout, hcl)
|
transport = raft.NewNetworkTransportWithLogger(s, pool, timeout, hcl)
|
||||||
} else {
|
} else {
|
||||||
log.V(1).Info("setup", "transport", "tcp")
|
log.V(1).Info("setup", "transport", "tcp")
|
||||||
address, err := net.ResolveTCPAddr("tcp", cfg.Address)
|
address, err := net.ResolveTCPAddr("tcp", cfg.Listen)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
transport, err = raft.NewTCPTransportWithLogger(cfg.Address, address, pool, timeout, hcl)
|
transport, err = raft.NewTCPTransportWithLogger(cfg.Listen, address, pool, timeout, hcl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -85,10 +85,10 @@ func (c *Cluster) Start(raftcfg *config.Config) error {
|
||||||
// Add Local Peer
|
// Add Local Peer
|
||||||
configuration.Servers = append(configuration.Servers, raft.Server{
|
configuration.Servers = append(configuration.Servers, raft.Server{
|
||||||
ID: raft.ServerID(cfg.ID),
|
ID: raft.ServerID(cfg.ID),
|
||||||
Address: raft.ServerAddress(cfg.Address),
|
Address: raft.ServerAddress(cfg.Listen),
|
||||||
})
|
})
|
||||||
for _, p := range cfg.Peers {
|
for _, p := range cfg.Peers {
|
||||||
if cfg.Address != p.Address {
|
if cfg.Listen != p.Address {
|
||||||
configuration.Servers = append(configuration.Servers, raft.Server{
|
configuration.Servers = append(configuration.Servers, raft.Server{
|
||||||
ID: raft.ServerID(p.ID),
|
ID: raft.ServerID(p.ID),
|
||||||
Address: raft.ServerAddress(p.Address)})
|
Address: raft.ServerAddress(p.Address)})
|
||||||
|
|
@ -113,7 +113,7 @@ func (c *Cluster) Start(raftcfg *config.Config) error {
|
||||||
leading := false
|
leading := false
|
||||||
following := false
|
following := false
|
||||||
for {
|
for {
|
||||||
if !leading && cfg.Address == string(c.r.Leader()) {
|
if !leading && cfg.Listen == string(c.r.Leader()) {
|
||||||
leading = true
|
leading = true
|
||||||
go c.leader(ctx)
|
go c.leader(ctx)
|
||||||
} else if !following && !leading {
|
} else if !following && !leading {
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func NewStream(cfg *config.Raft) (s *stream, err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
l, err := tls.Listen("tcp", cfg.Address, &tls.Config{
|
l, err := tls.Listen("tcp", cfg.Listen, &tls.Config{
|
||||||
MinVersion: tls.VersionTLS13,
|
MinVersion: tls.VersionTLS13,
|
||||||
CipherSuites: ciphers,
|
CipherSuites: ciphers,
|
||||||
CurvePreferences: curves,
|
CurvePreferences: curves,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue