main.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //TODO: Harden. Add failover for every method and agent calls
  2. //TODO: Figure out why mongodb keeps failing (log rotation?)
  3. package main
  4. import (
  5. "fmt"
  6. "log"
  7. "net"
  8. "os"
  9. "os/signal"
  10. "strconv"
  11. "sync"
  12. "time"
  13. controller "github.com/gravitl/netmaker/controllers"
  14. "github.com/gravitl/netmaker/database"
  15. "github.com/gravitl/netmaker/functions"
  16. nodepb "github.com/gravitl/netmaker/grpc"
  17. "github.com/gravitl/netmaker/models"
  18. "github.com/gravitl/netmaker/netclient/ncutils"
  19. "github.com/gravitl/netmaker/servercfg"
  20. "github.com/gravitl/netmaker/serverctl"
  21. "google.golang.org/grpc"
  22. )
  23. // Start DB Connection and start API Request Handler
  24. func main() {
  25. fmt.Println(models.RetrieveLogo()) // print the logo
  26. initialize() // initial db and grpc server
  27. defer database.CloseDB()
  28. startControllers() // start the grpc or rest endpoints
  29. }
  30. func initialize() { // Client Mode Prereq Check
  31. var err error
  32. if err = database.InitializeDatabase(); err != nil {
  33. log.Println("Error connecting to database.")
  34. log.Fatal(err)
  35. }
  36. log.Println("database successfully connected.")
  37. if servercfg.IsClientMode() != "off" {
  38. output, err := ncutils.RunCmd("id -u", true)
  39. if err != nil {
  40. log.Println("Error running 'id -u' for prereq check. Please investigate or disable client mode.")
  41. log.Fatal(output, err)
  42. }
  43. uid, err := strconv.Atoi(string(output[:len(output)-1]))
  44. if err != nil {
  45. log.Println("Error retrieving uid from 'id -u' for prereq check. Please investigate or disable client mode.")
  46. log.Fatal(err)
  47. }
  48. if uid != 0 {
  49. log.Fatal("To run in client mode requires root privileges. Either disable client mode or run with sudo.")
  50. }
  51. if err := serverctl.InitServerNetclient(); err != nil {
  52. log.Fatal("Did not find netclient to use CLIENT_MODE")
  53. }
  54. }
  55. if servercfg.IsDNSMode() {
  56. err := functions.SetDNSDir()
  57. if err != nil {
  58. log.Fatal(err)
  59. }
  60. }
  61. }
  62. func startControllers() {
  63. var waitnetwork sync.WaitGroup
  64. //Run Agent Server
  65. if servercfg.IsAgentBackend() {
  66. if !(servercfg.DisableRemoteIPCheck()) && servercfg.GetGRPCHost() == "127.0.0.1" {
  67. err := servercfg.SetHost()
  68. if err != nil {
  69. log.Println("Unable to Set host. Exiting...")
  70. log.Fatal(err)
  71. }
  72. }
  73. waitnetwork.Add(1)
  74. go runGRPC(&waitnetwork)
  75. }
  76. // Run the client in goroutine locally if CLIENT_MODE is "contained"
  77. if servercfg.IsClientMode() == "contained" {
  78. waitnetwork.Add(1)
  79. go runClient(&waitnetwork)
  80. }
  81. if servercfg.IsDNSMode() {
  82. err := controller.SetDNS()
  83. if err != nil {
  84. log.Println("error occurred initializing DNS:", err)
  85. }
  86. }
  87. //Run Rest Server
  88. if servercfg.IsRestBackend() {
  89. if !servercfg.DisableRemoteIPCheck() && servercfg.GetAPIHost() == "127.0.0.1" {
  90. err := servercfg.SetHost()
  91. if err != nil {
  92. log.Println("Unable to Set host. Exiting...")
  93. log.Fatal(err)
  94. }
  95. }
  96. waitnetwork.Add(1)
  97. controller.HandleRESTRequests(&waitnetwork)
  98. }
  99. if !servercfg.IsAgentBackend() && !servercfg.IsRestBackend() {
  100. log.Println("No Server Mode selected, so nothing is being served! Set either Agent mode (AGENT_BACKEND) or Rest mode (REST_BACKEND) to 'true'.")
  101. }
  102. waitnetwork.Wait()
  103. log.Println("[netmaker] exiting")
  104. }
  105. func runClient(wg *sync.WaitGroup) {
  106. defer wg.Done()
  107. log.Println("CLIENT_MODE running as contained")
  108. go func() {
  109. for {
  110. if err := serverctl.HandleContainedClient(); err != nil {
  111. // PASS
  112. }
  113. time.Sleep(time.Second * 15)
  114. }
  115. }()
  116. }
  117. func runGRPC(wg *sync.WaitGroup) {
  118. defer wg.Done()
  119. // Configure 'log' package to give file name and line number on eg. log.Fatal
  120. // Pipe flags to one another (log.LstdFLags = log.Ldate | log.Ltime)
  121. log.SetFlags(log.LstdFlags | log.Lshortfile)
  122. grpcport := servercfg.GetGRPCPort()
  123. listener, err := net.Listen("tcp", ":"+grpcport)
  124. // Handle errors if any
  125. if err != nil {
  126. log.Fatalf("Unable to listen on port "+grpcport+", error: %v", err)
  127. }
  128. s := grpc.NewServer(
  129. authServerUnaryInterceptor(),
  130. )
  131. // Create NodeService type
  132. srv := &controller.NodeServiceServer{}
  133. // Register the service with the server
  134. nodepb.RegisterNodeServiceServer(s, srv)
  135. // Start the server in a child routine
  136. go func() {
  137. if err := s.Serve(listener); err != nil {
  138. log.Fatalf("Failed to serve: %v", err)
  139. }
  140. }()
  141. log.Println("Agent Server succesfully started on port " + grpcport + " (gRPC)")
  142. // Right way to stop the server using a SHUTDOWN HOOK
  143. // Create a channel to receive OS signals
  144. c := make(chan os.Signal)
  145. // Relay os.Interrupt to our channel (os.Interrupt = CTRL+C)
  146. // Ignore other incoming signals
  147. signal.Notify(c, os.Interrupt)
  148. // Block main routine until a signal is received
  149. // As long as user doesn't press CTRL+C a message is not passed and our main routine keeps running
  150. <-c
  151. // After receiving CTRL+C Properly stop the server
  152. log.Println("Stopping the Agent server...")
  153. s.Stop()
  154. listener.Close()
  155. log.Println("Agent server closed..")
  156. log.Println("Closed DB connection.")
  157. }
  158. func authServerUnaryInterceptor() grpc.ServerOption {
  159. return grpc.UnaryInterceptor(controller.AuthServerUnaryInterceptor)
  160. }
  161. // func authServerStreamInterceptor() grpc.ServerOption {
  162. // return grpc.StreamInterceptor(controller.AuthServerStreamInterceptor)
  163. // }