mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/kube-vip/kube-vip.git
synced 2026-09-20 08:03:47 +08:00
Adds golangci-lint to check for code errors + clean up resulting findings after running.
Signed-off-by: Steve Sloka <slokas@vmware.com>
This commit is contained in:
13
.golangci.yml
Normal file
13
.golangci.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
run:
|
||||
timeout: 10m
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- gofmt
|
||||
- goimports
|
||||
- revive
|
||||
- gosec
|
||||
- misspell
|
||||
- unconvert
|
||||
- unparam
|
||||
2
Makefile
2
Makefile
@@ -87,7 +87,7 @@ check:
|
||||
go mod tidy
|
||||
test -z "$(git status --porcelain)"
|
||||
test -z $(shell gofmt -l main.go | tee /dev/stderr) || echo "[WARN] Fix formatting issues with 'make fmt'"
|
||||
golint ./...
|
||||
golangci-lint run
|
||||
go vet ./...
|
||||
|
||||
run: install
|
||||
|
||||
@@ -24,13 +24,13 @@ func init() {
|
||||
kubeVipSampleConfig.Flags().BoolVar(&cliConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
|
||||
kubeVipSampleConfig.Flags().BoolVar(&cliConfig.EnableARP, "arp", true, "Use ARP broadcasts to improve VIP re-allocations")
|
||||
kubeVipSampleConfig.Flags().StringVar(&cliLocalPeer, "localPeer", "server1:192.168.0.1:10000", "Settings for this peer, format: id:address:port")
|
||||
kubeVipSampleConfig.Flags().StringSliceVar(&cliRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma seperated remotePeers, format: id:address:port")
|
||||
kubeVipSampleConfig.Flags().StringSliceVar(&cliRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma separated remotePeers, format: id:address:port")
|
||||
// Load Balancer flags
|
||||
kubeVipSampleConfig.Flags().BoolVar(&cliConfigLB.BindToVip, "lbBindToVip", false, "Bind example load balancer to VIP")
|
||||
kubeVipSampleConfig.Flags().StringVar(&cliConfigLB.Type, "lbType", "tcp", "Type of load balancer instance (TCP/HTTP)")
|
||||
kubeVipSampleConfig.Flags().StringVar(&cliConfigLB.Name, "lbName", "Example Load Balancer", "The name of a load balancer instance")
|
||||
kubeVipSampleConfig.Flags().IntVar(&cliConfigLB.Port, "lbPort", 8080, "Port that load balancer will expose on")
|
||||
kubeVipSampleConfig.Flags().StringSliceVar(&cliBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma seperated backends, format: address:port")
|
||||
kubeVipSampleConfig.Flags().StringSliceVar(&cliBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma separated backends, format: address:port")
|
||||
}
|
||||
|
||||
var kubeVipSampleConfig = &cobra.Command{
|
||||
@@ -72,13 +72,13 @@ var kubeVipSampleConfig = &cobra.Command{
|
||||
|
||||
err := cliConfig.ParseFlags(cliLocalPeer, cliRemotePeers, cliBackends)
|
||||
if err != nil {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
err = kubevip.ParseEnvironment(&cliConfig)
|
||||
if err != nil {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln(err)
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ var kubeKubeadm = &cobra.Command{
|
||||
Use: "kubeadm",
|
||||
Short: "Kubeadm functions",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
},
|
||||
}
|
||||
@@ -43,15 +43,19 @@ var kubeKubeadmInit = &cobra.Command{
|
||||
log.SetLevel(log.Level(logLevel))
|
||||
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
err := kubevip.ParseEnvironment(&initConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing environment from config: %v", err)
|
||||
}
|
||||
|
||||
// TODO - check for certain things VIP/interfaces
|
||||
if initConfig.Interface == "" {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No interface is specified for kube-vip to bind to")
|
||||
}
|
||||
|
||||
if initConfig.VIP == "" && initConfig.Address == "" {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No address is specified for kube-vip to expose services on")
|
||||
}
|
||||
cfg := kubevip.GeneratePodManifestFromConfig(&initConfig, Release.Version, inCluster)
|
||||
@@ -69,15 +73,19 @@ var kubeKubeadmJoin = &cobra.Command{
|
||||
|
||||
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
err := kubevip.ParseEnvironment(&initConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("Error parsing environment from config: %v", err)
|
||||
}
|
||||
|
||||
// TODO - check for certain things VIP/interfaces
|
||||
if initConfig.Interface == "" {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No interface is specified for kube-vip to bind to")
|
||||
}
|
||||
|
||||
if initConfig.VIP == "" && initConfig.Address == "" {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No address is specified for kube-vip to expose services on")
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ var kubeManifest = &cobra.Command{
|
||||
Use: "manifest",
|
||||
Short: "Manifest functions",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
},
|
||||
}
|
||||
@@ -41,11 +41,13 @@ var kubeManifestPod = &cobra.Command{
|
||||
log.SetLevel(log.Level(logLevel))
|
||||
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
if err := kubevip.ParseEnvironment(&initConfig); err != nil {
|
||||
log.Fatalf("Error parsing environment from config: %v", err)
|
||||
}
|
||||
|
||||
// The control plane has a requirement for a VIP being specified
|
||||
if initConfig.EnableControlPane && (initConfig.VIP == "" && initConfig.Address == "" && !initConfig.DDNS) {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No address is specified for kube-vip to expose services on")
|
||||
}
|
||||
cfg := kubevip.GeneratePodManifestFromConfig(&initConfig, Release.Version, inCluster)
|
||||
@@ -62,12 +64,15 @@ var kubeManifestDaemon = &cobra.Command{
|
||||
log.SetLevel(log.Level(logLevel))
|
||||
initConfig.LoadBalancers = append(initConfig.LoadBalancers, initLoadBalancer)
|
||||
// TODO - A load of text detailing what's actually happening
|
||||
kubevip.ParseEnvironment(&initConfig)
|
||||
if err := kubevip.ParseEnvironment(&initConfig); err != nil {
|
||||
log.Fatalf("error parsing environment config: %v", err)
|
||||
}
|
||||
|
||||
// TODO - check for certain things VIP/interfaces
|
||||
|
||||
// The control plane has a requirement for a VIP being specified
|
||||
if initConfig.EnableControlPane && (initConfig.VIP == "" && initConfig.Address == "" && !initConfig.DDNS) {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalln("No address is specified for kube-vip to expose services on")
|
||||
}
|
||||
cfg := kubevip.GenerateDeamonsetManifestFromConfig(&initConfig, Release.Version, inCluster, taint)
|
||||
|
||||
@@ -33,14 +33,14 @@ func init() {
|
||||
kubeVipStart.Flags().BoolVar(&startConfig.StartAsLeader, "startAsLeader", false, "Start this instance as the cluster leader")
|
||||
kubeVipStart.Flags().BoolVar(&startConfig.EnableARP, "arp", false, "Use ARP broadcasts to improve VIP re-allocations")
|
||||
kubeVipStart.Flags().StringVar(&startLocalPeer, "localPeer", "server1:192.168.0.1:10000", "Settings for this peer, format: id:address:port")
|
||||
kubeVipStart.Flags().StringSliceVar(&startRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma seperated remotePeers, format: id:address:port")
|
||||
kubeVipStart.Flags().StringSliceVar(&startRemotePeers, "remotePeers", []string{"server2:192.168.0.2:10000", "server3:192.168.0.3:10000"}, "Comma separated remotePeers, format: id:address:port")
|
||||
// Load Balancer flags
|
||||
kubeVipStart.Flags().BoolVar(&startConfigLB.BindToVip, "lbBindToVip", false, "Bind example load balancer to VIP")
|
||||
kubeVipStart.Flags().StringVar(&startConfigLB.Type, "lbType", "tcp", "Type of load balancer instance (TCP/HTTP)")
|
||||
kubeVipStart.Flags().StringVar(&startConfigLB.Name, "lbName", "Example Load Balancer", "The name of a load balancer instance")
|
||||
kubeVipStart.Flags().IntVar(&startConfigLB.Port, "lbPort", 8080, "Port that load balancer will expose on")
|
||||
kubeVipStart.Flags().IntVar(&startConfigLB.BackendPort, "lbBackEndPort", 6443, "A port that all backends may be using (optional)")
|
||||
kubeVipStart.Flags().StringSliceVar(&startBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma seperated backends, format: address:port")
|
||||
kubeVipStart.Flags().StringSliceVar(&startBackends, "lbBackends", []string{"192.168.0.1:8080", "192.168.0.2:8080"}, "Comma separated backends, format: address:port")
|
||||
|
||||
// Cluster configuration
|
||||
kubeVipStart.Flags().StringVar(&startKubeConfigPath, "kubeConfig", "/etc/kubernetes/admin.conf", "The path of a kubernetes configuration file")
|
||||
@@ -83,7 +83,9 @@ var kubeVipStart = &cobra.Command{
|
||||
if startConfig.SingleNode {
|
||||
// If the Virtual IP isn't disabled then create the netlink configuration
|
||||
// Start a single node cluster
|
||||
newCluster.StartSingleNode(&startConfig, disableVIP)
|
||||
if err := newCluster.StartSingleNode(&startConfig, disableVIP); err != nil {
|
||||
log.Errorf("error starting single node: %v", err)
|
||||
}
|
||||
} else {
|
||||
if disableVIP {
|
||||
log.Fatalln("Cluster mode requires the Virtual IP to be enabled, use single node with no VIP")
|
||||
|
||||
@@ -21,16 +21,16 @@ import (
|
||||
var configPath string
|
||||
|
||||
// Path to the configuration file
|
||||
var namespace string
|
||||
// var namespace string
|
||||
|
||||
// Disable the Virtual IP (bind to the existing network stack)
|
||||
var disableVIP bool
|
||||
|
||||
// Disable the Virtual IP (bind to the existing network stack)
|
||||
var controlPlane bool
|
||||
// var controlPlane bool
|
||||
|
||||
// Run as a load balancer service (within a pod / kubernetes)
|
||||
var serviceArp bool
|
||||
// var serviceArp bool
|
||||
|
||||
// ConfigMap name within a Kubernetes cluster
|
||||
var configMap string
|
||||
@@ -114,7 +114,7 @@ func init() {
|
||||
kubeVipCmd.PersistentFlags().Uint32Var(&initConfig.BGPPeerConfig.AS, "peerAS", 65000, "The AS number for a BGP peer")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.BGPPeerConfig.Password, "peerPass", "", "The md5 password for a BGP peer")
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.BGPPeerConfig.MultiHop, "multihop", false, "This will enable BGP multihop support")
|
||||
kubeVipCmd.PersistentFlags().StringSliceVar(&initConfig.BGPPeers, "bgppeers", []string{}, "Comma seperated BGP Peer, format: address:as:password:multihop")
|
||||
kubeVipCmd.PersistentFlags().StringSliceVar(&initConfig.BGPPeers, "bgppeers", []string{}, "Comma separated BGP Peer, format: address:as:password:multihop")
|
||||
|
||||
// Control plane specific flags
|
||||
kubeVipCmd.PersistentFlags().StringVarP(&initConfig.Namespace, "namespace", "n", "kube-system", "The configuration map defined within the cluster")
|
||||
@@ -129,7 +129,7 @@ func init() {
|
||||
kubeVipCmd.PersistentFlags().BoolVar(&initConfig.EnableServices, "services", false, "Enable Kubernetes services, hybrid mode")
|
||||
|
||||
// Prometheus HTTP Server
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.PrometheusHTTPServer, "promethuesHTTPServer", ":2112", "Host and port used to expose Promethues metrics via an HTTP server")
|
||||
kubeVipCmd.PersistentFlags().StringVar(&initConfig.PrometheusHTTPServer, "promethuesHTTPServer", ":2112", "Host and port used to expose Prometheus metrics via an HTTP server")
|
||||
|
||||
kubeVipCmd.AddCommand(kubeKubeadm)
|
||||
kubeVipCmd.AddCommand(kubeManifest)
|
||||
@@ -167,7 +167,7 @@ var kubeVipSample = &cobra.Command{
|
||||
Use: "sample",
|
||||
Short: "Generate a Sample configuration",
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
},
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ var kubeVipManager = &cobra.Command{
|
||||
log.Infof("No interface is specified for VIP in config, auto-detecting default Interface")
|
||||
defaultIF, err := vip.GetDefaultGatewayInterface()
|
||||
if err != nil {
|
||||
cmd.Help()
|
||||
_ = cmd.Help()
|
||||
log.Fatalf("unable to detect default interface -> [%v]", err)
|
||||
}
|
||||
initConfig.Interface = defaultIF.Name
|
||||
@@ -266,6 +266,7 @@ var kubeVipManager = &cobra.Command{
|
||||
},
|
||||
}
|
||||
|
||||
// PrometheusHTTPServerConfig defines the Prometheus server configuration.
|
||||
type PrometheusHTTPServerConfig struct {
|
||||
// Addr sets the http server address used to expose the metric endpoint
|
||||
Addr string
|
||||
|
||||
@@ -7,12 +7,12 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"github.com/golang/protobuf/ptypes" //nolint
|
||||
"github.com/golang/protobuf/ptypes/any"
|
||||
api "github.com/osrg/gobgp/api"
|
||||
)
|
||||
|
||||
//AddPeer will add peers to the BGP configuration
|
||||
// AddPeer will add peers to the BGP configuration
|
||||
func (b *Server) AddPeer(peer Peer) (err error) {
|
||||
port := 179
|
||||
|
||||
@@ -20,7 +20,7 @@ func (b *Server) AddPeer(peer Peer) (err error) {
|
||||
peer.Address = t[0]
|
||||
|
||||
if port, err = strconv.Atoi(t[1]); err != nil {
|
||||
return fmt.Errorf("Unable to parse port '%s' as int: %s", t[1], err)
|
||||
return fmt.Errorf("unable to parse port '%s' as int: %s", t[1], err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,11 +73,13 @@ func (b *Server) getPath(ip net.IP) *api.Path {
|
||||
pfxLen = 128
|
||||
}
|
||||
|
||||
//nolint
|
||||
nlri, _ := ptypes.MarshalAny(&api.IPAddressPrefix{
|
||||
Prefix: ip.String(),
|
||||
PrefixLen: pfxLen,
|
||||
})
|
||||
|
||||
//nolint
|
||||
a1, _ := ptypes.MarshalAny(&api.OriginAttribute{
|
||||
Origin: 0,
|
||||
})
|
||||
@@ -91,6 +93,7 @@ func (b *Server) getPath(ip net.IP) *api.Path {
|
||||
nh = b.c.RouterID
|
||||
}
|
||||
|
||||
//nolint
|
||||
a2, _ := ptypes.MarshalAny(&api.NextHopAttribute{
|
||||
NextHop: nh,
|
||||
})
|
||||
|
||||
@@ -126,6 +126,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
signal.Notify(signalChan, syscall.SIGTERM)
|
||||
|
||||
// Add Notification for SIGKILL (sent from Kubernetes)
|
||||
//nolint
|
||||
signal.Notify(signalChan, syscall.SIGKILL)
|
||||
|
||||
go func() {
|
||||
@@ -137,7 +138,10 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
}()
|
||||
|
||||
// (attempt to) Remove the virtual IP, incase it already exists
|
||||
cluster.Network.DeleteIP()
|
||||
err = cluster.Network.DeleteIP()
|
||||
if err != nil {
|
||||
log.Errorf("could not delete virtualIP: %v", err)
|
||||
}
|
||||
|
||||
// Managers for Vip load balancers and none-vip loadbalancers
|
||||
nonVipLB := loadbalancer.LBManager{}
|
||||
@@ -150,7 +154,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
}
|
||||
}()
|
||||
|
||||
// If Packet is enabled then we can begin our preperation work
|
||||
// If Packet is enabled then we can begin our preparation work
|
||||
var packetClient *packngo.Client
|
||||
if c.EnableMetal {
|
||||
if c.ProviderConfig != "" {
|
||||
@@ -194,7 +198,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
if len(c.LoadBalancers) != 0 {
|
||||
for x := range c.LoadBalancers {
|
||||
// If the load balancer doesn't bind to the VIP
|
||||
if c.LoadBalancers[x].BindToVip == false {
|
||||
if !c.LoadBalancers[x].BindToVip {
|
||||
err = nonVipLB.Add("", &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -267,7 +271,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
|
||||
for x := range c.LoadBalancers {
|
||||
|
||||
if c.LoadBalancers[x].BindToVip == true {
|
||||
if c.LoadBalancers[x].BindToVip {
|
||||
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -287,7 +291,7 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
}
|
||||
}
|
||||
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
ctxArp, cancelArp = context.WithCancel(context.Background())
|
||||
|
||||
ipString := cluster.Network.IP()
|
||||
@@ -375,10 +379,6 @@ func (cluster *Cluster) StartLeaderCluster(c *kubevip.Config, sm *Manager, bgpSe
|
||||
OnNewLeader: func(identity string) {
|
||||
// we're notified when new leader elected
|
||||
log.Infof("Node [%s] is assuming leadership of the cluster", identity)
|
||||
|
||||
if identity == id {
|
||||
// We have the lock
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
@@ -51,7 +51,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
|
||||
// If we want to start a node as leader then we will not add any remote peers, this will leave this as a cluster of one
|
||||
// The remotePeers will add themselves to the cluster as they're added
|
||||
if c.StartAsLeader != true {
|
||||
if !c.StartAsLeader {
|
||||
for x := range c.RemotePeers {
|
||||
// Make sure that we don't add in this server twice
|
||||
if c.LocalPeer.Address != c.RemotePeers[x].Address {
|
||||
@@ -87,7 +87,10 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
isLeader := c.StartAsLeader
|
||||
|
||||
// (attempt to) Remove the virtual IP, incase it already exists
|
||||
cluster.Network.DeleteIP()
|
||||
err = cluster.Network.DeleteIP()
|
||||
if err != nil {
|
||||
log.Errorf("error deleting virtual IP: %v", err)
|
||||
}
|
||||
|
||||
// leader log broadcast - this counter is used to stop flooding STDOUT with leader log entries
|
||||
var leaderbroadcast int
|
||||
@@ -98,7 +101,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
// Iterate through all Configurations
|
||||
for x := range c.LoadBalancers {
|
||||
// If the load balancer doesn't bind to the VIP
|
||||
if c.LoadBalancers[x].BindToVip == false {
|
||||
if !c.LoadBalancers[x].BindToVip {
|
||||
err = nonVipLB.Add("", &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -112,15 +115,6 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
|
||||
go func() {
|
||||
for {
|
||||
if c.AddPeersAsBackends == true {
|
||||
// Get addresses and change backends
|
||||
|
||||
// c.LoadBalancers[0].Backends
|
||||
// for x := range raftServer.GetConfiguration().Configuration().Servers {
|
||||
// raftServer.GetConfiguration().Configuration().Servers[x].Address
|
||||
// }
|
||||
|
||||
}
|
||||
// Broadcast the current leader on this node if it's the correct time (every leaderLogcount * time.Second)
|
||||
if leaderbroadcast == leaderLogcount {
|
||||
log.Infof("The Node [%s] is leading", raftServer.Leader())
|
||||
@@ -130,7 +124,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
// ensure that if this node is the leader, it is set as the leader
|
||||
if localAddress == string(raftServer.Leader()) {
|
||||
// Re-broadcast arp to ensure network stays up to date
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
// Gratuitous ARP, will broadcast to new MAC <-> IP
|
||||
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
|
||||
if err != nil {
|
||||
@@ -143,7 +137,10 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
}
|
||||
} else {
|
||||
// (attempt to) Remove the virtual IP, incase it already exists to keep nodes clean
|
||||
cluster.Network.DeleteIP()
|
||||
err := cluster.Network.DeleteIP()
|
||||
if err != nil {
|
||||
log.Errorf("could not delete virtualIP: %v", err)
|
||||
}
|
||||
isLeader = false
|
||||
}
|
||||
|
||||
@@ -166,7 +163,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
|
||||
for x := range c.LoadBalancers {
|
||||
|
||||
if c.LoadBalancers[x].BindToVip == true {
|
||||
if c.LoadBalancers[x].BindToVip {
|
||||
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -187,7 +184,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
}
|
||||
}
|
||||
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
// Gratuitous ARP, will broadcast to new MAC <-> IP
|
||||
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
|
||||
if err != nil {
|
||||
@@ -220,7 +217,7 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
log.WithFields(log.Fields{"error": err, "ip": cluster.Network.IP(), "interface": cluster.Network.Interface()}).Error("Could not check ip")
|
||||
}
|
||||
|
||||
if result == false {
|
||||
if !result {
|
||||
log.Error("This node is leader and is adopting the virtual IP")
|
||||
|
||||
err = cluster.Network.AddIP()
|
||||
@@ -231,14 +228,14 @@ func (cluster *Cluster) StartRaftCluster(c *kubevip.Config) error {
|
||||
|
||||
for x := range c.LoadBalancers {
|
||||
|
||||
if c.LoadBalancers[x].BindToVip == true {
|
||||
if c.LoadBalancers[x].BindToVip {
|
||||
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
// Gratuitous ARP, will broadcast to new MAC <-> IP
|
||||
err = vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
|
||||
if err != nil {
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) error {
|
||||
// Start kube-vip as a single node server
|
||||
|
||||
// TODO - Split all this code out as a seperate function
|
||||
// TODO - Split all this code out as a separate function
|
||||
log.Infoln("Starting kube-vip as a single node cluster")
|
||||
|
||||
log.Info("This node is assuming leadership of the cluster")
|
||||
@@ -32,7 +32,7 @@ func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) erro
|
||||
// Iterate through all Configurations
|
||||
for x := range c.LoadBalancers {
|
||||
// If the load balancer doesn't bind to the VIP
|
||||
if c.LoadBalancers[x].BindToVip == false {
|
||||
if !c.LoadBalancers[x].BindToVip {
|
||||
err := nonVipLB.Add("", &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -55,7 +55,7 @@ func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) erro
|
||||
// Once we have the VIP running, start the load balancer(s) that bind to the VIP
|
||||
for x := range c.LoadBalancers {
|
||||
|
||||
if c.LoadBalancers[x].BindToVip == true {
|
||||
if c.LoadBalancers[x].BindToVip {
|
||||
err = VipLB.Add(cluster.Network.IP(), &c.LoadBalancers[x])
|
||||
if err != nil {
|
||||
log.Warnf("Error creating loadbalancer [%s] type [%s] -> error [%s]", c.LoadBalancers[x].Name, c.LoadBalancers[x].Type, err)
|
||||
@@ -64,7 +64,7 @@ func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) erro
|
||||
}
|
||||
}
|
||||
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
// Gratuitous ARP, will broadcast to new MAC <-> IP
|
||||
err := vip.ARPSendGratuitous(cluster.Network.IP(), c.Interface)
|
||||
if err != nil {
|
||||
@@ -73,6 +73,7 @@ func (cluster *Cluster) StartSingleNode(c *kubevip.Config, disableVIP bool) erro
|
||||
}
|
||||
|
||||
go func() {
|
||||
//nolint
|
||||
for {
|
||||
select {
|
||||
case <-cluster.stop:
|
||||
@@ -114,6 +115,7 @@ func (cluster *Cluster) StartLoadBalancerService(c *kubevip.Config, bgp *bgp.Ser
|
||||
|
||||
// use a Go context so we can tell the arp loop code when we
|
||||
// want to step down
|
||||
//nolint
|
||||
ctxArp, cancelArp := context.WithCancel(context.Background())
|
||||
defer cancelArp()
|
||||
|
||||
@@ -130,7 +132,7 @@ func (cluster *Cluster) StartLoadBalancerService(c *kubevip.Config, bgp *bgp.Ser
|
||||
log.Warnf("%v", err)
|
||||
}
|
||||
|
||||
if c.EnableARP == true {
|
||||
if c.EnableARP {
|
||||
ctxArp, cancelArp = context.WithCancel(context.Background())
|
||||
|
||||
ipString := cluster.Network.IP()
|
||||
@@ -196,6 +198,7 @@ func (cluster *Cluster) StartLoadBalancerService(c *kubevip.Config, bgp *bgp.Ser
|
||||
}
|
||||
|
||||
go func() {
|
||||
//nolint
|
||||
for {
|
||||
select {
|
||||
case <-cluster.stop:
|
||||
|
||||
@@ -6,16 +6,16 @@ const (
|
||||
//vipArp - defines if the arp broadcast should be enabled
|
||||
vipArp = "vip_arp"
|
||||
|
||||
//vipLeaderElection - defines if the kubernetes algorithim should be used
|
||||
//vipLeaderElection - defines if the kubernetes algorithm should be used
|
||||
vipLeaderElection = "vip_leaderelection"
|
||||
|
||||
//vipLeaderElection - defines if the kubernetes algorithim should be used
|
||||
//vipLeaderElection - defines if the kubernetes algorithm should be used
|
||||
vipLeaseDuration = "vip_leaseduration"
|
||||
|
||||
//vipLeaderElection - defines if the kubernetes algorithim should be used
|
||||
//vipLeaderElection - defines if the kubernetes algorithm should be used
|
||||
vipRenewDeadline = "vip_renewdeadline"
|
||||
|
||||
//vipLeaderElection - defines if the kubernetes algorithim should be used
|
||||
//vipLeaderElection - defines if the kubernetes algorithm should be used
|
||||
vipRetryPeriod = "vip_retryperiod"
|
||||
|
||||
//vipLogLevel - defines the level of logging to produce (5 being the most verbose)
|
||||
@@ -66,7 +66,7 @@ const (
|
||||
vipLocalPeer = "vip_localpeer"
|
||||
|
||||
//vipRemotePeers defines the configuration of the local raft peer
|
||||
vipRemotePeers = "vip_remotepeers"
|
||||
// vipRemotePeers = "vip_remotepeers"
|
||||
|
||||
//vipAddPeersToLB defines that RAFT peers should be added to the load-balancer
|
||||
vipAddPeersToLB = "vip_addpeerstolb"
|
||||
@@ -98,7 +98,7 @@ const (
|
||||
//bgpPeerAS defines the AS for a BGP peer
|
||||
bgpPeerAS = "bgp_peeras"
|
||||
//bgpPeerAS defines the AS for a BGP peer
|
||||
bgpPeerPassword = "bgp_peerpass"
|
||||
bgpPeerPassword = "bgp_peerpass" // nolint
|
||||
//bgpMultiHop enables mulithop routing
|
||||
bgpMultiHop = "bgp_multihop"
|
||||
//bgpSourceIF defines the source interface for BGP peering
|
||||
@@ -137,5 +137,5 @@ const (
|
||||
lbBackends = "lb_backends"
|
||||
|
||||
//vipConfigMap defines the configmap that kube-vip will watch for service definitions
|
||||
vipConfigMap = "vip_configmap"
|
||||
// vipConfigMap = "vip_configmap"
|
||||
)
|
||||
|
||||
@@ -56,7 +56,7 @@ func ParseEnvironment(c *Config) error {
|
||||
c.EnableLeaderElection = b
|
||||
}
|
||||
|
||||
// Attempt to find the Lease configuration from teh environment variables
|
||||
// Attempt to find the Lease configuration from the environment variables
|
||||
env = os.Getenv(vipLeaseDuration)
|
||||
if env != "" {
|
||||
i, err := strconv.ParseInt(env, 10, 32)
|
||||
@@ -196,7 +196,7 @@ func ParseEnvironment(c *Config) error {
|
||||
c.EnableARP = b
|
||||
}
|
||||
|
||||
//Removal of seperate peer
|
||||
//Removal of separate peer
|
||||
env = os.Getenv(vipLocalPeer)
|
||||
if env != "" {
|
||||
// Parse the string in format <id>:<address>:<port>
|
||||
@@ -213,10 +213,10 @@ func ParseEnvironment(c *Config) error {
|
||||
// Remove existing peers
|
||||
c.RemotePeers = []RaftPeer{}
|
||||
|
||||
// Parse the remote peers (comma seperated)
|
||||
// Parse the remote peers (comma separated)
|
||||
s := strings.Split(env, ",")
|
||||
if len(s) == 0 {
|
||||
return fmt.Errorf("The Remote Peer List [%s] is unable to be parsed, should be in comma seperated format <id>:<address>:<port>", env)
|
||||
return fmt.Errorf("The Remote Peer List [%s] is unable to be parsed, should be in comma separated format <id>:<address>:<port>", env)
|
||||
}
|
||||
for x := range s {
|
||||
// Parse the each remote peer string in format <id>:<address>:<port>
|
||||
@@ -426,10 +426,10 @@ func parseEnvironmentLoadBalancer(c *Config) error {
|
||||
// Remove existing backends
|
||||
c.LoadBalancers[0].Backends = []BackEnd{}
|
||||
|
||||
// Parse the remote peers (comma seperated)
|
||||
// Parse the remote peers (comma separated)
|
||||
s := strings.Split(env, ",")
|
||||
if len(s) == 0 {
|
||||
return fmt.Errorf("The Backends List [%s] is unable to be parsed, should be in comma seperated format <address>:<port>", env)
|
||||
return fmt.Errorf("The Backends List [%s] is unable to be parsed, should be in comma separated format <address>:<port>", env)
|
||||
}
|
||||
for x := range s {
|
||||
// Parse the each remote peer string in format <address>:<port>
|
||||
@@ -473,7 +473,7 @@ func generatePodSpec(c *Config, imageVersion string, inCluster bool) *corev1.Pod
|
||||
newEnvironment = append(newEnvironment, iface...)
|
||||
}
|
||||
|
||||
// Detect if we should be using a seperate interface for sercices
|
||||
// Detect if we should be using a separate interface for sercices
|
||||
if c.ServicesInterface != "" {
|
||||
// build environment variables
|
||||
svcInterface := []corev1.EnvVar{
|
||||
@@ -743,7 +743,7 @@ func generatePodSpec(c *Config, imageVersion string, inCluster bool) *corev1.Pod
|
||||
})
|
||||
}
|
||||
|
||||
// Parse peers into a comma seperated string
|
||||
// Parse peers into a comma separated string
|
||||
if len(c.RemotePeers) != 0 {
|
||||
var peers string
|
||||
for x := range c.RemotePeers {
|
||||
|
||||
@@ -55,7 +55,7 @@ func OpenConfig(path string) (*Config, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// If data is read succesfully parse the yaml
|
||||
// If data is read successfully parse the yaml
|
||||
var c Config
|
||||
err = yaml.Unmarshal(configData, &c)
|
||||
if err != nil {
|
||||
|
||||
@@ -99,7 +99,7 @@ type Config struct {
|
||||
// LeaderElection defines all of the settings for Kubernetes LeaderElection
|
||||
type LeaderElection struct {
|
||||
|
||||
// EnableLeaderElection will use the Kubernetes leader election algorithim
|
||||
// EnableLeaderElection will use the Kubernetes leader election algorithm
|
||||
EnableLeaderElection bool `yaml:"enableLeaderElection"`
|
||||
|
||||
// Lease Duration - length of time a lease can be held for
|
||||
|
||||
@@ -109,6 +109,7 @@ func NewLeaderElector(lec LeaderElectionConfig) (*LeaderElector, error) {
|
||||
}
|
||||
|
||||
// LeaderElectionConfig defines the configuration for the leaderElection
|
||||
// nolint
|
||||
type LeaderElectionConfig struct {
|
||||
// Lock is the resource that will be used for locking
|
||||
Lock rl.Interface
|
||||
@@ -191,7 +192,7 @@ type LeaderElector struct {
|
||||
metrics leaderMetricsAdapter
|
||||
|
||||
// name is the name of the resource lock for debugging
|
||||
name string
|
||||
// name string
|
||||
}
|
||||
|
||||
// Run starts the leader election loop
|
||||
|
||||
@@ -28,7 +28,7 @@ type leaderMetricsAdapter interface {
|
||||
leaderOff(name string)
|
||||
}
|
||||
|
||||
// GaugeMetric represents a single numerical value that can arbitrarily go up
|
||||
// SwitchMetric represents a single numerical value that can arbitrarily go up
|
||||
// and down.
|
||||
type SwitchMetric interface {
|
||||
On(name string)
|
||||
@@ -72,7 +72,8 @@ type MetricsProvider interface {
|
||||
|
||||
type noopMetricsProvider struct{}
|
||||
|
||||
func (_ noopMetricsProvider) NewLeaderMetric() SwitchMetric {
|
||||
// NewLeaderMetric returns a new SwitchMetric.
|
||||
func (nmp noopMetricsProvider) NewLeaderMetric() SwitchMetric {
|
||||
return noopMetric{}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func persistentConnection(frontendConnection net.Conn, lb *kubevip.LoadBalancer)
|
||||
wg.Done()
|
||||
}()
|
||||
// go func() {
|
||||
// Begin copying recieving (endpoint -> back to frontend)
|
||||
// Begin copying receiving (endpoint -> back to frontend)
|
||||
bytes, err := io.Copy(frontendConnection, endpoint)
|
||||
log.Debugf("[%d] bytes of data sent to client", bytes)
|
||||
if err != nil {
|
||||
@@ -116,7 +116,7 @@ func persistentUDPConnection(frontendConnection net.Conn, lb *kubevip.LoadBalanc
|
||||
wg.Done()
|
||||
}()
|
||||
// go func() {
|
||||
// Begin copying recieving (endpoint -> back to frontend)
|
||||
// Begin copying receiving (endpoint -> back to frontend)
|
||||
bytes, err := io.Copy(frontendConnection, endpoint)
|
||||
log.Debugf("[%d] bytes of data sent to client", bytes)
|
||||
if err != nil {
|
||||
|
||||
@@ -57,11 +57,10 @@ func (lb *LBInstance) startHTTP(bindAddress string) error {
|
||||
|
||||
server := &http.Server{Addr: frontEnd, Handler: mux}
|
||||
|
||||
go func() error {
|
||||
go func() {
|
||||
if err := server.ListenAndServe(); err != nil {
|
||||
return err
|
||||
log.Fatalf("error starting http server: %v", err)
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
// If the stop channel is closed then the server will be gracefully shut down
|
||||
@@ -120,7 +119,9 @@ func StartHTTP(lb *kubevip.LoadBalancer, address string) error {
|
||||
mux := http.NewServeMux()
|
||||
mux.HandleFunc("/", handler)
|
||||
log.Infof("Starting server listening [%s]", frontEnd)
|
||||
http.ListenAndServe(frontEnd, mux)
|
||||
if err := http.ListenAndServe(frontEnd, mux); err != nil {
|
||||
log.Fatalf("error serving: %v", err)
|
||||
}
|
||||
// Should never get here
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
package loadbalancer
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
@@ -61,118 +59,3 @@ func (lb *LBInstance) startTCP(bindAddress string) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// startTCPDNU - Start TCP service Do not use
|
||||
// This stops the service by closing the listener and then ignorning the error from Accept()
|
||||
func (lb *LBInstance) startTCPDNU(bindAddress string) error {
|
||||
fullAddress := fmt.Sprintf("%s:%d", bindAddress, lb.instance.Port)
|
||||
log.Infof("Starting TCP Load Balancer for service [%s]", fullAddress)
|
||||
|
||||
//l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", bindAddress, lb.instance.Port))
|
||||
laddr, err := net.ResolveTCPAddr("tcp", fullAddress)
|
||||
if nil != err {
|
||||
log.Errorln(err)
|
||||
}
|
||||
l, err := net.ListenTCP("tcp", laddr)
|
||||
if nil != err {
|
||||
return fmt.Errorf("Unable to bind [%s]", err.Error())
|
||||
}
|
||||
go func() {
|
||||
<-lb.stop
|
||||
log.Debugln("Closing listener")
|
||||
|
||||
// We've closed the stop channel
|
||||
err = l.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
// Close the stopped channel as the listener has been stopped
|
||||
close(lb.stopped)
|
||||
|
||||
}()
|
||||
|
||||
go func() {
|
||||
for {
|
||||
|
||||
fd, err := l.Accept()
|
||||
if err != nil {
|
||||
// Check it it's an accept timeout
|
||||
if opErr, ok := err.(*net.OpError); ok && opErr.Timeout() {
|
||||
continue
|
||||
} else if err != io.EOF {
|
||||
log.Errorf("TCP Accept error [%s]", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
go persistentConnection(fd, lb.instance)
|
||||
//go processRequests(lb.instance, fd)
|
||||
}
|
||||
// }
|
||||
}()
|
||||
log.Infof("Load Balancer [%s] started", lb.instance.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// user -> [LB]
|
||||
// [LB] (select end pot) -> [endpoint]
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
func processRequests(lb *kubevip.LoadBalancer, frontendConnection net.Conn) {
|
||||
for {
|
||||
// READ FROM client
|
||||
buf := make([]byte, 1024*1024)
|
||||
datalen, err := frontendConnection.Read(buf)
|
||||
if err != nil {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
log.Debugf("Sent [%d] bytes to the LB", datalen)
|
||||
data := buf[0:datalen]
|
||||
|
||||
// Connect to Endpoint
|
||||
ep, err := lb.ReturnEndpointAddr()
|
||||
if err != nil {
|
||||
log.Errorf("No Backends available")
|
||||
}
|
||||
log.Debugf("Attempting endpoint [%s]", ep)
|
||||
|
||||
endpoint, err := net.Dial("tcp", ep)
|
||||
if err != nil {
|
||||
fmt.Println("dial error:", err)
|
||||
// return nil, err
|
||||
}
|
||||
log.Debugf("succesfully connected to [%s]", ep)
|
||||
|
||||
// Set a timeout
|
||||
endpoint.SetReadDeadline(time.Now().Add(time.Second * 1))
|
||||
|
||||
b, err := endpointRequest(endpoint, ep, string(data))
|
||||
|
||||
_, err = frontendConnection.Write(b)
|
||||
if err != nil {
|
||||
log.Fatal("Write: ", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// endpointRequest will take an endpoint address and send the data and wait for the response
|
||||
func endpointRequest(endpoint net.Conn, endpointAddr, request string) ([]byte, error) {
|
||||
|
||||
// defer conn.Close()
|
||||
datalen, err := fmt.Fprintf(endpoint, request)
|
||||
if err != nil {
|
||||
fmt.Println("dial error:", err)
|
||||
return nil, err
|
||||
}
|
||||
log.Debugf("Sent [%d] bytes to the endpoint", datalen)
|
||||
|
||||
var b bytes.Buffer
|
||||
io.Copy(&b, endpoint)
|
||||
log.Debugf("Recieved [%d] from the endpoint", b.Len())
|
||||
return b.Bytes(), nil
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ type Manager struct {
|
||||
config *kubevip.Config
|
||||
|
||||
// Manager services
|
||||
service bool
|
||||
// service bool
|
||||
|
||||
// Keeps track of all running instances
|
||||
serviceInstances []Instance
|
||||
@@ -45,7 +45,7 @@ type Manager struct {
|
||||
// This channel is used to signal a shutdown
|
||||
signalChan chan os.Signal
|
||||
|
||||
// This is a promethues counter used to count the number of events received
|
||||
// This is a prometheus counter used to count the number of events received
|
||||
// from the service watcher
|
||||
countServiceWatchEvent *prometheus.CounterVec
|
||||
}
|
||||
@@ -148,6 +148,7 @@ func (sm *Manager) Start() error {
|
||||
signal.Notify(sm.signalChan, syscall.SIGTERM)
|
||||
|
||||
// Add Notification for SIGKILL (sent from Kubernetes)
|
||||
//nolint
|
||||
signal.Notify(sm.signalChan, syscall.SIGKILL)
|
||||
|
||||
// If BGP is enabled then we start a server instance that will broadcast VIPs
|
||||
|
||||
@@ -110,7 +110,7 @@ func (sm *Manager) startARP() error {
|
||||
// Set the struct to nil so nothing should use it in future
|
||||
sm.upnp = nil
|
||||
} else {
|
||||
log.Infof("Succesfully enabled UPNP, Gateway address [%s]", sm.upnp.GatewayOutsideIP)
|
||||
log.Infof("Successfully enabled UPNP, Gateway address [%s]", sm.upnp.GatewayOutsideIP)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ func (sm *Manager) startBGP() error {
|
||||
//var ns string
|
||||
var err error
|
||||
|
||||
// If Packet is enabled then we can begin our preperation work
|
||||
// If Packet is enabled then we can begin our preparation work
|
||||
var packetClient *packngo.Client
|
||||
if sm.config.EnableMetal {
|
||||
if sm.config.ProviderConfig != "" {
|
||||
|
||||
@@ -2,6 +2,7 @@ package manager
|
||||
|
||||
import "github.com/prometheus/client_golang/prometheus"
|
||||
|
||||
// PrometheusCollector defines a service watch event counter.
|
||||
func (sm *Manager) PrometheusCollector() []prometheus.Collector {
|
||||
return []prometheus.Collector{sm.countServiceWatchEvent}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,18 @@ func (sm *Manager) deleteService(uid string) error {
|
||||
} else {
|
||||
// Flip the found when we match
|
||||
found = true
|
||||
if sm.serviceInstances[x].isDHCP == true {
|
||||
if sm.serviceInstances[x].isDHCP {
|
||||
sm.serviceInstances[x].dhcpClient.Stop()
|
||||
macvlan, err := netlink.LinkByName(sm.serviceInstances[x].dhcpInterface)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error finding VIP Interface, for deleting DHCP Link : %v", err)
|
||||
return fmt.Errorf("error finding VIP Interface: %v", err)
|
||||
}
|
||||
|
||||
err = netlink.LinkDel(macvlan)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting DHCP Link : %v", err)
|
||||
}
|
||||
|
||||
netlink.LinkDel(macvlan)
|
||||
}
|
||||
if sm.serviceInstances[x].vipConfig.EnableBGP {
|
||||
cidrVip := fmt.Sprintf("%s/%s", sm.serviceInstances[x].vipConfig.VIP, sm.serviceInstances[x].vipConfig.VIPCIDR)
|
||||
@@ -61,8 +65,8 @@ func (sm *Manager) deleteService(uid string) error {
|
||||
}
|
||||
}
|
||||
// If we've been through all services and not found the correct one then error
|
||||
if found == false {
|
||||
return fmt.Errorf("Unable to find/stop service [%s]", uid)
|
||||
if !found {
|
||||
return fmt.Errorf("unable to find/stop service [%s]", uid)
|
||||
}
|
||||
|
||||
// Update the service array
|
||||
|
||||
@@ -183,7 +183,6 @@ func (sm *Manager) annotationsWatcher() error {
|
||||
sm.config.BGPPeerConfig = bgpPeer
|
||||
|
||||
rw.Stop()
|
||||
break
|
||||
case watch.Deleted:
|
||||
node, ok := event.Object.(*v1.Node)
|
||||
if !ok {
|
||||
|
||||
@@ -19,7 +19,7 @@ func AttachEIP(c *packngo.Client, k *kubevip.Config, hostname string) error {
|
||||
// Fallback to attempting to find the project by name
|
||||
proj := findProject(k.MetalProject, c)
|
||||
if proj == nil {
|
||||
return fmt.Errorf("Unable to find Project [%s]", k.MetalProject)
|
||||
return fmt.Errorf("unable to find Project [%s]", k.MetalProject)
|
||||
}
|
||||
|
||||
projID = proj.ID
|
||||
@@ -40,7 +40,10 @@ func AttachEIP(c *packngo.Client, k *kubevip.Config, hostname string) error {
|
||||
// If attachements already exist then remove them
|
||||
if len(ip.Assignments) != 0 {
|
||||
hrefID := path.Base(ip.Assignments[0].Href)
|
||||
c.DeviceIPs.Unassign(hrefID)
|
||||
_, err := c.DeviceIPs.Unassign(hrefID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to unassign deviceIP %q: %v", hrefID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +51,7 @@ func AttachEIP(c *packngo.Client, k *kubevip.Config, hostname string) error {
|
||||
// Lookup this server through the packet API
|
||||
thisDevice := findSelf(c, projID)
|
||||
if thisDevice == nil {
|
||||
return fmt.Errorf("Unable to find local/this device in packet API")
|
||||
return fmt.Errorf("unable to find local/this device in packet API")
|
||||
}
|
||||
|
||||
// Assign the EIP to this device
|
||||
|
||||
@@ -45,7 +45,7 @@ type Manager struct {
|
||||
// This channel is used to signal a shutdown
|
||||
signalChan chan os.Signal
|
||||
|
||||
// This is a promethues counter used to count the number of events received
|
||||
// This is a prometheus counter used to count the number of events received
|
||||
// from the service watcher
|
||||
countServiceWatchEvent *prometheus.CounterVec
|
||||
}
|
||||
@@ -77,7 +77,7 @@ type Instance struct {
|
||||
// NewManager will create a new managing object
|
||||
func NewManager(configMap string, config *kubevip.Config) (*Manager, error) {
|
||||
var clientset *kubernetes.Clientset
|
||||
if OutSideCluster == false {
|
||||
if !OutSideCluster {
|
||||
// This will attempt to load the configuration when running within a POD
|
||||
cfg, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
|
||||
@@ -38,7 +38,7 @@ func (sm *Manager) startARP() error {
|
||||
// Set the struct to nil so nothing should use it in future
|
||||
sm.upnp = nil
|
||||
} else {
|
||||
log.Infof("Succesfully enabled UPNP, Gateway address [%s]", sm.upnp.GatewayOutsideIP)
|
||||
log.Infof("Successfully enabled UPNP, Gateway address [%s]", sm.upnp.GatewayOutsideIP)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +89,7 @@ func (sm *Manager) startARP() error {
|
||||
signal.Notify(signalChan, syscall.SIGTERM)
|
||||
|
||||
// Add Notification for SIGKILL (sent from Kubernetes)
|
||||
//nolint
|
||||
signal.Notify(signalChan, syscall.SIGKILL)
|
||||
go func() {
|
||||
<-signalChan
|
||||
@@ -112,7 +113,9 @@ func (sm *Manager) startARP() error {
|
||||
RetryPeriod: 1 * time.Second,
|
||||
Callbacks: leaderelection.LeaderCallbacks{
|
||||
OnStartedLeading: func(ctx context.Context) {
|
||||
sm.servicesWatcher(ctx)
|
||||
if err := sm.servicesWatcher(ctx); err != nil {
|
||||
log.Fatalf("error starting services watcher: %v", err)
|
||||
}
|
||||
},
|
||||
OnStoppedLeading: func() {
|
||||
// we can do cleanup here
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
// Start will begin the Manager, which will start services and watch the configmap
|
||||
func (sm *Manager) startBGP() error {
|
||||
|
||||
// If Packet is enabled then we can begin our preperation work
|
||||
// If Packet is enabled then we can begin our preparation work
|
||||
var packetClient *packngo.Client
|
||||
var err error
|
||||
if sm.config.EnableMetal {
|
||||
@@ -63,6 +63,7 @@ func (sm *Manager) startBGP() error {
|
||||
signal.Notify(signalChan, syscall.SIGTERM)
|
||||
|
||||
// Add Notification for SIGKILL (sent from Kubernetes)
|
||||
//nolint
|
||||
signal.Notify(signalChan, syscall.SIGKILL)
|
||||
go func() {
|
||||
<-signalChan
|
||||
@@ -71,7 +72,9 @@ func (sm *Manager) startBGP() error {
|
||||
cancel()
|
||||
}()
|
||||
|
||||
sm.servicesWatcher(ctx)
|
||||
if err := sm.servicesWatcher(ctx); err != nil {
|
||||
log.Fatalf("error starting services watcher: %v", err)
|
||||
}
|
||||
|
||||
log.Infof("Shutting down Kube-Vip")
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ func (sm *Manager) stopService(uid string) error {
|
||||
sm.serviceInstances[x].cluster.Stop()
|
||||
}
|
||||
}
|
||||
if found == false {
|
||||
return fmt.Errorf("Unable to find/stop service [%s]", uid)
|
||||
if !found {
|
||||
return fmt.Errorf("unable to find/stop service [%s]", uid)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -42,12 +42,14 @@ func (sm *Manager) deleteService(uid string) error {
|
||||
} else {
|
||||
// Flip the found when we match
|
||||
found = true
|
||||
if sm.serviceInstances[x].isDHCP == true {
|
||||
if sm.serviceInstances[x].isDHCP {
|
||||
macvlan, err := netlink.LinkByName(sm.serviceInstances[x].dhcpInterface)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error finding VIP Interface, for deleting DHCP Link : %v", err)
|
||||
return fmt.Errorf("error finding VIP Interface, for deleting DHCP Link : %v", err)
|
||||
}
|
||||
if err := netlink.LinkDel(macvlan); err != nil {
|
||||
return fmt.Errorf("error deleing link: %v", err)
|
||||
}
|
||||
netlink.LinkDel(macvlan)
|
||||
}
|
||||
if sm.serviceInstances[x].vipConfig.EnableBGP {
|
||||
cidrVip := fmt.Sprintf("%s/%s", sm.serviceInstances[x].vipConfig.VIP, sm.serviceInstances[x].vipConfig.VIPCIDR)
|
||||
@@ -57,8 +59,8 @@ func (sm *Manager) deleteService(uid string) error {
|
||||
}
|
||||
}
|
||||
// If we've been through all services and not found the correct one then error
|
||||
if found == false {
|
||||
return fmt.Errorf("Unable to find/stop service [%s]", uid)
|
||||
if !found {
|
||||
return fmt.Errorf("unable to find/stop service [%s]", uid)
|
||||
}
|
||||
|
||||
// Update the service array
|
||||
@@ -95,7 +97,7 @@ func (sm *Manager) syncServices(service *v1.Service) error {
|
||||
}
|
||||
|
||||
// This instance wasn't found, we need to add it to the manager
|
||||
if foundInstance == false {
|
||||
if !foundInstance {
|
||||
// Create new service
|
||||
var newService Instance
|
||||
newService.UID = newServiceUID
|
||||
|
||||
@@ -12,41 +12,8 @@ import (
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
watchtools "k8s.io/client-go/tools/watch"
|
||||
|
||||
"github.com/kube-vip/kube-vip/pkg/kubevip"
|
||||
)
|
||||
|
||||
func rebuildEndpoints(eps v1.Endpoints) []kubevip.BackEnd {
|
||||
var addresses []string
|
||||
var ports []int32
|
||||
|
||||
for x := range eps.Subsets {
|
||||
// Loop over addresses
|
||||
for y := range eps.Subsets[x].Addresses {
|
||||
addresses = append(addresses, eps.Subsets[x].Addresses[y].IP)
|
||||
}
|
||||
for y := range eps.Subsets[x].Ports {
|
||||
ports = append(ports, eps.Subsets[x].Ports[y].Port)
|
||||
}
|
||||
}
|
||||
var newBackend []kubevip.BackEnd
|
||||
|
||||
// Build endpoints
|
||||
for x := range addresses {
|
||||
for y := range ports {
|
||||
// Print out Backends if debug logging is enabled
|
||||
if log.GetLevel() == log.DebugLevel {
|
||||
fmt.Printf("-> Address: %s:%d \n", addresses[x], ports[y])
|
||||
}
|
||||
newBackend = append(newBackend, kubevip.BackEnd{
|
||||
Address: addresses[x],
|
||||
Port: int(ports[y]),
|
||||
})
|
||||
}
|
||||
}
|
||||
return newBackend
|
||||
}
|
||||
|
||||
// This file handles the watching of a services endpoints and updates a load balancers endpoint configurations accordingly
|
||||
func (sm *Manager) servicesWatcher(ctx context.Context) error {
|
||||
// Watch function
|
||||
|
||||
@@ -92,7 +92,7 @@ func NewConfig(address string, iface string, isDDNS bool) (Network, error) {
|
||||
return result, err
|
||||
}
|
||||
|
||||
//AddIP - Add an IP address to the interface
|
||||
// AddIP - Add an IP address to the interface
|
||||
func (configurator *network) AddIP() error {
|
||||
if err := netlink.AddrReplace(configurator.link, configurator.address); err != nil {
|
||||
return errors.Wrap(err, "could not add ip")
|
||||
@@ -100,7 +100,7 @@ func (configurator *network) AddIP() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
//DeleteIP - Remove an IP address from the interface
|
||||
// DeleteIP - Remove an IP address from the interface
|
||||
func (configurator *network) DeleteIP() error {
|
||||
result, err := configurator.IsSet()
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
// These syscalls are only supported on Linux, so this uses a build directive during compilation. Other OS's will use the arp_unsupported.go and recieve an error
|
||||
// These syscalls are only supported on Linux, so this uses a build directive during compilation. Other OS's will use the arp_unsupported.go and receive an error
|
||||
|
||||
package vip
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// It"s DHCP client implementation that refers to https://www.rfc-editor.org/rfc/rfc2131.html
|
||||
package vip
|
||||
|
||||
// DHCP client implementation that refers to https://www.rfc-editor.org/rfc/rfc2131.html
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
// Callback is a function called on certain events
|
||||
type Callback func(*nclient4.Lease)
|
||||
|
||||
// Client is a DHCP client, responsible for maintaining ipv4 lease for one specified interface
|
||||
// DHCPClient is responsible for maintaining ipv4 lease for one specified interface
|
||||
type DHCPClient struct {
|
||||
iface *net.Interface
|
||||
lease *nclient4.Lease
|
||||
@@ -26,6 +27,7 @@ type DHCPClient struct {
|
||||
onBound Callback
|
||||
}
|
||||
|
||||
// NewDHCPClient returns a new DHCP Client.
|
||||
func NewDHCPClient(iface *net.Interface, initRebootFlag bool, requestedIP string, onBound Callback) *DHCPClient {
|
||||
return &DHCPClient{
|
||||
iface: iface,
|
||||
@@ -163,10 +165,12 @@ func (c *DHCPClient) Start() {
|
||||
|
||||
func (c *DHCPClient) request() (*nclient4.Lease, error) {
|
||||
broadcast, err := nclient4.New(c.iface.Name)
|
||||
defer broadcast.Close()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("create a broadcast client for iface %s failed, error: %w", c.iface.Name, err)
|
||||
}
|
||||
|
||||
defer broadcast.Close()
|
||||
|
||||
return broadcast.Request(context.TODO())
|
||||
}
|
||||
|
||||
|
||||
@@ -40,8 +40,13 @@ func (d *ipUpdater) Run(ctx context.Context) {
|
||||
}
|
||||
|
||||
log.Infof("setting %s as an IP", ip)
|
||||
d.vip.SetIP(ip)
|
||||
d.vip.AddIP()
|
||||
if err := d.vip.SetIP(ip); err != nil {
|
||||
log.Errorf("setting %s as an IP: %v", ip, err)
|
||||
}
|
||||
|
||||
if err := d.vip.AddIP(); err != nil {
|
||||
log.Errorf("error adding virtual IP: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
time.Sleep(3 * time.Second)
|
||||
|
||||
@@ -9,12 +9,14 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
// NdpResponder defines the parameters for the NDP connection.
|
||||
type NdpResponder struct {
|
||||
intf string
|
||||
hardwareAddr net.HardwareAddr
|
||||
conn *ndp.Conn
|
||||
}
|
||||
|
||||
// NewNDPResponder takes an ifaceName and returns a new NDP responder and error if encountered.
|
||||
func NewNDPResponder(ifaceName string) (*NdpResponder, error) {
|
||||
iface, err := net.InterfaceByName(ifaceName)
|
||||
if err != nil {
|
||||
@@ -35,10 +37,12 @@ func NewNDPResponder(ifaceName string) (*NdpResponder, error) {
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
// Close closes the NDP responder connection.
|
||||
func (n *NdpResponder) Close() error {
|
||||
return n.conn.Close()
|
||||
}
|
||||
|
||||
// SendGratuitous broadcasts an NDP update or returns error if encountered.
|
||||
func (n *NdpResponder) SendGratuitous(address string) error {
|
||||
ip := net.ParseIP(address)
|
||||
if ip == nil {
|
||||
|
||||
@@ -227,7 +227,7 @@ func assertControlPlaneIsRoutable(controlPlaneVIP string, transportTimeout, even
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, // nolint
|
||||
}
|
||||
client := &http.Client{Transport: transport, Timeout: transportTimeout}
|
||||
Eventually(func() int {
|
||||
@@ -235,6 +235,7 @@ func assertControlPlaneIsRoutable(controlPlaneVIP string, transportTimeout, even
|
||||
if resp == nil {
|
||||
return -1
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
return resp.StatusCode
|
||||
}, eventuallyTimeout).Should(Equal(http.StatusOK), "Failed to connect to VIP")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user