hostmap.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. //go:build e2e_testing
  2. // +build e2e_testing
  3. package router
  4. import (
  5. "fmt"
  6. "strings"
  7. "github.com/slackhq/nebula"
  8. )
  9. type edge struct {
  10. from string
  11. to string
  12. dual bool
  13. }
  14. func renderHostmaps(controls ...*nebula.Control) string {
  15. var lines []*edge
  16. r := "graph TB\n"
  17. for _, c := range controls {
  18. sr, se := renderHostmap(c)
  19. r += sr
  20. for _, e := range se {
  21. add := true
  22. // Collapse duplicate edges into a bi-directionally connected edge
  23. for _, ge := range lines {
  24. if e.to == ge.from && e.from == ge.to {
  25. add = false
  26. ge.dual = true
  27. break
  28. }
  29. }
  30. if add {
  31. lines = append(lines, e)
  32. }
  33. }
  34. }
  35. for _, line := range lines {
  36. if line.dual {
  37. r += fmt.Sprintf("\t%v <--> %v\n", line.from, line.to)
  38. } else {
  39. r += fmt.Sprintf("\t%v --> %v\n", line.from, line.to)
  40. }
  41. }
  42. return r
  43. }
  44. func renderHostmap(c *nebula.Control) (string, []*edge) {
  45. var lines []string
  46. var globalLines []*edge
  47. clusterName := strings.Trim(c.GetCert().Details.Name, " ")
  48. clusterVpnIp := c.GetCert().Details.Ips[0].IP
  49. r := fmt.Sprintf("\tsubgraph %s[\"%s (%s)\"]\n", clusterName, clusterName, clusterVpnIp)
  50. hm := c.GetHostmap()
  51. // Draw the vpn to index nodes
  52. r += fmt.Sprintf("\t\tsubgraph %s.hosts[\"Hosts (vpn ip to index)\"]\n", clusterName)
  53. for vpnIp, hi := range hm.Hosts {
  54. r += fmt.Sprintf("\t\t\t%v.%v[\"%v\"]\n", clusterName, vpnIp, vpnIp)
  55. lines = append(lines, fmt.Sprintf("%v.%v --> %v.%v", clusterName, vpnIp, clusterName, hi.GetLocalIndex()))
  56. rs := hi.GetRelayState()
  57. for _, relayIp := range rs.CopyRelayIps() {
  58. lines = append(lines, fmt.Sprintf("%v.%v --> %v.%v", clusterName, vpnIp, clusterName, relayIp))
  59. }
  60. for _, relayIp := range rs.CopyRelayForIdxs() {
  61. lines = append(lines, fmt.Sprintf("%v.%v --> %v.%v", clusterName, vpnIp, clusterName, relayIp))
  62. }
  63. }
  64. r += "\t\tend\n"
  65. // Draw the relay hostinfos
  66. if len(hm.Relays) > 0 {
  67. r += fmt.Sprintf("\t\tsubgraph %s.relays[\"Relays (relay index to hostinfo)\"]\n", clusterName)
  68. for relayIndex, hi := range hm.Relays {
  69. r += fmt.Sprintf("\t\t\t%v.%v[\"%v\"]\n", clusterName, relayIndex, relayIndex)
  70. lines = append(lines, fmt.Sprintf("%v.%v --> %v.%v", clusterName, relayIndex, clusterName, hi.GetLocalIndex()))
  71. }
  72. r += "\t\tend\n"
  73. }
  74. // Draw the local index to relay or remote index nodes
  75. r += fmt.Sprintf("\t\tsubgraph indexes.%s[\"Indexes (index to hostinfo)\"]\n", clusterName)
  76. for idx, hi := range hm.Indexes {
  77. r += fmt.Sprintf("\t\t\t%v.%v[\"%v (%v)\"]\n", clusterName, idx, idx, hi.GetVpnIp())
  78. remoteClusterName := strings.Trim(hi.GetCert().Details.Name, " ")
  79. globalLines = append(globalLines, &edge{from: fmt.Sprintf("%v.%v", clusterName, idx), to: fmt.Sprintf("%v.%v", remoteClusterName, hi.GetRemoteIndex())})
  80. _ = hi
  81. }
  82. r += "\t\tend\n"
  83. // Add the edges inside this host
  84. for _, line := range lines {
  85. r += fmt.Sprintf("\t\t%v\n", line)
  86. }
  87. r += "\tend\n"
  88. return r, globalLines
  89. }