open-consul/consul/util.go

142 lines
2.9 KiB
Go
Raw Normal View History

2013-12-12 19:07:14 +00:00
package consul
2013-12-19 22:18:55 +00:00
import (
2014-01-08 00:58:16 +00:00
"encoding/binary"
2013-12-31 23:44:17 +00:00
"fmt"
2013-12-19 22:37:54 +00:00
"github.com/hashicorp/serf/serf"
2013-12-31 23:44:17 +00:00
"net"
2013-12-19 22:18:55 +00:00
"os"
"path/filepath"
2013-12-19 22:37:54 +00:00
"strconv"
2013-12-19 22:18:55 +00:00
)
2013-12-31 23:44:17 +00:00
/*
* Contains an entry for each private block:
* 10.0.0.0/8
* 172.16.0.0/12
* 192.168/16
*/
var privateBlocks []*net.IPNet
2014-01-20 23:39:07 +00:00
// serverparts is used to return the parts of a server role
type serverParts struct {
Datacenter string
Port int
2014-01-30 21:13:29 +00:00
Bootstrap bool
}
2013-12-31 23:44:17 +00:00
func init() {
// Add each private block
privateBlocks = make([]*net.IPNet, 3)
_, block, err := net.ParseCIDR("10.0.0.0/8")
if err != nil {
panic(fmt.Sprintf("Bad cidr. Got %v", err))
}
privateBlocks[0] = block
_, block, err = net.ParseCIDR("172.16.0.0/12")
if err != nil {
panic(fmt.Sprintf("Bad cidr. Got %v", err))
}
privateBlocks[1] = block
_, block, err = net.ParseCIDR("192.168.0.0/16")
if err != nil {
panic(fmt.Sprintf("Bad cidr. Got %v", err))
}
privateBlocks[2] = block
}
2013-12-12 19:07:14 +00:00
// strContains checks if a list contains a string
func strContains(l []string, s string) bool {
for _, v := range l {
if v == s {
return true
}
}
return false
}
2013-12-19 22:18:55 +00:00
// ensurePath is used to make sure a path exists
func ensurePath(path string, dir bool) error {
if !dir {
path = filepath.Dir(path)
}
return os.MkdirAll(path, 0755)
}
2013-12-19 22:37:54 +00:00
// Returns if a member is a consul server. Returns a bool,
// the data center, and the rpc port
2014-01-20 23:39:07 +00:00
func isConsulServer(m serf.Member) (bool, *serverParts) {
2014-01-30 21:13:29 +00:00
if m.Tags["role"] != "consul" {
2014-01-20 23:39:07 +00:00
return false, nil
2013-12-19 22:37:54 +00:00
}
2014-01-30 21:13:29 +00:00
datacenter := m.Tags["dc"]
port_str := m.Tags["port"]
_, bootstrap := m.Tags["bootstrap"]
2013-12-19 22:37:54 +00:00
port, err := strconv.Atoi(port_str)
if err != nil {
2014-01-20 23:39:07 +00:00
return false, nil
2013-12-19 22:37:54 +00:00
}
2014-01-30 21:13:29 +00:00
return true, &serverParts{datacenter, port, bootstrap}
2013-12-19 22:37:54 +00:00
}
2013-12-31 23:44:17 +00:00
// Returns if a member is a consul node. Returns a boo,
// and the data center.
func isConsulNode(m serf.Member) (bool, string) {
2014-01-30 21:13:29 +00:00
if m.Tags["role"] != "node" {
return false, ""
}
2014-01-30 21:13:29 +00:00
return true, m.Tags["dc"]
}
2013-12-31 23:44:17 +00:00
// Returns if the given IP is in a private block
func isPrivateIP(ip_str string) bool {
ip := net.ParseIP(ip_str)
for _, priv := range privateBlocks {
if priv.Contains(ip) {
return true
}
}
return false
}
// GetPrivateIP is used to return the first private IP address
// associated with an interface on the machine
func GetPrivateIP() (*net.IPNet, error) {
addresses, err := net.InterfaceAddrs()
if err != nil {
return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
}
// Find private IPv4 address
for _, addr := range addresses {
ip, ok := addr.(*net.IPNet)
if !ok {
continue
}
if ip.IP.To4() == nil {
continue
}
if !isPrivateIP(ip.IP.String()) {
continue
}
return ip, nil
}
return nil, fmt.Errorf("No private IP address found")
}
2014-01-08 00:58:16 +00:00
// Converts bytes to an integer
func bytesToUint64(b []byte) uint64 {
return binary.BigEndian.Uint64(b)
}
// Converts a uint to a byte slice
func uint64ToBytes(u uint64) []byte {
buf := make([]byte, 8)
binary.BigEndian.PutUint64(buf, u)
return buf
}