1
0

net.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "github.com/Sirupsen/logrus"
  7. "github.com/asaskevich/govalidator"
  8. "github.com/cad/ovpm"
  9. "github.com/cad/ovpm/pb"
  10. "github.com/olekukonko/tablewriter"
  11. "github.com/urfave/cli"
  12. )
  13. var netDefineCommand = cli.Command{
  14. Name: "def",
  15. Aliases: []string{"d"},
  16. Usage: "Define a network.",
  17. Flags: []cli.Flag{
  18. cli.StringFlag{
  19. Name: "cidr, c",
  20. Usage: "CIDR of the network",
  21. },
  22. cli.StringFlag{
  23. Name: "name, n",
  24. Usage: "name of the network",
  25. },
  26. cli.StringFlag{
  27. Name: "type, t",
  28. Usage: "type of the network (see $ovpm net types)",
  29. },
  30. cli.StringFlag{
  31. Name: "via, v",
  32. Usage: "if network type is route, via represents route's gateway",
  33. },
  34. },
  35. Action: func(c *cli.Context) error {
  36. action = "net:create"
  37. name := c.String("name")
  38. cidr := c.String("cidr")
  39. typ := c.String("type")
  40. via := c.String("via")
  41. if name == "" || cidr == "" || typ == "" {
  42. fmt.Println(cli.ShowSubcommandHelp(c))
  43. os.Exit(1)
  44. }
  45. switch ovpm.NetworkTypeFromString(typ) {
  46. case ovpm.ROUTE:
  47. if via != "" && !govalidator.IsIPv4(via) {
  48. fmt.Printf("validation error: `%s` must be a network in the IPv4 form", via)
  49. fmt.Println()
  50. fmt.Println(cli.ShowSubcommandHelp(c))
  51. os.Exit(1)
  52. }
  53. case ovpm.SERVERNET:
  54. if via != "" {
  55. fmt.Println("--via flag can only be used with --type ROUTE")
  56. fmt.Println()
  57. fmt.Println(cli.ShowSubcommandHelp(c))
  58. os.Exit(1)
  59. }
  60. default: // Means UNDEFINEDNET
  61. fmt.Printf("undefined network type %s", typ)
  62. fmt.Println()
  63. fmt.Println("Network Types:")
  64. fmt.Println(" ", ovpm.GetAllNetworkTypes())
  65. fmt.Println()
  66. fmt.Println(cli.ShowSubcommandHelp(c))
  67. os.Exit(1)
  68. }
  69. conn := getConn(c.GlobalString("daemon-port"))
  70. defer conn.Close()
  71. netSvc := pb.NewNetworkServiceClient(conn)
  72. response, err := netSvc.Create(context.Background(), &pb.NetworkCreateRequest{Name: name, CIDR: cidr, Type: typ, Via: via})
  73. if err != nil {
  74. logrus.Errorf("network can not be created '%s': %v", name, err)
  75. os.Exit(1)
  76. return err
  77. }
  78. logrus.Infof("network created: %s (%s)", response.Network.Name, response.Network.CIDR)
  79. return nil
  80. },
  81. }
  82. var netListCommand = cli.Command{
  83. Name: "list",
  84. Aliases: []string{"l"},
  85. Usage: "List defined networks.",
  86. Action: func(c *cli.Context) error {
  87. action = "net:list"
  88. conn := getConn(c.GlobalString("daemon-port"))
  89. defer conn.Close()
  90. netSvc := pb.NewNetworkServiceClient(conn)
  91. resp, err := netSvc.List(context.Background(), &pb.NetworkListRequest{})
  92. if err != nil {
  93. logrus.Errorf("networks can not be fetched: %v", err)
  94. os.Exit(1)
  95. return err
  96. }
  97. table := tablewriter.NewWriter(os.Stdout)
  98. table.SetHeader([]string{"#", "name", "cidr", "type", "assoc", "created at"})
  99. //table.SetBorder(false)
  100. for i, network := range resp.Networks {
  101. // Create associated user list for this network.
  102. var usernameList string
  103. assocUsers, err := netSvc.GetAssociatedUsers(context.Background(), &pb.NetworkGetAssociatedUsersRequest{Name: network.Name})
  104. if err != nil {
  105. logrus.Errorf("assoc users can not be fetched: %v", err)
  106. os.Exit(1)
  107. return err
  108. }
  109. usernames := assocUsers.Usernames
  110. count := len(usernames)
  111. for i, uname := range usernames {
  112. if i+1 == count {
  113. usernameList = usernameList + fmt.Sprintf("%s", uname)
  114. } else {
  115. usernameList = usernameList + fmt.Sprintf("%s, ", uname)
  116. }
  117. }
  118. var cidr = network.CIDR
  119. var via = network.Via
  120. if via == "" {
  121. via = "vpn-server"
  122. }
  123. if ovpm.NetworkTypeFromString(network.Type) == ovpm.ROUTE {
  124. cidr = fmt.Sprintf("%s via %s", network.CIDR, via)
  125. }
  126. data := []string{fmt.Sprintf("%v", i+1), network.Name, cidr, network.Type, usernameList, network.CreatedAt}
  127. table.Append(data)
  128. }
  129. table.Render()
  130. return nil
  131. },
  132. }
  133. var netTypesCommand = cli.Command{
  134. Name: "types",
  135. Aliases: []string{"t"},
  136. Usage: "Show available network types.",
  137. Action: func(c *cli.Context) error {
  138. action = "net:types"
  139. conn := getConn(c.GlobalString("daemon-port"))
  140. defer conn.Close()
  141. netSvc := pb.NewNetworkServiceClient(conn)
  142. resp, err := netSvc.GetAllTypes(context.Background(), &pb.NetworkGetAllTypesRequest{})
  143. if err != nil {
  144. logrus.Errorf("networks can not be fetched: %v", err)
  145. os.Exit(1)
  146. return err
  147. }
  148. table := tablewriter.NewWriter(os.Stdout)
  149. table.SetHeader([]string{"#", "net type", "desc"})
  150. //table.SetBorder(false)
  151. for i, ntype := range resp.Types {
  152. data := []string{fmt.Sprintf("%v", i+1), ntype.Type, ntype.Description}
  153. table.Append(data)
  154. }
  155. table.Render()
  156. return nil
  157. },
  158. }
  159. var netUndefineCommand = cli.Command{
  160. Name: "undef",
  161. Aliases: []string{"u"},
  162. Usage: "Undefine an existing network.",
  163. Flags: []cli.Flag{
  164. cli.StringFlag{
  165. Name: "net, n",
  166. Usage: "name of the network",
  167. },
  168. },
  169. Action: func(c *cli.Context) error {
  170. action = "net:delete"
  171. name := c.String("net")
  172. if name == "" {
  173. fmt.Println(cli.ShowSubcommandHelp(c))
  174. os.Exit(1)
  175. }
  176. conn := getConn(c.GlobalString("daemon-port"))
  177. defer conn.Close()
  178. netSvc := pb.NewNetworkServiceClient(conn)
  179. resp, err := netSvc.Delete(context.Background(), &pb.NetworkDeleteRequest{Name: name})
  180. if err != nil {
  181. logrus.Errorf("networks can not be deleted: %v", err)
  182. os.Exit(1)
  183. return err
  184. }
  185. logrus.Infof("network deleted: %s (%s)", resp.Network.Name, resp.Network.CIDR)
  186. return nil
  187. },
  188. }
  189. var netAssociateCommand = cli.Command{
  190. Name: "assoc",
  191. Aliases: []string{"a"},
  192. Usage: "Associate a user with a network.",
  193. Flags: []cli.Flag{
  194. cli.StringFlag{
  195. Name: "net, n",
  196. Usage: "name of the network",
  197. },
  198. cli.StringFlag{
  199. Name: "user, u",
  200. Usage: "name of the user",
  201. },
  202. },
  203. Action: func(c *cli.Context) error {
  204. action = "net:associate"
  205. netName := c.String("net")
  206. userName := c.String("user")
  207. if netName == "" || userName == "" {
  208. fmt.Println(cli.ShowSubcommandHelp(c))
  209. os.Exit(1)
  210. }
  211. conn := getConn(c.GlobalString("daemon-port"))
  212. defer conn.Close()
  213. netSvc := pb.NewNetworkServiceClient(conn)
  214. _, err := netSvc.Associate(context.Background(), &pb.NetworkAssociateRequest{Name: netName, Username: userName})
  215. if err != nil {
  216. logrus.Errorf("networks can not be associated: %v", err)
  217. os.Exit(1)
  218. return err
  219. }
  220. logrus.Infof("network associated: user:%s <-> network:%s", userName, netName)
  221. return nil
  222. },
  223. }
  224. var netDissociateCommand = cli.Command{
  225. Name: "dissoc",
  226. Aliases: []string{"di"},
  227. Usage: "Dissociate a user from a network.",
  228. Flags: []cli.Flag{
  229. cli.StringFlag{
  230. Name: "net, n",
  231. Usage: "name of the network",
  232. },
  233. cli.StringFlag{
  234. Name: "user, u",
  235. Usage: "name of the user",
  236. },
  237. },
  238. Action: func(c *cli.Context) error {
  239. action = "net:dissociate"
  240. netName := c.String("net")
  241. userName := c.String("user")
  242. if netName == "" || userName == "" {
  243. fmt.Println(cli.ShowSubcommandHelp(c))
  244. os.Exit(1)
  245. }
  246. conn := getConn(c.GlobalString("daemon-port"))
  247. defer conn.Close()
  248. netSvc := pb.NewNetworkServiceClient(conn)
  249. _, err := netSvc.Dissociate(context.Background(), &pb.NetworkDissociateRequest{Name: netName, Username: userName})
  250. if err != nil {
  251. logrus.Errorf("networks can not be dissociated: %v", err)
  252. os.Exit(1)
  253. return err
  254. }
  255. logrus.Infof("network dissociated: user:%s <-> network:%s", userName, netName)
  256. return nil
  257. },
  258. }