Merge 9bba9d4b86
into b187f32407
This commit is contained in:
commit
3dfd3af5dc
@ -69,6 +69,7 @@ var (
|
|||||||
availableGranularities = strings.Join([]string{
|
availableGranularities = strings.Join([]string{
|
||||||
string(mesh.LogicalGranularity),
|
string(mesh.LogicalGranularity),
|
||||||
string(mesh.FullGranularity),
|
string(mesh.FullGranularity),
|
||||||
|
string(mesh.CrossGranularity),
|
||||||
}, ", ")
|
}, ", ")
|
||||||
availableLogLevels = strings.Join([]string{
|
availableLogLevels = strings.Join([]string{
|
||||||
logLevelAll,
|
logLevelAll,
|
||||||
@ -223,6 +224,7 @@ func runRoot(_ *cobra.Command, _ []string) error {
|
|||||||
switch gr {
|
switch gr {
|
||||||
case mesh.LogicalGranularity:
|
case mesh.LogicalGranularity:
|
||||||
case mesh.FullGranularity:
|
case mesh.FullGranularity:
|
||||||
|
case mesh.CrossGranularity:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("mesh granularity %v unknown; possible values are: %s", granularity, availableGranularities)
|
return fmt.Errorf("mesh granularity %v unknown; possible values are: %s", granularity, availableGranularities)
|
||||||
}
|
}
|
||||||
|
@ -49,6 +49,7 @@ var (
|
|||||||
availableGranularities = strings.Join([]string{
|
availableGranularities = strings.Join([]string{
|
||||||
string(mesh.LogicalGranularity),
|
string(mesh.LogicalGranularity),
|
||||||
string(mesh.FullGranularity),
|
string(mesh.FullGranularity),
|
||||||
|
string(mesh.CrossGranularity),
|
||||||
string(mesh.AutoGranularity),
|
string(mesh.AutoGranularity),
|
||||||
}, ", ")
|
}, ", ")
|
||||||
availableLogLevels = strings.Join([]string{
|
availableLogLevels = strings.Join([]string{
|
||||||
@ -80,6 +81,7 @@ func runRoot(c *cobra.Command, _ []string) error {
|
|||||||
switch opts.granularity {
|
switch opts.granularity {
|
||||||
case mesh.LogicalGranularity:
|
case mesh.LogicalGranularity:
|
||||||
case mesh.FullGranularity:
|
case mesh.FullGranularity:
|
||||||
|
case mesh.CrossGranularity:
|
||||||
case mesh.AutoGranularity:
|
case mesh.AutoGranularity:
|
||||||
default:
|
default:
|
||||||
return fmt.Errorf("mesh granularity %s unknown; posible values are: %s", granularity, availableGranularities)
|
return fmt.Errorf("mesh granularity %s unknown; posible values are: %s", granularity, availableGranularities)
|
||||||
@ -151,8 +153,9 @@ func determineGranularity(gr mesh.Granularity, ns []*mesh.Node) (mesh.Granularit
|
|||||||
switch ret {
|
switch ret {
|
||||||
case mesh.LogicalGranularity:
|
case mesh.LogicalGranularity:
|
||||||
case mesh.FullGranularity:
|
case mesh.FullGranularity:
|
||||||
|
case mesh.CrossGranularity:
|
||||||
default:
|
default:
|
||||||
return ret, fmt.Errorf("mesh granularity %s is not supported", opts.granularity)
|
return ret, fmt.Errorf("mesh granularity %s is not supported", ret)
|
||||||
}
|
}
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
@ -48,7 +48,7 @@ Flags:
|
|||||||
--local Should Kilo manage routes within a location? (default true)
|
--local Should Kilo manage routes within a location? (default true)
|
||||||
--log-level string Log level to use. Possible values: all, debug, info, warn, error, none (default "info")
|
--log-level string Log level to use. Possible values: all, debug, info, warn, error, none (default "info")
|
||||||
--master string The address of the Kubernetes API server (overrides any value in kubeconfig).
|
--master string The address of the Kubernetes API server (overrides any value in kubeconfig).
|
||||||
--mesh-granularity string The granularity of the network mesh to create. Possible values: location, full (default "location")
|
--mesh-granularity string The granularity of the network mesh to create. Possible values: location, full, cross (default "location")
|
||||||
--mtu uint The MTU of the WireGuard interface created by Kilo. (default 1420)
|
--mtu uint The MTU of the WireGuard interface created by Kilo. (default 1420)
|
||||||
--port int The port over which WireGuard peers should communicate. (default 51820)
|
--port int The port over which WireGuard peers should communicate. (default 51820)
|
||||||
--prioritise-private-addresses Prefer to assign a private IP address to the node's endpoint.
|
--prioritise-private-addresses Prefer to assign a private IP address to the node's endpoint.
|
||||||
|
@ -47,6 +47,11 @@ kgctl graph | circo -Tsvg > cluster.svg
|
|||||||
|
|
||||||
<img src="./graphs/full-mesh.svg" />
|
<img src="./graphs/full-mesh.svg" />
|
||||||
|
|
||||||
|
# Cross Mesh
|
||||||
|
|
||||||
|
In this topology all nodes within the same location are not encrypted. Traffic to any other node outside of current location is encrypted
|
||||||
|
with direct node-to-node encryption. To use this mesh specify `--mesh-granularity=cross`.
|
||||||
|
|
||||||
## Mixed
|
## Mixed
|
||||||
|
|
||||||
The `kilo.squat.ai/location` annotation can be used to create cluster mixing some fully meshed nodes and some nodes grouped by logical location.
|
The `kilo.squat.ai/location` annotation can be used to create cluster mixing some fully meshed nodes and some nodes grouped by logical location.
|
||||||
|
@ -334,6 +334,7 @@ func translateNode(node *v1.Node, topologyLabel string) *mesh.Node {
|
|||||||
switch meshGranularity {
|
switch meshGranularity {
|
||||||
case mesh.LogicalGranularity:
|
case mesh.LogicalGranularity:
|
||||||
case mesh.FullGranularity:
|
case mesh.FullGranularity:
|
||||||
|
case mesh.CrossGranularity:
|
||||||
default:
|
default:
|
||||||
meshGranularity = ""
|
meshGranularity = ""
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,9 @@ const (
|
|||||||
// FullGranularity indicates that the network should create
|
// FullGranularity indicates that the network should create
|
||||||
// a mesh between every node.
|
// a mesh between every node.
|
||||||
FullGranularity Granularity = "full"
|
FullGranularity Granularity = "full"
|
||||||
|
// CrossGranularity indicates that network is encrypted only
|
||||||
|
// between nodes in different locations.
|
||||||
|
CrossGranularity Granularity = "cross"
|
||||||
// AutoGranularity can be used with kgctl to obtain
|
// AutoGranularity can be used with kgctl to obtain
|
||||||
// the granularity automatically.
|
// the granularity automatically.
|
||||||
AutoGranularity Granularity = "auto"
|
AutoGranularity Granularity = "auto"
|
||||||
|
@ -49,17 +49,24 @@ func (t *Topology) Dot() (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, s := range t.segments {
|
for i, s := range t.segments {
|
||||||
if err := g.AddSubGraph("kilo", subGraphName(s.location), nil); err != nil {
|
location := s.location
|
||||||
|
plainConnection := false
|
||||||
|
if s.nodeLocation != "" {
|
||||||
|
location = s.nodeLocation
|
||||||
|
plainConnection = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := g.AddSubGraph("kilo", subGraphName(location), nil); err != nil {
|
||||||
return "", fmt.Errorf("failed to add subgraph")
|
return "", fmt.Errorf("failed to add subgraph")
|
||||||
}
|
}
|
||||||
if err := g.AddAttr(subGraphName(s.location), string(gographviz.Label), graphEscape(s.location)); err != nil {
|
if err := g.AddAttr(subGraphName(location), string(gographviz.Label), graphEscape(location)); err != nil {
|
||||||
return "", fmt.Errorf("failed to add label to subgraph")
|
return "", fmt.Errorf("failed to add label to subgraph")
|
||||||
}
|
}
|
||||||
if err := g.AddAttr(subGraphName(s.location), string(gographviz.Style), `"dashed,rounded"`); err != nil {
|
if err := g.AddAttr(subGraphName(location), string(gographviz.Style), `"dashed,rounded"`); err != nil {
|
||||||
return "", fmt.Errorf("failed to add style to subgraph")
|
return "", fmt.Errorf("failed to add style to subgraph")
|
||||||
}
|
}
|
||||||
for j := range s.cidrs {
|
for j := range s.cidrs {
|
||||||
if err := g.AddNode(subGraphName(s.location), graphEscape(s.hostnames[j]), nodeAttrs); err != nil {
|
if err := g.AddNode(subGraphName(location), graphEscape(s.hostnames[j]), nodeAttrs); err != nil {
|
||||||
return "", fmt.Errorf("failed to add node to subgraph")
|
return "", fmt.Errorf("failed to add node to subgraph")
|
||||||
}
|
}
|
||||||
var wg net.IP
|
var wg net.IP
|
||||||
@ -75,11 +82,11 @@ func (t *Topology) Dot() (string, error) {
|
|||||||
if s.privateIPs != nil {
|
if s.privateIPs != nil {
|
||||||
priv = s.privateIPs[j]
|
priv = s.privateIPs[j]
|
||||||
}
|
}
|
||||||
if err := g.Nodes.Lookup[graphEscape(s.hostnames[j])].Attrs.Add(string(gographviz.Label), nodeLabel(s.location, s.hostnames[j], s.cidrs[j], priv, wg, endpoint)); err != nil {
|
if err := g.Nodes.Lookup[graphEscape(s.hostnames[j])].Attrs.Add(string(gographviz.Label), nodeLabel(location, s.hostnames[j], s.cidrs[j], priv, wg, endpoint)); err != nil {
|
||||||
return "", fmt.Errorf("failed to add label to node")
|
return "", fmt.Errorf("failed to add label to node")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
meshSubGraph(g, g.Relations.SortedChildren(subGraphName(s.location)), s.leader, nil)
|
meshSubGraph(g, g.Relations.SortedChildren(subGraphName(location)), s.leader, plainConnection, nil)
|
||||||
leaders[i] = graphEscape(s.hostnames[s.leader])
|
leaders[i] = graphEscape(s.hostnames[s.leader])
|
||||||
}
|
}
|
||||||
meshGraph(g, leaders, nil)
|
meshGraph(g, leaders, nil)
|
||||||
@ -116,15 +123,26 @@ func meshGraph(g *gographviz.Graph, nodes []string, attrs gographviz.Attrs) {
|
|||||||
if i == j {
|
if i == j {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
dsts := g.Edges.SrcToDsts[nodes[i]]
|
||||||
|
if dsts != nil && len(dsts[nodes[j]]) != 0 {
|
||||||
|
// nodes already connected via plain connection
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
g.Edges.Add(&gographviz.Edge{Src: nodes[i], Dst: nodes[j], Dir: true, Attrs: attrs})
|
g.Edges.Add(&gographviz.Edge{Src: nodes[i], Dst: nodes[j], Dir: true, Attrs: attrs})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func meshSubGraph(g *gographviz.Graph, nodes []string, leader int, attrs gographviz.Attrs) {
|
func meshSubGraph(g *gographviz.Graph, nodes []string, leader int, plainConnection bool, attrs gographviz.Attrs) {
|
||||||
if attrs == nil {
|
if attrs == nil {
|
||||||
attrs = make(gographviz.Attrs)
|
attrs = make(gographviz.Attrs)
|
||||||
attrs[gographviz.Dir] = "both"
|
attrs[gographviz.Dir] = "both"
|
||||||
|
if plainConnection {
|
||||||
|
attrs[gographviz.Style] = "dotted"
|
||||||
|
attrs[gographviz.ArrowHead] = "none"
|
||||||
|
attrs[gographviz.ArrowTail] = "none"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for i := range nodes {
|
for i := range nodes {
|
||||||
if i == leader {
|
if i == leader {
|
||||||
|
@ -137,7 +137,7 @@ func (t *Topology) Routes(kiloIfaceName string, kiloIface, privIface, tunlIface
|
|||||||
}
|
}
|
||||||
for _, segment := range t.segments {
|
for _, segment := range t.segments {
|
||||||
// Add routes for the current segment if local is true.
|
// Add routes for the current segment if local is true.
|
||||||
if segment.location == t.location {
|
if (segment.location == t.location) || (t.nodeLocation != "" && segment.nodeLocation == t.nodeLocation) {
|
||||||
// If the local node does not have a private IP address,
|
// If the local node does not have a private IP address,
|
||||||
// then skip adding routes, because the node is in its own location.
|
// then skip adding routes, because the node is in its own location.
|
||||||
if local && t.privateIP != nil {
|
if local && t.privateIP != nil {
|
||||||
|
@ -37,8 +37,10 @@ type Topology struct {
|
|||||||
// key is the private key of the node creating the topology.
|
// key is the private key of the node creating the topology.
|
||||||
key wgtypes.Key
|
key wgtypes.Key
|
||||||
port int
|
port int
|
||||||
// Location is the logical location of the local host.
|
// location is the logical location of the local host.
|
||||||
location string
|
location string
|
||||||
|
// nodeLocation is the location annotation of the node. This is set only in cross location topology.
|
||||||
|
nodeLocation string
|
||||||
segments []*segment
|
segments []*segment
|
||||||
peers []*Peer
|
peers []*Peer
|
||||||
|
|
||||||
@ -71,8 +73,10 @@ type segment struct {
|
|||||||
endpoint *wireguard.Endpoint
|
endpoint *wireguard.Endpoint
|
||||||
key wgtypes.Key
|
key wgtypes.Key
|
||||||
persistentKeepalive time.Duration
|
persistentKeepalive time.Duration
|
||||||
// Location is the logical location of this segment.
|
// location is the logical location of this segment.
|
||||||
location string
|
location string
|
||||||
|
// nodeLocation is the node location annotation. This is set only for cross location topology.
|
||||||
|
nodeLocation string
|
||||||
|
|
||||||
// cidrs is a slice of subnets of all peers in the segment.
|
// cidrs is a slice of subnets of all peers in the segment.
|
||||||
cidrs []*net.IPNet
|
cidrs []*net.IPNet
|
||||||
@ -91,14 +95,34 @@ type segment struct {
|
|||||||
allowedLocationIPs []net.IPNet
|
allowedLocationIPs []net.IPNet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// topoKey is used to group nodes into locations.
|
||||||
|
type topoKey struct {
|
||||||
|
location string
|
||||||
|
nodeLocation string
|
||||||
|
}
|
||||||
|
|
||||||
// NewTopology creates a new Topology struct from a given set of nodes and peers.
|
// NewTopology creates a new Topology struct from a given set of nodes and peers.
|
||||||
func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Granularity, hostname string, port int, key wgtypes.Key, subnet *net.IPNet, persistentKeepalive time.Duration, logger log.Logger) (*Topology, error) {
|
func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Granularity, hostname string, port int, key wgtypes.Key, subnet *net.IPNet, persistentKeepalive time.Duration, logger log.Logger) (*Topology, error) {
|
||||||
if logger == nil {
|
if logger == nil {
|
||||||
logger = log.NewNopLogger()
|
logger = log.NewNopLogger()
|
||||||
}
|
}
|
||||||
topoMap := make(map[string][]*Node)
|
topoMap := make(map[topoKey][]*Node)
|
||||||
|
var localLocation, localNodeLocation string
|
||||||
|
switch granularity {
|
||||||
|
case LogicalGranularity:
|
||||||
|
localLocation = logicalLocationPrefix + nodes[hostname].Location
|
||||||
|
if nodes[hostname].InternalIP == nil {
|
||||||
|
localLocation = nodeLocationPrefix + hostname
|
||||||
|
}
|
||||||
|
case FullGranularity:
|
||||||
|
localLocation = nodeLocationPrefix + hostname
|
||||||
|
case CrossGranularity:
|
||||||
|
localLocation = nodeLocationPrefix + hostname
|
||||||
|
localNodeLocation = logicalLocationPrefix + nodes[hostname].Location
|
||||||
|
}
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
var location string
|
var location, nodeLocation string
|
||||||
switch granularity {
|
switch granularity {
|
||||||
case LogicalGranularity:
|
case LogicalGranularity:
|
||||||
location = logicalLocationPrefix + node.Location
|
location = logicalLocationPrefix + node.Location
|
||||||
@ -109,18 +133,12 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
|||||||
}
|
}
|
||||||
case FullGranularity:
|
case FullGranularity:
|
||||||
location = nodeLocationPrefix + node.Name
|
location = nodeLocationPrefix + node.Name
|
||||||
|
case CrossGranularity:
|
||||||
|
location = nodeLocationPrefix + node.Name
|
||||||
|
nodeLocation = logicalLocationPrefix + node.Location
|
||||||
}
|
}
|
||||||
topoMap[location] = append(topoMap[location], node)
|
key := topoKey{location: location, nodeLocation: nodeLocation}
|
||||||
}
|
topoMap[key] = append(topoMap[key], node)
|
||||||
var localLocation string
|
|
||||||
switch granularity {
|
|
||||||
case LogicalGranularity:
|
|
||||||
localLocation = logicalLocationPrefix + nodes[hostname].Location
|
|
||||||
if nodes[hostname].InternalIP == nil {
|
|
||||||
localLocation = nodeLocationPrefix + hostname
|
|
||||||
}
|
|
||||||
case FullGranularity:
|
|
||||||
localLocation = nodeLocationPrefix + hostname
|
|
||||||
}
|
}
|
||||||
|
|
||||||
t := Topology{
|
t := Topology{
|
||||||
@ -128,6 +146,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
|||||||
port: port,
|
port: port,
|
||||||
hostname: hostname,
|
hostname: hostname,
|
||||||
location: localLocation,
|
location: localLocation,
|
||||||
|
nodeLocation: localNodeLocation,
|
||||||
persistentKeepalive: persistentKeepalive,
|
persistentKeepalive: persistentKeepalive,
|
||||||
privateIP: nodes[hostname].InternalIP,
|
privateIP: nodes[hostname].InternalIP,
|
||||||
subnet: nodes[hostname].Subnet,
|
subnet: nodes[hostname].Subnet,
|
||||||
@ -141,7 +160,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
|||||||
return topoMap[location][i].Name < topoMap[location][j].Name
|
return topoMap[location][i].Name < topoMap[location][j].Name
|
||||||
})
|
})
|
||||||
leader := findLeader(topoMap[location])
|
leader := findLeader(topoMap[location])
|
||||||
if location == localLocation && topoMap[location][leader].Name == hostname {
|
if location.nodeLocation != "" || (location.location == localLocation && topoMap[location][leader].Name == hostname) {
|
||||||
t.leader = true
|
t.leader = true
|
||||||
}
|
}
|
||||||
var allowedIPs []net.IPNet
|
var allowedIPs []net.IPNet
|
||||||
@ -181,7 +200,8 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
|||||||
endpoint: topoMap[location][leader].Endpoint,
|
endpoint: topoMap[location][leader].Endpoint,
|
||||||
key: topoMap[location][leader].Key,
|
key: topoMap[location][leader].Key,
|
||||||
persistentKeepalive: topoMap[location][leader].PersistentKeepalive,
|
persistentKeepalive: topoMap[location][leader].PersistentKeepalive,
|
||||||
location: location,
|
location: location.location,
|
||||||
|
nodeLocation: location.nodeLocation,
|
||||||
cidrs: cidrs,
|
cidrs: cidrs,
|
||||||
hostnames: hostnames,
|
hostnames: hostnames,
|
||||||
leader: leader,
|
leader: leader,
|
||||||
@ -225,7 +245,7 @@ func NewTopology(nodes map[string]*Node, peers map[string]*Peer, granularity Gra
|
|||||||
|
|
||||||
// Now that the topology is ordered, update the discoveredEndpoints map
|
// Now that the topology is ordered, update the discoveredEndpoints map
|
||||||
// add new ones by going through the ordered topology: segments, nodes
|
// add new ones by going through the ordered topology: segments, nodes
|
||||||
for _, node := range topoMap[segment.location] {
|
for _, node := range topoMap[topoKey{location: segment.location, nodeLocation: segment.nodeLocation}] {
|
||||||
for key := range node.DiscoveredEndpoints {
|
for key := range node.DiscoveredEndpoints {
|
||||||
if _, ok := t.discoveredEndpoints[key]; !ok {
|
if _, ok := t.discoveredEndpoints[key]; !ok {
|
||||||
t.discoveredEndpoints[key] = node.DiscoveredEndpoints[key]
|
t.discoveredEndpoints[key] = node.DiscoveredEndpoints[key]
|
||||||
@ -308,7 +328,7 @@ func (t *Topology) Conf() *wireguard.Conf {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, s := range t.segments {
|
for _, s := range t.segments {
|
||||||
if s.location == t.location {
|
if (s.location == t.location) || (t.nodeLocation != "" && t.nodeLocation == s.nodeLocation) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
peer := wireguard.Peer{
|
peer := wireguard.Peer{
|
||||||
|
@ -532,6 +532,274 @@ func TestNewTopology(t *testing.T) {
|
|||||||
logger: log.NewNopLogger(),
|
logger: log.NewNopLogger(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "cross from a",
|
||||||
|
granularity: CrossGranularity,
|
||||||
|
hostname: nodes["a"].Name,
|
||||||
|
result: &Topology{
|
||||||
|
hostname: nodes["a"].Name,
|
||||||
|
leader: true,
|
||||||
|
location: nodeLocationPrefix + nodes["a"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["a"].Location,
|
||||||
|
subnet: nodes["a"].Subnet,
|
||||||
|
privateIP: nodes["a"].InternalIP,
|
||||||
|
wireGuardCIDR: &net.IPNet{IP: w1, Mask: net.CIDRMask(16, 32)},
|
||||||
|
segments: []*segment{
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["a"].Endpoint,
|
||||||
|
key: nodes["a"].Key,
|
||||||
|
persistentKeepalive: nodes["a"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["a"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["a"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||||
|
hostnames: []string{"a"},
|
||||||
|
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||||
|
wireGuardIP: w1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["b"].Endpoint,
|
||||||
|
key: nodes["b"].Key,
|
||||||
|
persistentKeepalive: nodes["b"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["b"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["b"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||||
|
hostnames: []string{"b"},
|
||||||
|
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||||
|
wireGuardIP: w2,
|
||||||
|
allowedLocationIPs: nodes["b"].AllowedLocationIPs,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["c"].Endpoint,
|
||||||
|
key: nodes["c"].Key,
|
||||||
|
persistentKeepalive: nodes["c"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["c"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["c"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||||
|
hostnames: []string{"c"},
|
||||||
|
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||||
|
wireGuardIP: w3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["d"].Endpoint,
|
||||||
|
key: nodes["d"].Key,
|
||||||
|
persistentKeepalive: nodes["d"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["d"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["d"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||||
|
hostnames: []string{"d"},
|
||||||
|
privateIPs: nil,
|
||||||
|
wireGuardIP: w4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peers: []*Peer{peers["a"], peers["b"]},
|
||||||
|
logger: log.NewNopLogger(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cross from b",
|
||||||
|
granularity: CrossGranularity,
|
||||||
|
hostname: nodes["b"].Name,
|
||||||
|
result: &Topology{
|
||||||
|
hostname: nodes["b"].Name,
|
||||||
|
leader: true,
|
||||||
|
location: nodeLocationPrefix + nodes["b"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["b"].Location,
|
||||||
|
subnet: nodes["b"].Subnet,
|
||||||
|
privateIP: nodes["b"].InternalIP,
|
||||||
|
wireGuardCIDR: &net.IPNet{IP: w2, Mask: net.CIDRMask(16, 32)},
|
||||||
|
segments: []*segment{
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["a"].Endpoint,
|
||||||
|
key: nodes["a"].Key,
|
||||||
|
persistentKeepalive: nodes["a"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["a"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["a"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||||
|
hostnames: []string{"a"},
|
||||||
|
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||||
|
wireGuardIP: w1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["b"].Endpoint,
|
||||||
|
key: nodes["b"].Key,
|
||||||
|
persistentKeepalive: nodes["b"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["b"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["b"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||||
|
hostnames: []string{"b"},
|
||||||
|
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||||
|
wireGuardIP: w2,
|
||||||
|
allowedLocationIPs: nodes["b"].AllowedLocationIPs,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["c"].Endpoint,
|
||||||
|
key: nodes["c"].Key,
|
||||||
|
persistentKeepalive: nodes["c"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["c"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["c"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||||
|
hostnames: []string{"c"},
|
||||||
|
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||||
|
wireGuardIP: w3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["d"].Endpoint,
|
||||||
|
key: nodes["d"].Key,
|
||||||
|
persistentKeepalive: nodes["d"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["d"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["d"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||||
|
hostnames: []string{"d"},
|
||||||
|
privateIPs: nil,
|
||||||
|
wireGuardIP: w4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peers: []*Peer{peers["a"], peers["b"]},
|
||||||
|
logger: log.NewNopLogger(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cross from c",
|
||||||
|
granularity: CrossGranularity,
|
||||||
|
hostname: nodes["c"].Name,
|
||||||
|
result: &Topology{
|
||||||
|
hostname: nodes["c"].Name,
|
||||||
|
leader: true,
|
||||||
|
location: nodeLocationPrefix + nodes["c"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["c"].Location,
|
||||||
|
subnet: nodes["c"].Subnet,
|
||||||
|
privateIP: nodes["c"].InternalIP,
|
||||||
|
wireGuardCIDR: &net.IPNet{IP: w3, Mask: net.CIDRMask(16, 32)},
|
||||||
|
segments: []*segment{
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["a"].Endpoint,
|
||||||
|
key: nodes["a"].Key,
|
||||||
|
persistentKeepalive: nodes["a"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["a"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["a"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||||
|
hostnames: []string{"a"},
|
||||||
|
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||||
|
wireGuardIP: w1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["b"].Endpoint,
|
||||||
|
key: nodes["b"].Key,
|
||||||
|
persistentKeepalive: nodes["b"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["b"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["b"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||||
|
hostnames: []string{"b"},
|
||||||
|
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||||
|
wireGuardIP: w2,
|
||||||
|
allowedLocationIPs: nodes["b"].AllowedLocationIPs,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["c"].Endpoint,
|
||||||
|
key: nodes["c"].Key,
|
||||||
|
persistentKeepalive: nodes["c"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["c"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["c"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||||
|
hostnames: []string{"c"},
|
||||||
|
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||||
|
wireGuardIP: w3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["d"].Endpoint,
|
||||||
|
key: nodes["d"].Key,
|
||||||
|
persistentKeepalive: nodes["d"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["d"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["d"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||||
|
hostnames: []string{"d"},
|
||||||
|
privateIPs: nil,
|
||||||
|
wireGuardIP: w4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peers: []*Peer{peers["a"], peers["b"]},
|
||||||
|
logger: log.NewNopLogger(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "cross from d",
|
||||||
|
granularity: CrossGranularity,
|
||||||
|
hostname: nodes["d"].Name,
|
||||||
|
result: &Topology{
|
||||||
|
hostname: nodes["d"].Name,
|
||||||
|
leader: true,
|
||||||
|
location: nodeLocationPrefix + nodes["d"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["d"].Location,
|
||||||
|
subnet: nodes["d"].Subnet,
|
||||||
|
privateIP: nil,
|
||||||
|
wireGuardCIDR: &net.IPNet{IP: w4, Mask: net.CIDRMask(16, 32)},
|
||||||
|
segments: []*segment{
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["a"].Subnet, *nodes["a"].InternalIP, {IP: w1, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["a"].Endpoint,
|
||||||
|
key: nodes["a"].Key,
|
||||||
|
persistentKeepalive: nodes["a"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["a"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["a"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["a"].Subnet},
|
||||||
|
hostnames: []string{"a"},
|
||||||
|
privateIPs: []net.IP{nodes["a"].InternalIP.IP},
|
||||||
|
wireGuardIP: w1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["b"].Subnet, *nodes["b"].InternalIP, {IP: w2, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["b"].Endpoint,
|
||||||
|
key: nodes["b"].Key,
|
||||||
|
persistentKeepalive: nodes["b"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["b"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["b"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["b"].Subnet},
|
||||||
|
hostnames: []string{"b"},
|
||||||
|
privateIPs: []net.IP{nodes["b"].InternalIP.IP},
|
||||||
|
wireGuardIP: w2,
|
||||||
|
allowedLocationIPs: nodes["b"].AllowedLocationIPs,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["c"].Subnet, *nodes["c"].InternalIP, {IP: w3, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["c"].Endpoint,
|
||||||
|
key: nodes["c"].Key,
|
||||||
|
persistentKeepalive: nodes["c"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["c"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["c"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["c"].Subnet},
|
||||||
|
hostnames: []string{"c"},
|
||||||
|
privateIPs: []net.IP{nodes["c"].InternalIP.IP},
|
||||||
|
wireGuardIP: w3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
allowedIPs: []net.IPNet{*nodes["d"].Subnet, {IP: w4, Mask: net.CIDRMask(32, 32)}},
|
||||||
|
endpoint: nodes["d"].Endpoint,
|
||||||
|
key: nodes["d"].Key,
|
||||||
|
persistentKeepalive: nodes["d"].PersistentKeepalive,
|
||||||
|
location: nodeLocationPrefix + nodes["d"].Name,
|
||||||
|
nodeLocation: logicalLocationPrefix + nodes["d"].Location,
|
||||||
|
cidrs: []*net.IPNet{nodes["d"].Subnet},
|
||||||
|
hostnames: []string{"d"},
|
||||||
|
privateIPs: nil,
|
||||||
|
wireGuardIP: w4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
peers: []*Peer{peers["a"], peers["b"]},
|
||||||
|
logger: log.NewNopLogger(),
|
||||||
|
},
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
tc.result.key = key
|
tc.result.key = key
|
||||||
tc.result.port = port
|
tc.result.port = port
|
||||||
|
Loading…
Reference in New Issue
Block a user