mirror of
https://github.com/cloudflare/cloudflared
synced 2026-06-08 13:33:07 +00:00
6681d179dc
It also fixes the marshelling of CIDR into JSON since otherwise it would show garbled characters as the mask.
110 lines
2.8 KiB
Go
110 lines
2.8 KiB
Go
package teamnet
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"net"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// Route is a mapping from customer's IP space to a tunnel.
|
|
// Each route allows the customer to route eyeballs in their corporate network
|
|
// to certain private IP ranges. Each Route represents an IP range in their
|
|
// network, and says that eyeballs can reach that route using the corresponding
|
|
// tunnel.
|
|
type Route struct {
|
|
Network CIDR `json:"network"`
|
|
TunnelID uuid.UUID `json:"tunnel_id"`
|
|
Comment string `json:"comment"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
DeletedAt time.Time `json:"deleted_at"`
|
|
}
|
|
|
|
// 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)
|
|
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
|
|
if err := json.Unmarshal(data, &s); err != nil {
|
|
return errors.Wrap(err, "error parsing cidr string")
|
|
}
|
|
_, network, err := net.ParseCIDR(s)
|
|
if err != nil {
|
|
return errors.Wrap(err, "error parsing invalid network from backend")
|
|
}
|
|
if network == nil {
|
|
return fmt.Errorf("backend returned invalid network %s", s)
|
|
}
|
|
*c = CIDR(*network)
|
|
return nil
|
|
}
|
|
|
|
// NewRoute has all the parameters necessary to add a new route to the table.
|
|
type NewRoute struct {
|
|
Network net.IPNet
|
|
TunnelID uuid.UUID
|
|
Comment string
|
|
}
|
|
|
|
// MarshalJSON handles fields with non-JSON types (e.g. net.IPNet).
|
|
func (r NewRoute) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(&struct {
|
|
TunnelID uuid.UUID `json:"tunnel_id"`
|
|
Comment string `json:"comment"`
|
|
}{
|
|
TunnelID: r.TunnelID,
|
|
Comment: r.Comment,
|
|
})
|
|
}
|
|
|
|
// DetailedRoute is just a Route with some extra fields, e.g. TunnelName.
|
|
type DetailedRoute struct {
|
|
Network CIDR `json:"network"`
|
|
TunnelID uuid.UUID `json:"tunnel_id"`
|
|
Comment string `json:"comment"`
|
|
CreatedAt time.Time `json:"created_at"`
|
|
DeletedAt time.Time `json:"deleted_at"`
|
|
TunnelName string `json:"tunnel_name"`
|
|
}
|
|
|
|
// IsZero checks if DetailedRoute is the zero value.
|
|
func (r *DetailedRoute) IsZero() bool {
|
|
return r.TunnelID == uuid.Nil
|
|
}
|
|
|
|
// TableString outputs a table row summarizing the route, to be used
|
|
// when showing the user their routing table.
|
|
func (r DetailedRoute) TableString() string {
|
|
deletedColumn := "-"
|
|
if !r.DeletedAt.IsZero() {
|
|
deletedColumn = r.DeletedAt.Format(time.RFC3339)
|
|
}
|
|
return fmt.Sprintf(
|
|
"%s\t%s\t%s\t%s\t%s\t%s\t",
|
|
r.Network.String(),
|
|
r.Comment,
|
|
r.TunnelID,
|
|
r.TunnelName,
|
|
r.CreatedAt.Format(time.RFC3339),
|
|
deletedColumn,
|
|
)
|
|
}
|