checkin.go 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. package functions
  2. import (
  3. "google.golang.org/grpc/credentials"
  4. "crypto/tls"
  5. "fmt"
  6. "context"
  7. "strings"
  8. "log"
  9. "net"
  10. "os/exec"
  11. "github.com/gravitl/netmaker/netclient/config"
  12. "github.com/gravitl/netmaker/netclient/local"
  13. "github.com/gravitl/netmaker/netclient/wireguard"
  14. "github.com/gravitl/netmaker/netclient/server"
  15. "github.com/gravitl/netmaker/netclient/auth"
  16. nodepb "github.com/gravitl/netmaker/grpc"
  17. "google.golang.org/grpc"
  18. "google.golang.org/grpc/metadata"
  19. //homedir "github.com/mitchellh/go-homedir"
  20. )
  21. func CheckIn(cliconf config.ClientConfig) error {
  22. network := cliconf.Network
  23. node := server.GetNode(network)
  24. cfg, err := config.ReadConfig(network)
  25. if err != nil {
  26. return err
  27. }
  28. nodecfg := cfg.Node
  29. servercfg := cfg.Server
  30. fmt.Println("Checking into server at " + servercfg.GRPCAddress)
  31. setupcheck := true
  32. ipchange := false
  33. if nodecfg.DNS == "on" || cliconf.Node.DNS == "on" {
  34. fmt.Println("setting dns")
  35. ifacename := node.Interface
  36. nameserver := servercfg.CoreDNSAddr
  37. network := node.Nodenetwork
  38. _ = local.UpdateDNS(ifacename, network, nameserver)
  39. }
  40. if !(nodecfg.IPForwarding == "off") {
  41. out, err := exec.Command("sysctl", "net.ipv4.ip_forward").Output()
  42. if err != nil {
  43. fmt.Println(err)
  44. fmt.Println("WARNING: Error encountered setting ip forwarding. This can break functionality.")
  45. } else {
  46. s := strings.Fields(string(out))
  47. if s[2] != "1" {
  48. _, err = exec.Command("sysctl", "-w", "net.ipv4.ip_forward=1").Output()
  49. if err != nil {
  50. fmt.Println(err)
  51. fmt.Println("WARNING: Error encountered setting ip forwarding. You may want to investigate this.")
  52. }
  53. }
  54. }
  55. }
  56. if nodecfg.Roaming != "off" {
  57. if nodecfg.IsLocal != "yes" {
  58. fmt.Println("Checking to see if public addresses have changed")
  59. extIP, err := getPublicIP()
  60. if err != nil {
  61. fmt.Printf("Error encountered checking ip addresses: %v", err)
  62. }
  63. if nodecfg.Endpoint != extIP && extIP != "" {
  64. fmt.Println("Endpoint has changed from " +
  65. nodecfg.Endpoint + " to " + extIP)
  66. fmt.Println("Updating address")
  67. nodecfg.Endpoint = extIP
  68. nodecfg.PostChanges = "true"
  69. node.Endpoint = extIP
  70. node.Postchanges = "true"
  71. ipchange = true
  72. }
  73. intIP, err := getPrivateAddr()
  74. if err != nil {
  75. fmt.Printf("Error encountered checking ip addresses: %v", err)
  76. }
  77. if nodecfg.LocalAddress != intIP && intIP != "" {
  78. fmt.Println("Local Address has changed from " +
  79. nodecfg.LocalAddress + " to " + intIP)
  80. fmt.Println("Updating address")
  81. nodecfg.LocalAddress = intIP
  82. nodecfg.PostChanges = "true"
  83. node.Localaddress = intIP
  84. node.Postchanges = "true"
  85. ipchange = true
  86. }
  87. } else {
  88. fmt.Println("Checking to see if local addresses have changed")
  89. localIP, err := getLocalIP(nodecfg.LocalRange)
  90. if err != nil {
  91. fmt.Printf("Error encountered checking ip addresses: %v", err)
  92. }
  93. if nodecfg.Endpoint != localIP && localIP != "" {
  94. fmt.Println("Endpoint has changed from " +
  95. nodecfg.Endpoint + " to " + localIP)
  96. fmt.Println("Updating address")
  97. nodecfg.Endpoint = localIP
  98. nodecfg.LocalAddress = localIP
  99. nodecfg.PostChanges = "true"
  100. node.Endpoint = localIP
  101. node.Localaddress = localIP
  102. node.Postchanges = "true"
  103. ipchange = true
  104. }
  105. }
  106. if node.Postchanges != "true" {
  107. fmt.Println("Addresses have not changed.")
  108. }
  109. }
  110. if ipchange {
  111. err := config.ModConfig(&node)
  112. if err != nil {
  113. return err
  114. log.Fatalf("Error: %v", err)
  115. }
  116. err = wireguard.SetWGConfig(network)
  117. if err != nil {
  118. return err
  119. log.Fatalf("Error: %v", err)
  120. }
  121. node = server.GetNode(network)
  122. cfg, err := config.ReadConfig(network)
  123. if err != nil {
  124. return err
  125. }
  126. nodecfg = cfg.Node
  127. }
  128. var wcclient nodepb.NodeServiceClient
  129. var requestOpts grpc.DialOption
  130. requestOpts = grpc.WithInsecure()
  131. if servercfg.GRPCSSL == "on" {
  132. log.Println("using SSL")
  133. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  134. requestOpts = grpc.WithTransportCredentials(h2creds)
  135. } else {
  136. log.Println("using insecure GRPC connection")
  137. }
  138. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  139. if err != nil {
  140. fmt.Printf("Cant dial GRPC server: %v", err)
  141. return err
  142. }
  143. wcclient = nodepb.NewNodeServiceClient(conn)
  144. ctx := context.Background()
  145. fmt.Println("Authenticating with GRPC Server")
  146. ctx, err = auth.SetJWT(wcclient, network)
  147. if err != nil {
  148. fmt.Printf("Failed to authenticate: %v", err)
  149. return err
  150. }
  151. fmt.Println("Authenticated")
  152. fmt.Println("Checking In.")
  153. var header metadata.MD
  154. node.Nodenetwork = network
  155. checkinres, err := wcclient.CheckIn(
  156. ctx,
  157. &nodepb.CheckInReq{
  158. Node: &node,
  159. },
  160. grpc.Header(&header),
  161. )
  162. if err != nil {
  163. if checkinres != nil && checkinres.Checkinresponse.Ispending {
  164. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  165. return nil
  166. }
  167. fmt.Printf("Unable to process Check In request: %v", err)
  168. return err
  169. }
  170. fmt.Println("Checked in.")
  171. if checkinres.Checkinresponse.Ispending {
  172. fmt.Println("Node is in pending status. Waiting for Admin approval of node before making further updates.")
  173. return err
  174. }
  175. newinterface := server.GetNode(network).Interface
  176. readreq := &nodepb.ReadNodeReq{
  177. Macaddress: node.Macaddress,
  178. Network: node.Nodenetwork,
  179. }
  180. readres, err := wcclient.ReadNode(ctx, readreq, grpc.Header(&header))
  181. if err != nil {
  182. fmt.Printf("Error: %v", err)
  183. } else {
  184. currentiface := readres.Node.Interface
  185. ifaceupdate := newinterface != currentiface
  186. if err != nil {
  187. log.Printf("Error retrieving interface: %v", err)
  188. }
  189. if ifaceupdate {
  190. fmt.Println("Interface update: " + currentiface +
  191. " >>>> " + newinterface)
  192. err := DeleteInterface(currentiface, nodecfg.PostDown)
  193. if err != nil {
  194. fmt.Println("ERROR DELETING INTERFACE: " + currentiface)
  195. }
  196. err = wireguard.SetWGConfig(network)
  197. if err != nil {
  198. log.Printf("Error updating interface: %v", err)
  199. }
  200. }
  201. }
  202. if checkinres.Checkinresponse.Needconfigupdate {
  203. fmt.Println("Server has requested that node update config.")
  204. fmt.Println("Updating config from remote server.")
  205. req := &nodepb.ReadNodeReq{
  206. Macaddress: node.Macaddress,
  207. Network: node.Nodenetwork,
  208. }
  209. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  210. if err != nil {
  211. return err
  212. log.Fatalf("Error: %v", err)
  213. }
  214. err = config.ModConfig(readres.Node)
  215. if err != nil {
  216. return err
  217. log.Fatalf("Error: %v", err)
  218. }
  219. err = wireguard.SetWGConfig(network)
  220. if err != nil {
  221. return err
  222. log.Fatalf("Error: %v", err)
  223. }
  224. setupcheck = false
  225. } else if nodecfg.PostChanges == "true" {
  226. fmt.Println("Node has requested to update remote config.")
  227. fmt.Println("Posting local config to remote server.")
  228. postnode := server.GetNode(network)
  229. req := &nodepb.UpdateNodeReq{
  230. Node: &postnode,
  231. }
  232. res, err := wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  233. if err != nil {
  234. return err
  235. log.Fatalf("Error: %v", err)
  236. }
  237. res.Node.Postchanges = "false"
  238. err = config.ModConfig(res.Node)
  239. if err != nil {
  240. return err
  241. log.Fatalf("Error: %v", err)
  242. }
  243. err = wireguard.SetWGConfig(network)
  244. if err != nil {
  245. return err
  246. log.Fatalf("Error: %v", err)
  247. }
  248. setupcheck = false
  249. }
  250. if checkinres.Checkinresponse.Needkeyupdate {
  251. fmt.Println("Server has requested that node update key pairs.")
  252. fmt.Println("Proceeding to re-generate key pairs for Wiregard.")
  253. err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
  254. if err != nil {
  255. return err
  256. log.Fatalf("Unable to process reset keys request: %v", err)
  257. }
  258. setupcheck = false
  259. }
  260. if checkinres.Checkinresponse.Needpeerupdate {
  261. fmt.Println("Server has requested that node update peer list.")
  262. fmt.Println("Updating peer list from remote server.")
  263. err = wireguard.SetWGConfig(network)
  264. if err != nil {
  265. return err
  266. log.Fatalf("Unable to process Set Peers request: %v", err)
  267. }
  268. setupcheck = false
  269. }
  270. if checkinres.Checkinresponse.Needdelete {
  271. fmt.Println("This machine got the delete signal. Deleting.")
  272. err := LeaveNetwork(network)
  273. if err != nil {
  274. return err
  275. log.Fatalf("Error: %v", err)
  276. }
  277. }
  278. if setupcheck {
  279. iface := nodecfg.Interface
  280. _, err := net.InterfaceByName(iface)
  281. if err != nil {
  282. fmt.Println("interface " + iface + " does not currently exist. Setting up WireGuard.")
  283. err = wireguard.SetWGKeyConfig(network, servercfg.GRPCAddress)
  284. if err != nil {
  285. return err
  286. log.Fatalf("Error: %v", err)
  287. }
  288. }
  289. }
  290. return nil
  291. }
  292. func Pull (network string) error{
  293. node := server.GetNode(network)
  294. cfg, err := config.ReadConfig(network)
  295. if err != nil {
  296. return err
  297. }
  298. servercfg := cfg.Server
  299. var header metadata.MD
  300. var wcclient nodepb.NodeServiceClient
  301. var requestOpts grpc.DialOption
  302. requestOpts = grpc.WithInsecure()
  303. if cfg.Server.GRPCSSL == "on" {
  304. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  305. requestOpts = grpc.WithTransportCredentials(h2creds)
  306. }
  307. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  308. if err != nil {
  309. fmt.Printf("Cant dial GRPC server: %v", err)
  310. return err
  311. }
  312. wcclient = nodepb.NewNodeServiceClient(conn)
  313. ctx := context.Background()
  314. ctx, err = auth.SetJWT(wcclient, network)
  315. if err != nil {
  316. fmt.Printf("Failed to authenticate: %v", err)
  317. return err
  318. }
  319. req := &nodepb.ReadNodeReq{
  320. Macaddress: node.Macaddress,
  321. Network: node.Nodenetwork,
  322. }
  323. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  324. if err != nil {
  325. return err
  326. }
  327. err = config.ModConfig(readres.Node)
  328. if err != nil {
  329. return err
  330. }
  331. err = wireguard.SetWGConfig(network)
  332. if err != nil {
  333. return err
  334. }
  335. return err
  336. }
  337. func Push (network string) error{
  338. postnode := server.GetNode(network)
  339. cfg, err := config.ReadConfig(network)
  340. if err != nil {
  341. return err
  342. }
  343. servercfg := cfg.Server
  344. var header metadata.MD
  345. var wcclient nodepb.NodeServiceClient
  346. var requestOpts grpc.DialOption
  347. requestOpts = grpc.WithInsecure()
  348. if cfg.Server.GRPCSSL == "on" {
  349. h2creds := credentials.NewTLS(&tls.Config{NextProtos: []string{"h2"}})
  350. requestOpts = grpc.WithTransportCredentials(h2creds)
  351. }
  352. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  353. if err != nil {
  354. fmt.Printf("Cant dial GRPC server: %v", err)
  355. return err
  356. }
  357. wcclient = nodepb.NewNodeServiceClient(conn)
  358. ctx := context.Background()
  359. ctx, err = auth.SetJWT(wcclient, network)
  360. if err != nil {
  361. fmt.Printf("Failed to authenticate: %v", err)
  362. return err
  363. }
  364. req := &nodepb.UpdateNodeReq{
  365. Node: &postnode,
  366. }
  367. _, err = wcclient.UpdateNode(ctx, req, grpc.Header(&header))
  368. return err
  369. }