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:
Steve Sloka
2021-10-19 11:15:09 -04:00
parent 70f14a5bfd
commit 2e9c2244c1
38 changed files with 192 additions and 276 deletions

13
.golangci.yml Normal file
View File

@@ -0,0 +1,13 @@
run:
timeout: 10m
linters:
enable:
- bodyclose
- gofmt
- goimports
- revive
- gosec
- misspell
- unconvert
- unparam

View File

@@ -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

View File

@@ -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)
}

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -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")

View File

@@ -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

View File

@@ -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,
})

View File

@@ -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
}
},
},
})

View File

@@ -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 {

View File

@@ -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:

View File

@@ -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"
)

View File

@@ -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 {

View File

@@ -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 {

View File

@@ -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

View File

@@ -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

View File

@@ -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{}
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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)
}
}

View File

@@ -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 != "" {

View File

@@ -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}
}

View File

@@ -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

View File

@@ -58,7 +58,7 @@ func (sm *Manager) servicesWatcher(ctx context.Context) error {
if !ok {
return fmt.Errorf("Unable to parse Kubernetes services from API watcher")
}
if svc.Spec.LoadBalancerIP == "" {
log.Infof("Service [%s] has been addded/modified, it has no assigned external addresses", svc.Name)
} else {
@@ -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 {

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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")

View File

@@ -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

View File

@@ -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

View File

@@ -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 {

View File

@@ -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

View File

@@ -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())
}

View File

@@ -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)

View File

@@ -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 {

View File

@@ -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")
}