client_teamnet.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. package tunnelstore
  2. import (
  3. "io"
  4. "net"
  5. "net/http"
  6. "net/url"
  7. "path"
  8. "github.com/cloudflare/cloudflared/teamnet"
  9. "github.com/pkg/errors"
  10. )
  11. // ListRoutes calls the Tunnelstore GET endpoint for all routes under an account.
  12. func (r *RESTClient) ListRoutes(filter *teamnet.Filter) ([]*teamnet.DetailedRoute, error) {
  13. endpoint := r.baseEndpoints.accountRoutes
  14. endpoint.RawQuery = filter.Encode()
  15. resp, err := r.sendRequest("GET", endpoint, nil)
  16. if err != nil {
  17. return nil, errors.Wrap(err, "REST request failed")
  18. }
  19. defer resp.Body.Close()
  20. if resp.StatusCode == http.StatusOK {
  21. return parseListDetailedRoutes(resp.Body)
  22. }
  23. return nil, r.statusCodeToError("list routes", resp)
  24. }
  25. // AddRoute calls the Tunnelstore POST endpoint for a given route.
  26. func (r *RESTClient) AddRoute(newRoute teamnet.NewRoute) (teamnet.Route, error) {
  27. endpoint := r.baseEndpoints.accountRoutes
  28. endpoint.Path = path.Join(endpoint.Path, "network", url.PathEscape(newRoute.Network.String()))
  29. resp, err := r.sendRequest("POST", endpoint, newRoute)
  30. if err != nil {
  31. return teamnet.Route{}, errors.Wrap(err, "REST request failed")
  32. }
  33. defer resp.Body.Close()
  34. if resp.StatusCode == http.StatusOK {
  35. return parseRoute(resp.Body)
  36. }
  37. return teamnet.Route{}, r.statusCodeToError("add route", resp)
  38. }
  39. // DeleteRoute calls the Tunnelstore DELETE endpoint for a given route.
  40. func (r *RESTClient) DeleteRoute(network net.IPNet) error {
  41. endpoint := r.baseEndpoints.accountRoutes
  42. endpoint.Path = path.Join(endpoint.Path, "network", url.PathEscape(network.String()))
  43. resp, err := r.sendRequest("DELETE", endpoint, nil)
  44. if err != nil {
  45. return errors.Wrap(err, "REST request failed")
  46. }
  47. defer resp.Body.Close()
  48. if resp.StatusCode == http.StatusOK {
  49. _, err := parseRoute(resp.Body)
  50. return err
  51. }
  52. return r.statusCodeToError("delete route", resp)
  53. }
  54. // GetByIP checks which route will proxy a given IP.
  55. func (r *RESTClient) GetByIP(ip net.IP) (teamnet.DetailedRoute, error) {
  56. endpoint := r.baseEndpoints.accountRoutes
  57. endpoint.Path = path.Join(endpoint.Path, "ip", url.PathEscape(ip.String()))
  58. resp, err := r.sendRequest("GET", endpoint, nil)
  59. if err != nil {
  60. return teamnet.DetailedRoute{}, errors.Wrap(err, "REST request failed")
  61. }
  62. defer resp.Body.Close()
  63. if resp.StatusCode == http.StatusOK {
  64. return parseDetailedRoute(resp.Body)
  65. }
  66. return teamnet.DetailedRoute{}, r.statusCodeToError("get route by IP", resp)
  67. }
  68. func parseListRoutes(body io.ReadCloser) ([]*teamnet.Route, error) {
  69. var routes []*teamnet.Route
  70. err := parseResponse(body, &routes)
  71. return routes, err
  72. }
  73. func parseListDetailedRoutes(body io.ReadCloser) ([]*teamnet.DetailedRoute, error) {
  74. var routes []*teamnet.DetailedRoute
  75. err := parseResponse(body, &routes)
  76. return routes, err
  77. }
  78. func parseRoute(body io.ReadCloser) (teamnet.Route, error) {
  79. var route teamnet.Route
  80. err := parseResponse(body, &route)
  81. return route, err
  82. }
  83. func parseDetailedRoute(body io.ReadCloser) (teamnet.DetailedRoute, error) {
  84. var route teamnet.DetailedRoute
  85. err := parseResponse(body, &route)
  86. return route, err
  87. }