common.go 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. package functions
  2. import (
  3. "fmt"
  4. "errors"
  5. "context"
  6. "net/http"
  7. "io/ioutil"
  8. "strings"
  9. "log"
  10. "net"
  11. "os"
  12. "os/exec"
  13. "github.com/gravitl/netmaker/netclient/config"
  14. "github.com/gravitl/netmaker/netclient/local"
  15. "github.com/gravitl/netmaker/netclient/auth"
  16. nodepb "github.com/gravitl/netmaker/grpc"
  17. "golang.zx2c4.com/wireguard/wgctrl"
  18. "google.golang.org/grpc"
  19. "google.golang.org/grpc/metadata"
  20. //homedir "github.com/mitchellh/go-homedir"
  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 GetFreePort(rangestart int32) (int32, error){
  41. wgclient, err := wgctrl.New()
  42. if err != nil {
  43. return 0, err
  44. }
  45. devices, err := wgclient.Devices()
  46. if err != nil {
  47. return 0, err
  48. }
  49. var portno int32
  50. portno = 0
  51. for x := rangestart; x <= 60000; x++ {
  52. conflict := false
  53. for _, i := range devices {
  54. if int32(i.ListenPort) == x {
  55. conflict = true
  56. break;
  57. }
  58. }
  59. if conflict {
  60. continue
  61. }
  62. portno = x
  63. break
  64. }
  65. return portno, err
  66. }
  67. func getLocalIP(localrange string) (string, error) {
  68. _, localRange, err := net.ParseCIDR(localrange)
  69. if err != nil {
  70. return "", err
  71. }
  72. ifaces, err := net.Interfaces()
  73. if err != nil {
  74. return "", err
  75. }
  76. var local string
  77. found := false
  78. for _, i := range ifaces {
  79. if i.Flags&net.FlagUp == 0 {
  80. continue // interface down
  81. }
  82. if i.Flags&net.FlagLoopback != 0 {
  83. continue // loopback interface
  84. }
  85. addrs, err := i.Addrs()
  86. if err != nil {
  87. return "", err
  88. }
  89. for _, addr := range addrs {
  90. var ip net.IP
  91. switch v := addr.(type) {
  92. case *net.IPNet:
  93. if !found {
  94. ip = v.IP
  95. local = ip.String()
  96. found = localRange.Contains(ip)
  97. }
  98. case *net.IPAddr:
  99. if !found {
  100. ip = v.IP
  101. local = ip.String()
  102. found = localRange.Contains(ip)
  103. }
  104. }
  105. }
  106. }
  107. if !found || local == "" {
  108. return "", errors.New("Failed to find local IP in range " + localrange)
  109. }
  110. return local, nil
  111. }
  112. func getPublicIP() (string, error) {
  113. iplist := []string{"http://ip.client.gravitl.com","https://ifconfig.me", "http://api.ipify.org", "http://ipinfo.io/ip"}
  114. endpoint := ""
  115. var err error
  116. for _, ipserver := range iplist {
  117. resp, err := http.Get(ipserver)
  118. if err != nil {
  119. continue
  120. }
  121. defer resp.Body.Close()
  122. if resp.StatusCode == http.StatusOK {
  123. bodyBytes, err := ioutil.ReadAll(resp.Body)
  124. if err != nil {
  125. continue
  126. }
  127. endpoint = string(bodyBytes)
  128. break
  129. }
  130. }
  131. if err == nil && endpoint == "" {
  132. err = errors.New("Public Address Not Found.")
  133. }
  134. return endpoint, err
  135. }
  136. func getMacAddr() ([]string, error) {
  137. ifas, err := net.Interfaces()
  138. if err != nil {
  139. return nil, err
  140. }
  141. var as []string
  142. for _, ifa := range ifas {
  143. a := ifa.HardwareAddr.String()
  144. if a != "" {
  145. as = append(as, a)
  146. }
  147. }
  148. return as, nil
  149. }
  150. func getPrivateAddr() (string, error) {
  151. ifaces, err := net.Interfaces()
  152. if err != nil {
  153. return "", err
  154. }
  155. var local string
  156. found := false
  157. for _, i := range ifaces {
  158. if i.Flags&net.FlagUp == 0 {
  159. continue // interface down
  160. }
  161. if i.Flags&net.FlagLoopback != 0 {
  162. continue // loopback interface
  163. }
  164. addrs, err := i.Addrs()
  165. if err != nil {
  166. return "", err
  167. }
  168. for _, addr := range addrs {
  169. var ip net.IP
  170. switch v := addr.(type) {
  171. case *net.IPNet:
  172. if !found {
  173. ip = v.IP
  174. local = ip.String()
  175. found = true
  176. }
  177. case *net.IPAddr:
  178. if !found {
  179. ip = v.IP
  180. local = ip.String()
  181. found = true
  182. }
  183. }
  184. }
  185. }
  186. if !found {
  187. err := errors.New("Local Address Not Found.")
  188. return "", err
  189. }
  190. return local, err
  191. }
  192. func needInterfaceUpdate(ctx context.Context, mac string, network string, iface string) (bool, string, error) {
  193. var header metadata.MD
  194. req := &nodepb.ReadNodeReq{
  195. Macaddress: mac,
  196. Network: network,
  197. }
  198. readres, err := wcclient.ReadNode(ctx, req, grpc.Header(&header))
  199. if err != nil {
  200. return false, "", err
  201. log.Fatalf("Error: %v", err)
  202. }
  203. oldiface := readres.Node.Interface
  204. return iface != oldiface, oldiface, err
  205. }
  206. func GetNode(network string) nodepb.Node {
  207. modcfg, err := config.ReadConfig(network)
  208. if err != nil {
  209. log.Fatalf("Error: %v", err)
  210. }
  211. nodecfg := modcfg.Node
  212. var node nodepb.Node
  213. node.Name = nodecfg.Name
  214. node.Interface = nodecfg.Interface
  215. node.Nodenetwork = nodecfg.Network
  216. node.Localaddress = nodecfg.LocalAddress
  217. node.Address = nodecfg.WGAddress
  218. node.Address6 = nodecfg.WGAddress6
  219. node.Listenport = nodecfg.Port
  220. node.Keepalive = nodecfg.KeepAlive
  221. node.Postup = nodecfg.PostUp
  222. node.Postdown = nodecfg.PostDown
  223. node.Publickey = nodecfg.PublicKey
  224. node.Macaddress = nodecfg.MacAddress
  225. node.Endpoint = nodecfg.Endpoint
  226. node.Password = nodecfg.Password
  227. if nodecfg.DNS == "on" {
  228. node.Dnsoff = true
  229. } else {
  230. node.Dnsoff = false
  231. }
  232. if nodecfg.IsDualStack == "yes" {
  233. node.Isdualstack = true
  234. } else {
  235. node.Isdualstack = false
  236. }
  237. if nodecfg.IsIngressGateway == "yes" {
  238. node.Isingressgateway = true
  239. } else {
  240. node.Isingressgateway = false
  241. }
  242. return node
  243. }
  244. func LeaveNetwork(network string) error {
  245. //need to implement checkin on server side
  246. cfg, err := config.ReadConfig(network)
  247. if err != nil {
  248. return err
  249. }
  250. servercfg := cfg.Server
  251. node := cfg.Node
  252. var wcclient nodepb.NodeServiceClient
  253. var requestOpts grpc.DialOption
  254. requestOpts = grpc.WithInsecure()
  255. conn, err := grpc.Dial(servercfg.GRPCAddress, requestOpts)
  256. if err != nil {
  257. log.Printf("Unable to establish client connection to " + servercfg.GRPCAddress + ": %v", err)
  258. }else {
  259. wcclient = nodepb.NewNodeServiceClient(conn)
  260. ctx := context.Background()
  261. ctx, err = auth.SetJWT(wcclient, network)
  262. if err != nil {
  263. log.Printf("Failed to authenticate: %v", err)
  264. } else {
  265. var header metadata.MD
  266. _, err = wcclient.DeleteNode(
  267. ctx,
  268. &nodepb.DeleteNodeReq{
  269. Macaddress: node.MacAddress,
  270. NetworkName: node.Network,
  271. },
  272. grpc.Header(&header),
  273. )
  274. if err != nil {
  275. log.Printf("Encountered error deleting node: %v", err)
  276. fmt.Println(err)
  277. } else {
  278. fmt.Println("delete node " + node.MacAddress + "from remote server on network " + node.Network)
  279. }
  280. }
  281. }
  282. err = local.WipeLocal(network)
  283. if err != nil {
  284. log.Printf("Unable to wipe local config: %v", err)
  285. }
  286. err = local.RemoveSystemDServices(network)
  287. return err
  288. }
  289. func DeleteInterface(ifacename string, postdown string) error{
  290. ipExec, err := exec.LookPath("ip")
  291. cmdIPLinkDel := &exec.Cmd {
  292. Path: ipExec,
  293. Args: []string{ ipExec, "link", "del", ifacename },
  294. Stdout: os.Stdout,
  295. Stderr: os.Stdout,
  296. }
  297. err = cmdIPLinkDel.Run()
  298. if err != nil {
  299. fmt.Println(err)
  300. }
  301. if postdown != "" {
  302. runcmds := strings.Split(postdown, "; ")
  303. err = local.RunCmds(runcmds)
  304. if err != nil {
  305. fmt.Println("Error encountered running PostDown: " + err.Error())
  306. }
  307. }
  308. return err
  309. }