common.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249
  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.CleanupWindows()
  95. } else if netclientutils.IsWindows() {
  96. local.CleanupMac()
  97. }
  98. return err
  99. }
  100. func LeaveNetwork(network string) error {
  101. //need to implement checkin on server side
  102. cfg, err := config.ReadConfig(network)
  103. if err != nil {
  104. return err
  105. }
  106. servercfg := cfg.Server
  107. node := cfg.Node
  108. var wcclient nodepb.NodeServiceClient
  109. conn, err := grpc.Dial(cfg.Server.GRPCAddress,
  110. netclientutils.GRPCRequestOpts(cfg.Server.GRPCSSL))
  111. if err != nil {
  112. log.Printf("Unable to establish client connection to "+servercfg.GRPCAddress+": %v", err)
  113. } else {
  114. wcclient = nodepb.NewNodeServiceClient(conn)
  115. ctx := context.Background()
  116. ctx, err = auth.SetJWT(wcclient, network)
  117. if err != nil {
  118. log.Printf("Failed to authenticate: %v", err)
  119. } else {
  120. if netclientutils.IsWindows() {
  121. local.RemoveWindowsConf(node.Interface)
  122. log.Println("removed Windows tunnel " + node.Interface)
  123. }
  124. node.SetID()
  125. var header metadata.MD
  126. _, err = wcclient.DeleteNode(
  127. ctx,
  128. &nodepb.Object{
  129. Data: node.ID,
  130. Type: nodepb.STRING_TYPE,
  131. },
  132. grpc.Header(&header),
  133. )
  134. if err != nil {
  135. log.Printf("Encountered error deleting node: %v", err)
  136. log.Println(err)
  137. } else {
  138. log.Println("Removed machine from " + node.Network + " network on remote server")
  139. }
  140. }
  141. }
  142. return RemoveLocalInstance(cfg, network)
  143. }
  144. func RemoveLocalInstance(cfg *config.ClientConfig, networkName string) error {
  145. err := local.WipeLocal(networkName)
  146. if err != nil {
  147. log.Printf("Unable to wipe local config: %v", err)
  148. } else {
  149. log.Println("Removed " + networkName + " network locally")
  150. }
  151. if cfg.Daemon != "off" {
  152. if netclientutils.IsWindows() {
  153. // TODO: Remove job?
  154. } else {
  155. err = local.RemoveSystemDServices(networkName)
  156. }
  157. }
  158. return err
  159. }
  160. func DeleteInterface(ifacename string, postdown string) error {
  161. var err error
  162. if netclientutils.IsWindows() {
  163. err = local.RemoveWindowsConf(ifacename)
  164. } else {
  165. ipExec, errN := exec.LookPath("ip")
  166. err = errN
  167. if err != nil {
  168. log.Println(err)
  169. }
  170. _, err = local.RunCmd(ipExec+" link del "+ifacename, false)
  171. if postdown != "" {
  172. runcmds := strings.Split(postdown, "; ")
  173. err = local.RunCmds(runcmds, true)
  174. }
  175. }
  176. return err
  177. }
  178. func List() error {
  179. networks, err := GetNetworks()
  180. if err != nil {
  181. return err
  182. }
  183. for _, network := range networks {
  184. cfg, err := config.ReadConfig(network)
  185. if err == nil {
  186. jsoncfg, _ := json.Marshal(
  187. map[string]string{
  188. "Name": cfg.Node.Name,
  189. "Interface": cfg.Node.Interface,
  190. "PrivateIPv4": cfg.Node.Address,
  191. "PrivateIPv6": cfg.Node.Address6,
  192. "PublicEndpoint": cfg.Node.Endpoint,
  193. })
  194. log.Println(network + ": " + string(jsoncfg))
  195. } else {
  196. log.Println(network + ": Could not retrieve network configuration.")
  197. }
  198. }
  199. return nil
  200. }
  201. func GetNetworks() ([]string, error) {
  202. var networks []string
  203. files, err := ioutil.ReadDir(netclientutils.GetNetclientPath())
  204. if err != nil {
  205. return networks, err
  206. }
  207. for _, f := range files {
  208. if strings.Contains(f.Name(), "netconfig-") {
  209. networkname := stringAfter(f.Name(), "netconfig-")
  210. networks = append(networks, networkname)
  211. }
  212. }
  213. return networks, err
  214. }
  215. func stringAfter(original string, substring string) string {
  216. position := strings.LastIndex(original, substring)
  217. if position == -1 {
  218. return ""
  219. }
  220. adjustedPosition := position + len(substring)
  221. if adjustedPosition >= len(original) {
  222. return ""
  223. }
  224. return original[adjustedPosition:len(original)]
  225. }