pkg/mesh,cmd: add WireGuard IP to Nodes
This allows admins or users to have some easy visibility into the configuration of the Kilo cluster.
This commit is contained in:
@@ -49,6 +49,9 @@ const (
|
||||
DefaultCNIPath = "/etc/cni/net.d/10-kilo.conflist"
|
||||
)
|
||||
|
||||
// DefaultKiloSubnet is the default CIDR for Kilo.
|
||||
var DefaultKiloSubnet = &net.IPNet{IP: []byte{10, 4, 0, 0}, Mask: []byte{255, 255, 0, 0}}
|
||||
|
||||
// Granularity represents the abstraction level at which the network
|
||||
// should be meshed.
|
||||
type Granularity string
|
||||
@@ -86,14 +89,16 @@ type Node struct {
|
||||
LastSeen int64
|
||||
// Leader is a suggestion to Kilo that
|
||||
// the node wants to lead its segment.
|
||||
Leader bool
|
||||
Location string
|
||||
Name string
|
||||
Subnet *net.IPNet
|
||||
Leader bool
|
||||
Location string
|
||||
Name string
|
||||
Subnet *net.IPNet
|
||||
WireGuardIP *net.IPNet
|
||||
}
|
||||
|
||||
// Ready indicates whether or not the node is ready.
|
||||
func (n *Node) Ready() bool {
|
||||
// Nodes that are not leaders will not have WireGuardIPs, so it is not required.
|
||||
return n != nil && n.ExternalIP != nil && n.Key != nil && n.InternalIP != nil && n.Subnet != nil && time.Now().Unix()-n.LastSeen < int64(resyncPeriod)*2/int64(time.Second)
|
||||
}
|
||||
|
||||
@@ -194,6 +199,7 @@ type Mesh struct {
|
||||
subnet *net.IPNet
|
||||
table *route.Table
|
||||
tunlIface int
|
||||
wireGuardIP *net.IPNet
|
||||
|
||||
// nodes and peers are mutable fields in the struct
|
||||
// and needs to be guarded.
|
||||
@@ -514,14 +520,15 @@ func (m *Mesh) handleLocal(n *Node) {
|
||||
// Take leader, location, and subnet from the argument, as these
|
||||
// are not determined by kilo.
|
||||
local := &Node{
|
||||
ExternalIP: n.ExternalIP,
|
||||
Key: m.pub,
|
||||
InternalIP: m.internalIP,
|
||||
LastSeen: time.Now().Unix(),
|
||||
Leader: n.Leader,
|
||||
Location: n.Location,
|
||||
Name: m.hostname,
|
||||
Subnet: n.Subnet,
|
||||
ExternalIP: n.ExternalIP,
|
||||
Key: m.pub,
|
||||
InternalIP: m.internalIP,
|
||||
LastSeen: time.Now().Unix(),
|
||||
Leader: n.Leader,
|
||||
Location: n.Location,
|
||||
Name: m.hostname,
|
||||
Subnet: n.Subnet,
|
||||
WireGuardIP: m.wireGuardIP,
|
||||
}
|
||||
if !nodesAreEqual(n, local) {
|
||||
level.Debug(m.logger).Log("msg", "local node differs from backend")
|
||||
@@ -583,6 +590,8 @@ func (m *Mesh) applyTopology() {
|
||||
m.errorCounter.WithLabelValues("apply").Inc()
|
||||
return
|
||||
}
|
||||
// Update the node's WireGuard IP.
|
||||
m.wireGuardIP = t.wireGuardCIDR
|
||||
conf := t.Conf()
|
||||
buf, err := conf.Bytes()
|
||||
if err != nil {
|
||||
@@ -740,7 +749,7 @@ func nodesAreEqual(a, b *Node) bool {
|
||||
// Ignore LastSeen when comparing equality we want to check if the nodes are
|
||||
// equivalent. However, we do want to check if LastSeen has transitioned
|
||||
// between valid and invalid.
|
||||
return ipNetsEqual(a.ExternalIP, b.ExternalIP) && string(a.Key) == string(b.Key) && ipNetsEqual(a.InternalIP, b.InternalIP) && a.Leader == b.Leader && a.Location == b.Location && a.Name == b.Name && subnetsEqual(a.Subnet, b.Subnet) && a.Ready() == b.Ready()
|
||||
return ipNetsEqual(a.ExternalIP, b.ExternalIP) && string(a.Key) == string(b.Key) && ipNetsEqual(a.WireGuardIP, b.WireGuardIP) && ipNetsEqual(a.InternalIP, b.InternalIP) && a.Leader == b.Leader && a.Location == b.Location && a.Name == b.Name && subnetsEqual(a.Subnet, b.Subnet) && a.Ready() == b.Ready()
|
||||
}
|
||||
|
||||
func peersAreEqual(a, b *Peer) bool {
|
||||
|
@@ -29,9 +29,8 @@ func allowedIPs(ips ...string) string {
|
||||
return strings.Join(ips, ", ")
|
||||
}
|
||||
|
||||
func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32, *net.IPNet) {
|
||||
func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32) {
|
||||
key := []byte("private")
|
||||
kiloNet := &net.IPNet{IP: net.ParseIP("10.4.0.0").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e1 := &net.IPNet{IP: net.ParseIP("10.1.0.1").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e2 := &net.IPNet{IP: net.ParseIP("10.1.0.2").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
e3 := &net.IPNet{IP: net.ParseIP("10.1.0.3").To4(), Mask: net.CIDRMask(16, 32)}
|
||||
@@ -89,11 +88,11 @@ func setup(t *testing.T) (map[string]*Node, map[string]*Peer, []byte, uint32, *n
|
||||
},
|
||||
},
|
||||
}
|
||||
return nodes, peers, key, DefaultKiloPort, kiloNet
|
||||
return nodes, peers, key, DefaultKiloPort
|
||||
}
|
||||
|
||||
func TestNewTopology(t *testing.T) {
|
||||
nodes, peers, key, port, kiloNet := setup(t)
|
||||
nodes, peers, key, port := setup(t)
|
||||
|
||||
w1 := net.ParseIP("10.4.0.1").To4()
|
||||
w2 := net.ParseIP("10.4.0.2").To4()
|
||||
@@ -112,7 +111,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["a"].Name,
|
||||
leader: true,
|
||||
location: nodes["a"].Location,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["a"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
@@ -148,7 +147,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["b"].Name,
|
||||
leader: true,
|
||||
location: nodes["b"].Location,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["b"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
@@ -184,7 +183,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["c"].Name,
|
||||
leader: false,
|
||||
location: nodes["b"].Location,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["c"].InternalIP,
|
||||
wireGuardCIDR: nil,
|
||||
segments: []*segment{
|
||||
@@ -220,7 +219,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["a"].Name,
|
||||
leader: true,
|
||||
location: nodes["a"].Name,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["a"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
@@ -266,7 +265,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["b"].Name,
|
||||
leader: true,
|
||||
location: nodes["b"].Name,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["b"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
@@ -312,7 +311,7 @@ func TestNewTopology(t *testing.T) {
|
||||
hostname: nodes["c"].Name,
|
||||
leader: true,
|
||||
location: nodes["c"].Name,
|
||||
subnet: kiloNet,
|
||||
subnet: DefaultKiloSubnet,
|
||||
privateIP: nodes["c"].InternalIP,
|
||||
wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
|
||||
segments: []*segment{
|
||||
@@ -353,7 +352,7 @@ func TestNewTopology(t *testing.T) {
|
||||
} {
|
||||
tc.result.key = key
|
||||
tc.result.port = port
|
||||
topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, kiloNet)
|
||||
topo, err := NewTopology(nodes, peers, tc.granularity, tc.hostname, port, key, DefaultKiloSubnet)
|
||||
if err != nil {
|
||||
t.Errorf("test case %q: failed to generate Topology: %v", tc.name, err)
|
||||
}
|
||||
@@ -372,12 +371,12 @@ func mustTopo(t *testing.T, nodes map[string]*Node, peers map[string]*Peer, gran
|
||||
}
|
||||
|
||||
func TestRoutes(t *testing.T) {
|
||||
nodes, peers, key, port, kiloNet := setup(t)
|
||||
nodes, peers, key, port := setup(t)
|
||||
kiloIface := 0
|
||||
privIface := 1
|
||||
pubIface := 2
|
||||
mustTopoForGranularityAndHost := func(granularity Granularity, hostname string) *Topology {
|
||||
return mustTopo(t, nodes, peers, granularity, hostname, port, key, kiloNet)
|
||||
return mustTopo(t, nodes, peers, granularity, hostname, port, key, DefaultKiloSubnet)
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
@@ -987,7 +986,7 @@ func TestRoutes(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestConf(t *testing.T) {
|
||||
nodes, peers, key, port, kiloNet := setup(t)
|
||||
nodes, peers, key, port := setup(t)
|
||||
for _, tc := range []struct {
|
||||
name string
|
||||
topology *Topology
|
||||
@@ -995,7 +994,7 @@ func TestConf(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "logical from a",
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
@@ -1019,7 +1018,7 @@ AllowedIPs = 10.5.0.3/24
|
||||
},
|
||||
{
|
||||
name: "logical from b",
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["b"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
@@ -1043,7 +1042,7 @@ AllowedIPs = 10.5.0.3/24
|
||||
},
|
||||
{
|
||||
name: "logical from c",
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["c"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, LogicalGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
@@ -1067,7 +1066,7 @@ AllowedIPs = 10.5.0.3/24
|
||||
},
|
||||
{
|
||||
name: "full from a",
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["a"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["a"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
@@ -1096,7 +1095,7 @@ AllowedIPs = 10.5.0.3/24
|
||||
},
|
||||
{
|
||||
name: "full from b",
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["b"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["b"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
@@ -1125,7 +1124,7 @@ AllowedIPs = 10.5.0.3/24
|
||||
},
|
||||
{
|
||||
name: "full from c",
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["c"].Name, port, key, kiloNet),
|
||||
topology: mustTopo(t, nodes, peers, FullGranularity, nodes["c"].Name, port, key, DefaultKiloSubnet),
|
||||
result: `[Interface]
|
||||
PrivateKey = private
|
||||
ListenPort = 51820
|
||||
|
Reference in New Issue
Block a user