Merge pull request #150 from juanfont/fix-shared-nodes

Fix shared nodes
This commit is contained in:
Juan Font 2021-10-16 14:09:23 +02:00 committed by GitHub
commit fddc2aa8fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 95 additions and 47 deletions

View File

@ -504,43 +504,43 @@ func (s *IntegrationTestSuite) TestSharedNodes() {
assert.Contains(s.T(), result, hostname) assert.Contains(s.T(), result, hostname)
} }
// TODO(kradalby): Figure out why these connections are not set up // TODO(juanfont): We have to find out why do we need to wait
// // TODO: See if we can have a more deterministic wait here. time.Sleep(100 * time.Second) // Wait for the nodes to receive updates
// time.Sleep(100 * time.Second)
// mainIps, err := getIPs(main.tailscales) mainIps, err := getIPs(main.tailscales)
// assert.Nil(s.T(), err) assert.Nil(s.T(), err)
// sharedIps, err := getIPs(shared.tailscales) sharedIps, err := getIPs(shared.tailscales)
// assert.Nil(s.T(), err) assert.Nil(s.T(), err)
// for hostname, tailscale := range main.tailscales { for hostname, tailscale := range main.tailscales {
// for peername, ip := range sharedIps { for peername, ip := range sharedIps {
// s.T().Run(fmt.Sprintf("%s-%s", hostname, peername), func(t *testing.T) { s.T().Run(fmt.Sprintf("%s-%s", hostname, peername), func(t *testing.T) {
// // We currently cant ping ourselves, so skip that. // We currently cant ping ourselves, so skip that.
// if peername != hostname { if peername != hostname {
// // We are only interested in "direct ping" which means what we // We are only interested in "direct ping" which means what we
// // might need a couple of more attempts before reaching the node. // might need a couple of more attempts before reaching the node.
// command := []string{ command := []string{
// "tailscale", "ping", "tailscale", "ping",
// "--timeout=1s", "--timeout=15s",
// "--c=20", "--c=20",
// "--until-direct=true", "--until-direct=true",
// ip.String(), ip.String(),
// } }
// fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, mainIps[hostname], peername, ip) fmt.Printf("Pinging from %s (%s) to %s (%s)\n", hostname, mainIps[hostname], peername, ip)
// result, err := executeCommand( result, err := executeCommand(
// &tailscale, &tailscale,
// command, command,
// ) []string{},
// assert.Nil(t, err) )
// fmt.Printf("Result for %s: %s\n", hostname, result) assert.Nil(t, err)
// assert.Contains(t, result, "pong") fmt.Printf("Result for %s: %s\n", hostname, result)
// } assert.Contains(t, result, "pong")
// }) }
// } })
// } }
}
} }
func (s *IntegrationTestSuite) TestTailDrop() { func (s *IntegrationTestSuite) TestTailDrop() {

View File

@ -78,13 +78,13 @@ func (h *Headscale) getDirectPeers(m *Machine) (Machines, error) {
return machines, nil return machines, nil
} }
// getShared fetches machines that are shared to the `Namespace` of the machine we are getting peers for
func (h *Headscale) getShared(m *Machine) (Machines, error) { func (h *Headscale) getShared(m *Machine) (Machines, error) {
log.Trace(). log.Trace().
Str("func", "getShared"). Str("func", "getShared").
Str("machine", m.Name). Str("machine", m.Name).
Msg("Finding shared peers") Msg("Finding shared peers")
// We fetch here machines that are shared to the `Namespace` of the machine we are getting peers for
sharedMachines := []SharedMachine{} sharedMachines := []SharedMachine{}
if err := h.db.Preload("Namespace").Preload("Machine").Where("namespace_id = ?", if err := h.db.Preload("Namespace").Preload("Machine").Where("namespace_id = ?",
m.NamespaceID).Find(&sharedMachines).Error; err != nil { m.NamespaceID).Find(&sharedMachines).Error; err != nil {
@ -105,6 +105,37 @@ func (h *Headscale) getShared(m *Machine) (Machines, error) {
return peers, nil return peers, nil
} }
// getSharedTo fetches the machines of the namespaces this machine is shared in
func (h *Headscale) getSharedTo(m *Machine) (Machines, error) {
log.Trace().
Str("func", "getSharedTo").
Str("machine", m.Name).
Msg("Finding peers in namespaces this machine is shared with")
sharedMachines := []SharedMachine{}
if err := h.db.Preload("Namespace").Preload("Machine").Where("machine_id = ?",
m.ID).Find(&sharedMachines).Error; err != nil {
return Machines{}, err
}
peers := make(Machines, 0)
for _, sharedMachine := range sharedMachines {
namespaceMachines, err := h.ListMachinesInNamespace(sharedMachine.Namespace.Name)
if err != nil {
return Machines{}, err
}
peers = append(peers, *namespaceMachines...)
}
sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID })
log.Trace().
Str("func", "getSharedTo").
Str("machine", m.Name).
Msgf("Found peers we are shared with: %s", peers.String())
return peers, nil
}
func (h *Headscale) getPeers(m *Machine) (Machines, error) { func (h *Headscale) getPeers(m *Machine) (Machines, error) {
direct, err := h.getDirectPeers(m) direct, err := h.getDirectPeers(m)
if err != nil { if err != nil {
@ -118,13 +149,24 @@ func (h *Headscale) getPeers(m *Machine) (Machines, error) {
shared, err := h.getShared(m) shared, err := h.getShared(m)
if err != nil { if err != nil {
log.Error(). log.Error().
Str("func", "getDirectPeers"). Str("func", "getShared").
Err(err).
Msg("Cannot fetch peers")
return Machines{}, err
}
sharedTo, err := h.getSharedTo(m)
if err != nil {
log.Error().
Str("func", "sharedTo").
Err(err). Err(err).
Msg("Cannot fetch peers") Msg("Cannot fetch peers")
return Machines{}, err return Machines{}, err
} }
peers := append(direct, shared...) peers := append(direct, shared...)
peers = append(peers, sharedTo...)
sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID }) sort.Slice(peers, func(i, j int) bool { return peers[i].ID < peers[j].ID })
log.Trace(). log.Trace().

View File

@ -274,7 +274,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
c.Assert(err, check.NotNil) c.Assert(err, check.NotNil)
m1 := &Machine{ m1 := &Machine{
ID: 0, ID: 1,
MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
@ -291,7 +291,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m2 := &Machine{ m2 := &Machine{
ID: 1, ID: 2,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
@ -308,7 +308,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m3 := &Machine{ m3 := &Machine{
ID: 2, ID: 3,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
@ -325,7 +325,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m4 := &Machine{ m4 := &Machine{
ID: 3, ID: 4,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
@ -343,7 +343,7 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
p1s, err := h.getPeers(m1) p1s, err := h.getPeers(m1)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(p1s), check.Equals, 1) // nodes 1 and 4 c.Assert(len(p1s), check.Equals, 1) // node1 can see node4
c.Assert(p1s[0].Name, check.Equals, "test_get_shared_nodes_4") c.Assert(p1s[0].Name, check.Equals, "test_get_shared_nodes_4")
err = h.AddSharedMachineToNamespace(m2, n1) err = h.AddSharedMachineToNamespace(m2, n1)
@ -351,18 +351,24 @@ func (s *Suite) TestComplexSharingAcrossNamespaces(c *check.C) {
p1sAfter, err := h.getPeers(m1) p1sAfter, err := h.getPeers(m1)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(p1sAfter), check.Equals, 2) // nodes 1, 2, 4 c.Assert(len(p1sAfter), check.Equals, 2) // node1 can see node2 (shared) and node4 (same namespace)
c.Assert(p1sAfter[0].Name, check.Equals, "test_get_shared_nodes_2") c.Assert(p1sAfter[0].Name, check.Equals, "test_get_shared_nodes_2")
c.Assert(p1sAfter[1].Name, check.Equals, "test_get_shared_nodes_4") c.Assert(p1sAfter[1].Name, check.Equals, "test_get_shared_nodes_4")
node1shared, err := h.getShared(m1) node1shared, err := h.getShared(m1)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(node1shared), check.Equals, 1) // nodes 1, 2, 4 c.Assert(len(node1shared), check.Equals, 1) // node1 can see node2 as shared
c.Assert(node1shared[0].Name, check.Equals, "test_get_shared_nodes_2") c.Assert(node1shared[0].Name, check.Equals, "test_get_shared_nodes_2")
pAlone, err := h.getPeers(m3) pAlone, err := h.getPeers(m3)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(len(pAlone), check.Equals, 0) // node 3 is alone c.Assert(len(pAlone), check.Equals, 0) // node3 is alone
pSharedTo, err := h.getPeers(m2)
c.Assert(err, check.IsNil)
c.Assert(len(pSharedTo), check.Equals, 2) // node2 should see node1 (sharedTo) and node4 (sharedTo), as is shared in namespace1
c.Assert(pSharedTo[0].Name, check.Equals, "test_get_shared_nodes_1")
c.Assert(pSharedTo[1].Name, check.Equals, "test_get_shared_nodes_4")
} }
func (s *Suite) TestDeleteSharedMachine(c *check.C) { func (s *Suite) TestDeleteSharedMachine(c *check.C) {
@ -391,7 +397,7 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) {
c.Assert(err, check.NotNil) c.Assert(err, check.NotNil)
m1 := &Machine{ m1 := &Machine{
ID: 0, ID: 1,
MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", MachineKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", NodeKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66", DiscoKey: "686824e749f3b7f2a5927ee6c1e422aee5292592d9179a271ed7b3e659b44a66",
@ -408,7 +414,7 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m2 := &Machine{ m2 := &Machine{
ID: 1, ID: 2,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
@ -425,7 +431,7 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m3 := &Machine{ m3 := &Machine{
ID: 2, ID: 3,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
@ -442,7 +448,7 @@ func (s *Suite) TestDeleteSharedMachine(c *check.C) {
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
m4 := &Machine{ m4 := &Machine{
ID: 3, ID: 4,
MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", MachineKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", NodeKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",
DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863", DiscoKey: "dec46ef9dc45c7d2f03bfcd5a640d9e24e3cc68ce3d9da223867c9bc6d5e9863",