High Availability daemon to share an IP around N servers.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zoreide/interface.go

128 lines
2.6 KiB

package main
import (
"fmt"
"log"
"math/rand"
"net"
"strconv"
"time"
"github.com/go-ping/ping"
"github.com/milosgajdos/tenus"
)
type AbstractBridge struct {
ExistingInterface string
BridgeIpCIDR string
IsActive bool
IsAlpha bool
hIerarchyNumber int64
}
var ZoreideBridge AbstractBridge
func init() {
ZoreideBridge.initializeHierarchy()
}
func (b *AbstractBridge) initializeHierarchy() {
rand.Seed(time.Now().UnixNano())
var letterRunes = []rune("123456789")
num := make([]rune, numberlenght)
for i := range num {
num[i] = letterRunes[rand.Intn(len(letterRunes))]
}
zz, err := strconv.ParseInt(string(num), 10, 64)
if err != nil {
log.Println("Error generating number: ", err.Error())
b.hIerarchyNumber = 0
return
} else {
b.hIerarchyNumber = zz
log.Println("Success generating number: ", b.hIerarchyNumber)
}
}
func (b *AbstractBridge) configureIpAndBridgeUp() {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <configureIpAndBridgeUp()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
// first we check the IP is free. Something weird could have happened in some
// other server
brIp, brIpNet, err := net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println(err.Error())
}
if doesIpExists(brIp.String()) {
log.Println("Cannot take this IP, it exists already: " + brIp.String())
return
}
br, err := tenus.NewLinkFrom(b.ExistingInterface)
if err != nil {
log.Println(err.Error())
}
if err := br.SetLinkIp(brIp, brIpNet); err != nil {
log.Println(err.Error())
}
}
func (b *AbstractBridge) removeIPandBridgeInt() {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <removeIPandBridgeInt()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
br, err := tenus.NewLinkFrom(b.ExistingInterface)
if err != nil {
log.Println(err.Error())
}
brIp, brIpNet, err := net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println(err.Error())
}
if err := br.UnsetLinkIp(brIp, brIpNet); err != nil {
log.Println(err.Error())
}
}
func doesIpExists(bridgeip string) bool {
pinger, err := ping.NewPinger(bridgeip)
if err != nil {
log.Println("Ping error: " + err.Error())
}
// just in case it doesn't stops alone
defer pinger.Stop()
pinger.Count = 3
pinger.Interval = time.Duration(10 * time.Millisecond)
pinger.Timeout = time.Duration(1 * time.Second)
pinger.Run() // blocks until finished
stats := pinger.Statistics()
return stats.PacketsRecv > 0
}