server.go 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package controller
  2. import (
  3. "encoding/json"
  4. "net/http"
  5. "strings"
  6. "syscall"
  7. "github.com/gorilla/mux"
  8. "golang.org/x/exp/slog"
  9. "github.com/gravitl/netmaker/database"
  10. "github.com/gravitl/netmaker/logic"
  11. "github.com/gravitl/netmaker/models"
  12. "github.com/gravitl/netmaker/mq"
  13. "github.com/gravitl/netmaker/servercfg"
  14. )
  15. func serverHandlers(r *mux.Router) {
  16. // r.HandleFunc("/api/server/addnetwork/{network}", securityCheckServer(true, http.HandlerFunc(addNetwork))).Methods(http.MethodPost)
  17. r.HandleFunc(
  18. "/api/server/health",
  19. func(resp http.ResponseWriter, req *http.Request) {
  20. resp.WriteHeader(http.StatusOK)
  21. resp.Write([]byte("Server is up and running!!"))
  22. },
  23. ).Methods(http.MethodGet)
  24. r.HandleFunc(
  25. "/api/server/shutdown",
  26. func(w http.ResponseWriter, _ *http.Request) {
  27. msg := "received api call to shutdown server, sending interruption..."
  28. slog.Warn(msg)
  29. _, _ = w.Write([]byte(msg))
  30. w.WriteHeader(http.StatusOK)
  31. _ = syscall.Kill(syscall.Getpid(), syscall.SIGINT)
  32. },
  33. ).Methods(http.MethodPost)
  34. r.HandleFunc("/api/server/getconfig", allowUsers(http.HandlerFunc(getConfig))).
  35. Methods(http.MethodGet)
  36. r.HandleFunc("/api/server/getserverinfo", Authorize(true, false, "node", http.HandlerFunc(getServerInfo))).
  37. Methods(http.MethodGet)
  38. r.HandleFunc("/api/server/status", getStatus).Methods(http.MethodGet)
  39. r.HandleFunc("/api/server/usage", Authorize(true, false, "user", http.HandlerFunc(getUsage))).
  40. Methods(http.MethodGet)
  41. }
  42. func getUsage(w http.ResponseWriter, _ *http.Request) {
  43. type usage struct {
  44. Hosts int `json:"hosts"`
  45. Clients int `json:"clients"`
  46. Networks int `json:"networks"`
  47. Users int `json:"users"`
  48. Ingresses int `json:"ingresses"`
  49. Egresses int `json:"egresses"`
  50. Relays int `json:"relays"`
  51. InternetGateways int `json:"internet_gateways"`
  52. }
  53. var serverUsage usage
  54. hosts, err := logic.GetAllHosts()
  55. if err == nil {
  56. serverUsage.Hosts = len(hosts)
  57. }
  58. clients, err := logic.GetAllExtClients()
  59. if err == nil {
  60. serverUsage.Clients = len(clients)
  61. }
  62. users, err := logic.GetUsers()
  63. if err == nil {
  64. serverUsage.Users = len(users)
  65. }
  66. networks, err := logic.GetNetworks()
  67. if err == nil {
  68. serverUsage.Networks = len(networks)
  69. }
  70. // TODO this part bellow can be optimized to get nodes just once
  71. ingresses, err := logic.GetAllIngresses()
  72. if err == nil {
  73. serverUsage.Ingresses = len(ingresses)
  74. }
  75. egresses, err := logic.GetAllEgresses()
  76. if err == nil {
  77. serverUsage.Egresses = len(egresses)
  78. }
  79. relays, err := logic.GetRelays()
  80. if err == nil {
  81. serverUsage.Relays = len(relays)
  82. }
  83. gateways, err := logic.GetInternetGateways()
  84. if err == nil {
  85. serverUsage.InternetGateways = len(gateways)
  86. }
  87. w.Header().Set("Content-Type", "application/json")
  88. json.NewEncoder(w).Encode(models.SuccessResponse{
  89. Code: http.StatusOK,
  90. Response: serverUsage,
  91. })
  92. }
  93. // swagger:route GET /api/server/status server getStatus
  94. //
  95. // Get the server configuration.
  96. //
  97. // Schemes: https
  98. //
  99. // Security:
  100. // oauth
  101. //
  102. // Responses:
  103. // 200: serverConfigResponse
  104. func getStatus(w http.ResponseWriter, r *http.Request) {
  105. type status struct {
  106. DB bool `json:"db_connected"`
  107. Broker bool `json:"broker_connected"`
  108. LicenseError string `json:"license_error"`
  109. IsPro bool `json:"is_pro"`
  110. }
  111. licenseErr := ""
  112. if servercfg.ErrLicenseValidation != nil {
  113. licenseErr = servercfg.ErrLicenseValidation.Error()
  114. }
  115. currentServerStatus := status{
  116. DB: database.IsConnected(),
  117. Broker: mq.IsConnected(),
  118. LicenseError: licenseErr,
  119. IsPro: servercfg.IsPro,
  120. }
  121. w.Header().Set("Content-Type", "application/json")
  122. json.NewEncoder(w).Encode(&currentServerStatus)
  123. }
  124. // allowUsers - allow all authenticated (valid) users - only used by getConfig, may be able to remove during refactor
  125. func allowUsers(next http.Handler) http.HandlerFunc {
  126. return func(w http.ResponseWriter, r *http.Request) {
  127. errorResponse := models.ErrorResponse{
  128. Code: http.StatusUnauthorized, Message: logic.Unauthorized_Msg,
  129. }
  130. bearerToken := r.Header.Get("Authorization")
  131. tokenSplit := strings.Split(bearerToken, " ")
  132. authToken := ""
  133. if len(tokenSplit) < 2 {
  134. logic.ReturnErrorResponse(w, r, errorResponse)
  135. return
  136. } else {
  137. authToken = tokenSplit[1]
  138. }
  139. user, _, _, err := logic.VerifyUserToken(authToken)
  140. if err != nil || user == "" {
  141. logic.ReturnErrorResponse(w, r, errorResponse)
  142. return
  143. }
  144. next.ServeHTTP(w, r)
  145. }
  146. }
  147. // swagger:route GET /api/server/getserverinfo server getServerInfo
  148. //
  149. // Get the server configuration.
  150. //
  151. // Schemes: https
  152. //
  153. // Security:
  154. // oauth
  155. //
  156. // Responses:
  157. // 200: serverConfigResponse
  158. func getServerInfo(w http.ResponseWriter, r *http.Request) {
  159. // Set header
  160. w.Header().Set("Content-Type", "application/json")
  161. // get params
  162. json.NewEncoder(w).Encode(servercfg.GetServerInfo())
  163. // w.WriteHeader(http.StatusOK)
  164. }
  165. // swagger:route GET /api/server/getconfig server getConfig
  166. //
  167. // Get the server configuration.
  168. //
  169. // Schemes: https
  170. //
  171. // Security:
  172. // oauth
  173. //
  174. // Responses:
  175. // 200: serverConfigResponse
  176. func getConfig(w http.ResponseWriter, r *http.Request) {
  177. // Set header
  178. w.Header().Set("Content-Type", "application/json")
  179. // get params
  180. scfg := servercfg.GetServerConfig()
  181. scfg.IsPro = "no"
  182. if servercfg.IsPro {
  183. scfg.IsPro = "yes"
  184. }
  185. json.NewEncoder(w).Encode(scfg)
  186. // w.WriteHeader(http.StatusOK)
  187. }