2020-12-22 02:06:46 +00:00
|
|
|
package tunnelstore
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
2020-12-29 17:51:42 +00:00
|
|
|
"net"
|
2020-12-22 02:06:46 +00:00
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"path"
|
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
2021-03-23 14:30:43 +00:00
|
|
|
|
|
|
|
"github.com/cloudflare/cloudflared/teamnet"
|
2020-12-22 02:06:46 +00:00
|
|
|
)
|
|
|
|
|
2020-12-29 17:51:42 +00:00
|
|
|
// ListRoutes calls the Tunnelstore GET endpoint for all routes under an account.
|
2021-01-05 23:55:18 +00:00
|
|
|
func (r *RESTClient) ListRoutes(filter *teamnet.Filter) ([]*teamnet.DetailedRoute, error) {
|
2020-12-22 02:06:46 +00:00
|
|
|
endpoint := r.baseEndpoints.accountRoutes
|
|
|
|
endpoint.RawQuery = filter.Encode()
|
|
|
|
resp, err := r.sendRequest("GET", endpoint, nil)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "REST request failed")
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusOK {
|
2021-01-05 23:55:18 +00:00
|
|
|
return parseListDetailedRoutes(resp.Body)
|
2020-12-22 02:06:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return nil, r.statusCodeToError("list routes", resp)
|
|
|
|
}
|
|
|
|
|
2020-12-29 17:51:42 +00:00
|
|
|
// AddRoute calls the Tunnelstore POST endpoint for a given route.
|
2020-12-22 02:06:46 +00:00
|
|
|
func (r *RESTClient) AddRoute(newRoute teamnet.NewRoute) (teamnet.Route, error) {
|
|
|
|
endpoint := r.baseEndpoints.accountRoutes
|
2021-01-06 23:54:51 +00:00
|
|
|
endpoint.Path = path.Join(endpoint.Path, "network", url.PathEscape(newRoute.Network.String()))
|
2020-12-22 02:06:46 +00:00
|
|
|
resp, err := r.sendRequest("POST", endpoint, newRoute)
|
|
|
|
if err != nil {
|
|
|
|
return teamnet.Route{}, errors.Wrap(err, "REST request failed")
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusOK {
|
|
|
|
return parseRoute(resp.Body)
|
|
|
|
}
|
|
|
|
|
|
|
|
return teamnet.Route{}, r.statusCodeToError("add route", resp)
|
|
|
|
}
|
|
|
|
|
2020-12-29 17:51:42 +00:00
|
|
|
// DeleteRoute calls the Tunnelstore DELETE endpoint for a given route.
|
|
|
|
func (r *RESTClient) DeleteRoute(network net.IPNet) error {
|
|
|
|
endpoint := r.baseEndpoints.accountRoutes
|
2021-01-06 23:54:51 +00:00
|
|
|
endpoint.Path = path.Join(endpoint.Path, "network", url.PathEscape(network.String()))
|
2020-12-29 17:51:42 +00:00
|
|
|
resp, err := r.sendRequest("DELETE", endpoint, nil)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "REST request failed")
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusOK {
|
|
|
|
_, err := parseRoute(resp.Body)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
return r.statusCodeToError("delete route", resp)
|
|
|
|
}
|
|
|
|
|
2021-01-05 23:55:18 +00:00
|
|
|
// GetByIP checks which route will proxy a given IP.
|
|
|
|
func (r *RESTClient) GetByIP(ip net.IP) (teamnet.DetailedRoute, error) {
|
|
|
|
endpoint := r.baseEndpoints.accountRoutes
|
|
|
|
endpoint.Path = path.Join(endpoint.Path, "ip", url.PathEscape(ip.String()))
|
|
|
|
resp, err := r.sendRequest("GET", endpoint, nil)
|
|
|
|
if err != nil {
|
|
|
|
return teamnet.DetailedRoute{}, errors.Wrap(err, "REST request failed")
|
|
|
|
}
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
if resp.StatusCode == http.StatusOK {
|
|
|
|
return parseDetailedRoute(resp.Body)
|
|
|
|
}
|
|
|
|
|
|
|
|
return teamnet.DetailedRoute{}, r.statusCodeToError("get route by IP", resp)
|
|
|
|
}
|
|
|
|
|
|
|
|
func parseListDetailedRoutes(body io.ReadCloser) ([]*teamnet.DetailedRoute, error) {
|
|
|
|
var routes []*teamnet.DetailedRoute
|
|
|
|
err := parseResponse(body, &routes)
|
|
|
|
return routes, err
|
|
|
|
}
|
|
|
|
|
2020-12-22 02:06:46 +00:00
|
|
|
func parseRoute(body io.ReadCloser) (teamnet.Route, error) {
|
|
|
|
var route teamnet.Route
|
|
|
|
err := parseResponse(body, &route)
|
|
|
|
return route, err
|
|
|
|
}
|
2021-01-05 23:55:18 +00:00
|
|
|
|
|
|
|
func parseDetailedRoute(body io.ReadCloser) (teamnet.DetailedRoute, error) {
|
|
|
|
var route teamnet.DetailedRoute
|
|
|
|
err := parseResponse(body, &route)
|
|
|
|
return route, err
|
|
|
|
}
|