common.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. package functions
  2. import (
  3. "context"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "log"
  9. "net"
  10. "os/exec"
  11. "strings"
  12. nodepb "github.com/gravitl/netmaker/grpc"
  13. "github.com/gravitl/netmaker/models"
  14. "github.com/gravitl/netmaker/netclient/auth"
  15. "github.com/gravitl/netmaker/netclient/config"
  16. "github.com/gravitl/netmaker/netclient/local"
  17. "github.com/gravitl/netmaker/netclient/netclientutils"
  18. "golang.zx2c4.com/wireguard/wgctrl"
  19. "google.golang.org/grpc"
  20. "google.golang.org/grpc/metadata"
  21. )
  22. var (
  23. wcclient nodepb.NodeServiceClient
  24. )
  25. func ListPorts() error {
  26. wgclient, err := wgctrl.New()
  27. if err != nil {
  28. return err
  29. }
  30. devices, err := wgclient.Devices()
  31. if err != nil {
  32. return err
  33. }
  34. fmt.Println("Here are your ports:")
  35. for _, i := range devices {
  36. fmt.Println(i.ListenPort)
  37. }
  38. return err
  39. }
  40. func getPrivateAddr() (string, error) {
  41. var local string
  42. conn, err := net.Dial("udp", "8.8.8.8:80")
  43. if err != nil {
  44. log.Fatal(err)
  45. }
  46. defer conn.Close()
  47. localAddr := conn.LocalAddr().(*net.UDPAddr)
  48. localIP := localAddr.IP
  49. local = localIP.String()
  50. if local == "" {
  51. err = errors.New("could not find local ip")
  52. }
  53. return local, err
  54. }
  55. func needInterfaceUpdate(ctx context.Context, mac string, network string, iface string) (bool, string, error) {
  56. var header metadata.MD
  57. req := &nodepb.Object{
  58. Data: mac + "###" + network,
  59. Type: nodepb.STRING_TYPE,
  60. }
  61. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  62. if err != nil {
  63. return false, "", err
  64. }
  65. var resNode models.Node
  66. if err := json.Unmarshal([]byte(readres.Data), &resNode); err != nil {
  67. return false, iface, err
  68. }
  69. oldiface := resNode.Interface
  70. return iface != oldiface, oldiface, err
  71. }
  72. func GetNode(network string) models.Node {
  73. modcfg, err := config.ReadConfig(network)
  74. if err != nil {
  75. log.Fatalf("Error: %v", err)
  76. }
  77. return modcfg.Node
  78. }
  79. func Uninstall() error {
  80. networks, err := GetNetworks()
  81. if err != nil {
  82. log.Println("unable to retrieve networks: ", err)
  83. log.Println("continuing uninstall without leaving networks")
  84. } else {
  85. for _, network := range networks {
  86. err = LeaveNetwork(network)
  87. if err != nil {
  88. log.Println("Encounter issue leaving network "+network+": ", err)
  89. }
  90. }
  91. }
  92. // clean up OS specific stuff
  93. if netclientutils.IsWindows() {
  94. local.Cleanup()
  95. }
  96. return err
  97. }
  98. func LeaveNetwork(network string) error {
  99. //need to implement checkin on server side
  100. cfg, err := config.ReadConfig(network)
  101. if err != nil {
  102. return err
  103. }
  104. servercfg := cfg.Server
  105. node := cfg.Node
  106. var wcclient nodepb.NodeServiceClient
  107. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  108. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  109. if err != nil {
  110. log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
  111. } else {
  112. wcclient = nodepb.NewNodeServiceClient(conn)
  113. ctx := context.Background()
  114. ctx, err = auth.SetJWT(wcclient, network)
  115. if err != nil {
  116. log.Printf("Failed to authenticate: %v", err)
  117. } else {
  118. if netclientutils.IsWindows() {
  119. local.RemoveWindowsConf(node.Interface)
  120. log.Println("removed Windows tunnel " + node.Interface)
  121. }
  122. node.SetID()
  123. var header metadata.MD
  124. _, err = wcclient.DeleteNode(
  125. ctx,
  126. &nodepb.Object{
  127. Data: node.ID,
  128. Type: nodepb.STRING_TYPE,
  129. },
  130. grpc.Header(&header),
  131. )
  132. if err != nil {
  133. log.Printf("Encountered error deleting node: %v", err)
  134. log.Println(err)
  135. } else {
  136. log.Println("Removed machine from " + node.Network + " network on remote server")
  137. }
  138. }
  139. }
  140. return RemoveLocalInstance(cfg, network)
  141. }
  142. func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
  143. err := local.WipeLocal(networkName)
  144. if err != nil {
  145. log.Printf("Unable to wipe local config: %v", err)
  146. } else {
  147. log.Println("Removed " + networkName + " network locally")
  148. }
  149. if cfg.Daemon != "off" {
  150. if netclientutils.IsWindows() {
  151. // TODO: Remove job?
  152. } else {
  153. err = local.RemoveSystemDServices(networkName)
  154. }
  155. }
  156. return err
  157. }
  158. func DeleteInterface(ifacename string, postdown string) error {
  159. var err error
  160. if netclientutils.IsWindows() {
  161. err = local.RemoveWindowsConf(ifacename)
  162. } else {
  163. ipExec, err := exec.LookPath("ip")
  164. if err != nil {
  165. log.Println(err)
  166. }
  167. out, err := local.RunCmd(ipExec + " link del " + ifacename)
  168. if err != nil {
  169. log.Println(out, err)
  170. }
  171. if postdown != "" {
  172. runcmds := strings.Split(postdown, "; ")
  173. err = local.RunCmds(runcmds)
  174. if err != nil {
  175. log.Println("Error encountered running PostDown: " + err.Error())
  176. }
  177. }
  178. }
  179. return err
  180. }
  181. func List() error {
  182. networks, err := GetNetworks()
  183. if err != nil {
  184. return err
  185. }
  186. for _, network := range networks {
  187. cfg, err := config.ReadConfig(network)
  188. if err == nil {
  189. jsoncfg, _ := json.Marshal(
  190. map[string]string{
  191. "Name": cfg.Node.Name,
  192. "Interface": cfg.Node.Interface,
  193. "PrivateIPv4": cfg.Node.Address,
  194. "PrivateIPv6": cfg.Node.Address6,
  195. "PublicEndpoint": cfg.Node.Endpoint,
  196. })
  197. log.Println(network + ": " + string(jsoncfg))
  198. } else {
  199. log.Println(network + ": Could not retrieve network configuration.")
  200. }
  201. }
  202. return nil
  203. }
  204. func GetNetworks() ([]string, error) {
  205. var networks []string
  206. files, err := ioutil.ReadDir(netclientutils.GetNetclientPath())
  207. if err != nil {
  208. return networks, err
  209. }
  210. for _, f := range files {
  211. if strings.Contains(f.Name(), "netconfig-") {
  212. networkname := stringAfter(f.Name(), "netconfig-")
  213. networks = append(networks, networkname)
  214. }
  215. }
  216. return networks, err
  217. }
  218. func stringAfter(original string, substring string) string {
  219. position := strings.LastIndex(original, substring)
  220. if position == -1 {
  221. return ""
  222. }
  223. adjustedPosition := position + len(substring)
  224. if adjustedPosition >= len(original) {
  225. return ""
  226. }
  227. return original[adjustedPosition:len(original)]
  228. }