TUN-3809: Allow routes ip show to output as JSON or YAML

It also fixes the marshelling of CIDR into JSON since otherwise
it would show garbled characters as the mask.
This commit is contained in:
Nuno Diegues 2021-01-26 11:58:56 +00:00
parent 2146f71b45
commit 6681d179dc
3 changed files with 33 additions and 10 deletions

View File

@ -41,7 +41,7 @@ func buildRouteIPSubcommand() *cli.Command {
Usage: "Show the routing table",
UsageText: "cloudflared tunnel [--config FILEPATH] route ip show [flags]",
Description: `Shows your organization's private route table. You can use flags to filter the results.`,
Flags: teamnet.FilterFlags,
Flags: showRoutesFlags(),
},
{
Name: "delete",
@ -62,6 +62,13 @@ func buildRouteIPSubcommand() *cli.Command {
}
}
func showRoutesFlags() []cli.Flag {
flags := make([]cli.Flag, 0)
flags = append(flags, teamnet.FilterFlags...)
flags = append(flags, outputFormatFlag)
return flags
}
func showRoutesCommand(c *cli.Context) error {
sc, err := newSubcommandContext(c)
if err != nil {

View File

@ -16,9 +16,9 @@ import (
// network, and says that eyeballs can reach that route using the corresponding
// tunnel.
type Route struct {
Network CIDR
Network CIDR `json:"network"`
TunnelID uuid.UUID `json:"tunnel_id"`
Comment string
Comment string `json:"comment"`
CreatedAt time.Time `json:"created_at"`
DeletedAt time.Time `json:"deleted_at"`
}
@ -26,11 +26,20 @@ type Route struct {
// CIDR is just a newtype wrapper around net.IPNet. It adds JSON unmarshalling.
type CIDR net.IPNet
func (c *CIDR) String() string {
n := net.IPNet(*c)
func (c CIDR) String() string {
n := net.IPNet(c)
return n.String()
}
func (c CIDR) MarshalJSON() ([]byte, error) {
str := c.String()
json, err := json.Marshal(str)
if err != nil {
return nil, errors.Wrap(err, "error serializing CIDR into JSON")
}
return json, nil
}
// UnmarshalJSON parses a JSON string into net.IPNet
func (c *CIDR) UnmarshalJSON(data []byte) error {
var s string
@ -68,9 +77,9 @@ func (r NewRoute) MarshalJSON() ([]byte, error) {
// DetailedRoute is just a Route with some extra fields, e.g. TunnelName.
type DetailedRoute struct {
Network CIDR
Network CIDR `json:"network"`
TunnelID uuid.UUID `json:"tunnel_id"`
Comment string
Comment string `json:"comment"`
CreatedAt time.Time `json:"created_at"`
DeletedAt time.Time `json:"deleted_at"`
TunnelName string `json:"tunnel_name"`

View File

@ -33,15 +33,15 @@ func TestUnmarshalRoute(t *testing.T) {
require.Equal(t, "test", r.Comment)
}
func TestUnmarshalDetailedRoute(t *testing.T) {
func TestDetailedRouteJsonRoundtrip(t *testing.T) {
// Response from the teamnet route backend
data := `{
"network":"10.1.2.40/29",
"tunnel_id":"fba6ffea-807f-4e7a-a740-4184ee1b82c8",
"tunnel_name":"Mr. Tun",
"comment":"test",
"created_at":"2020-12-22T02:00:15.587008Z",
"deleted_at":null
"deleted_at":"2021-01-14T05:01:42.183002Z",
"tunnel_name":"Mr. Tun"
}`
var r DetailedRoute
err := json.Unmarshal([]byte(data), &r)
@ -55,6 +55,13 @@ func TestUnmarshalDetailedRoute(t *testing.T) {
require.Equal(t, CIDR(*cidr), r.Network)
require.Equal(t, "test", r.Comment)
require.Equal(t, "Mr. Tun", r.TunnelName)
bytes, err := json.Marshal(r)
require.NoError(t, err)
obtainedJson := string(bytes)
data = strings.Replace(data, "\t", "", -1)
data = strings.Replace(data, "\n", "", -1)
require.Equal(t, data, obtainedJson)
}
func TestMarshalNewRoute(t *testing.T) {