common.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. package common
  2. import (
  3. "bytes"
  4. "context"
  5. "encoding/json"
  6. "fmt"
  7. "io"
  8. "log"
  9. "net"
  10. "net/http"
  11. "os"
  12. "os/exec"
  13. "strings"
  14. "time"
  15. "github.com/gravitl/netmaker/models"
  16. "github.com/gravitl/netmaker/netclient/config"
  17. "github.com/gravitl/netmaker/netclient/ncutils"
  18. "github.com/gravitl/netmaker/netclient/netclient-proxy/wg"
  19. "golang.zx2c4.com/wireguard/wgctrl/wgtypes"
  20. )
  21. const (
  22. NmProxyPort = 51722
  23. )
  24. type Conn struct {
  25. Config ConnConfig
  26. Proxy Proxy
  27. }
  28. // ConnConfig is a peer Connection configuration
  29. type ConnConfig struct {
  30. // Key is a public key of a remote peer
  31. Key string
  32. // LocalKey is a public key of a local peer
  33. LocalKey string
  34. ProxyConfig Config
  35. AllowedIPs []net.IPNet
  36. LocalWgPort int
  37. RemoteProxyIP net.IP
  38. RemoteWgPort int
  39. RemoteProxyPort int
  40. }
  41. type Config struct {
  42. Port int
  43. BodySize int
  44. Addr string
  45. WgListenAddr string
  46. RemoteKey string
  47. WgInterface *wg.WGIface
  48. AllowedIps []net.IPNet
  49. PreSharedKey *wgtypes.Key
  50. //ProxyServer *server.ProxyServer
  51. }
  52. // Proxy - WireguardProxy proxies
  53. type Proxy struct {
  54. Ctx context.Context
  55. Cancel context.CancelFunc
  56. Config Config
  57. RemoteConn net.Conn
  58. LocalConn net.Conn
  59. }
  60. var Peers = make(map[string]*Conn)
  61. var RemoteEndpointsMap = make(map[string][]string)
  62. // RunCmd - runs a local command
  63. func RunCmd(command string, printerr bool) (string, error) {
  64. args := strings.Fields(command)
  65. cmd := exec.Command(args[0], args[1:]...)
  66. cmd.Wait()
  67. out, err := cmd.CombinedOutput()
  68. if err != nil && printerr {
  69. log.Println("error running command: ", command)
  70. log.Println(strings.TrimSuffix(string(out), "\n"))
  71. }
  72. return string(out), err
  73. }
  74. // API function to interact with netmaker api endpoints. response from endpoint is returned
  75. func API(data interface{}, method, url, authorization string) (*http.Response, error) {
  76. var request *http.Request
  77. var err error
  78. if data != "" {
  79. payload, err := json.Marshal(data)
  80. if err != nil {
  81. return nil, fmt.Errorf("error encoding data %w", err)
  82. }
  83. request, err = http.NewRequest(method, url, bytes.NewBuffer(payload))
  84. if err != nil {
  85. return nil, fmt.Errorf("error creating http request %w", err)
  86. }
  87. request.Header.Set("Content-Type", "application/json")
  88. } else {
  89. request, err = http.NewRequest(method, url, nil)
  90. if err != nil {
  91. return nil, fmt.Errorf("error creating http request %w", err)
  92. }
  93. }
  94. if authorization != "" {
  95. request.Header.Set("authorization", "Bearer "+authorization)
  96. }
  97. request.Header.Set("requestfrom", "node")
  98. var httpClient http.Client
  99. httpClient.Timeout = time.Minute
  100. return httpClient.Do(request)
  101. }
  102. // Authenticate authenticates with api to permit subsequent interactions with the api
  103. func Authenticate(cfg *config.ClientConfig) (string, error) {
  104. pass, err := os.ReadFile(ncutils.GetNetclientPathSpecific() + "secret-" + cfg.Network)
  105. if err != nil {
  106. return "", fmt.Errorf("could not read secrets file %w", err)
  107. }
  108. data := models.AuthParams{
  109. MacAddress: cfg.Node.MacAddress,
  110. ID: cfg.Node.ID,
  111. Password: string(pass),
  112. }
  113. url := "https://" + cfg.Server.API + "/api/nodes/adm/" + cfg.Network + "/authenticate"
  114. response, err := API(data, http.MethodPost, url, "")
  115. if err != nil {
  116. return "", err
  117. }
  118. defer response.Body.Close()
  119. if response.StatusCode != http.StatusOK {
  120. bodybytes, _ := io.ReadAll(response.Body)
  121. return "", fmt.Errorf("failed to authenticate %s %s", response.Status, string(bodybytes))
  122. }
  123. resp := models.SuccessResponse{}
  124. if err := json.NewDecoder(response.Body).Decode(&resp); err != nil {
  125. return "", fmt.Errorf("error decoding respone %w", err)
  126. }
  127. tokenData := resp.Response.(map[string]interface{})
  128. token := tokenData["AuthToken"]
  129. return token.(string), nil
  130. }