166 lines
4.1 KiB
Go
166 lines
4.1 KiB
Go
package cfapi
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"net/url"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/pkg/errors"
|
|
"github.com/urfave/cli/v2"
|
|
)
|
|
|
|
var (
|
|
filterIpRouteDeleted = cli.BoolFlag{
|
|
Name: "filter-is-deleted",
|
|
Usage: "If false (default), only show non-deleted routes. If true, only show deleted routes.",
|
|
}
|
|
filterIpRouteTunnelID = cli.StringFlag{
|
|
Name: "filter-tunnel-id",
|
|
Usage: "Show only routes with the given tunnel ID.",
|
|
}
|
|
filterSubsetIpRoute = cli.StringFlag{
|
|
Name: "filter-network-is-subset-of",
|
|
Aliases: []string{"nsub"},
|
|
Usage: "Show only routes whose network is a subset of the given network.",
|
|
}
|
|
filterSupersetIpRoute = cli.StringFlag{
|
|
Name: "filter-network-is-superset-of",
|
|
Aliases: []string{"nsup"},
|
|
Usage: "Show only routes whose network is a superset of the given network.",
|
|
}
|
|
filterIpRouteComment = cli.StringFlag{
|
|
Name: "filter-comment-is",
|
|
Usage: "Show only routes with this comment.",
|
|
}
|
|
filterIpRouteByVnet = cli.StringFlag{
|
|
Name: "filter-vnet-id",
|
|
Usage: "Show only routes that are attached to the given virtual network ID.",
|
|
}
|
|
|
|
// Flags contains all filter flags.
|
|
IpRouteFilterFlags = []cli.Flag{
|
|
&filterIpRouteDeleted,
|
|
&filterIpRouteTunnelID,
|
|
&filterSubsetIpRoute,
|
|
&filterSupersetIpRoute,
|
|
&filterIpRouteComment,
|
|
&filterIpRouteByVnet,
|
|
}
|
|
)
|
|
|
|
// IpRouteFilter which routes get queried.
|
|
type IpRouteFilter struct {
|
|
queryParams url.Values
|
|
}
|
|
|
|
// NewIpRouteFilterFromCLI parses CLI flags to discover which filters should get applied.
|
|
func NewIpRouteFilterFromCLI(c *cli.Context) (*IpRouteFilter, error) {
|
|
f := &IpRouteFilter{
|
|
queryParams: url.Values{},
|
|
}
|
|
|
|
// Set deletion filter
|
|
if flag := filterIpRouteDeleted.Name; c.IsSet(flag) && c.Bool(flag) {
|
|
f.deleted()
|
|
} else {
|
|
f.notDeleted()
|
|
}
|
|
|
|
if subset, err := cidrFromFlag(c, filterSubsetIpRoute); err != nil {
|
|
return nil, err
|
|
} else if subset != nil {
|
|
f.networkIsSupersetOf(*subset)
|
|
}
|
|
|
|
if superset, err := cidrFromFlag(c, filterSupersetIpRoute); err != nil {
|
|
return nil, err
|
|
} else if superset != nil {
|
|
f.networkIsSupersetOf(*superset)
|
|
}
|
|
|
|
if comment := c.String(filterIpRouteComment.Name); comment != "" {
|
|
f.commentIs(comment)
|
|
}
|
|
|
|
if tunnelID := c.String(filterIpRouteTunnelID.Name); tunnelID != "" {
|
|
u, err := uuid.Parse(tunnelID)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "Couldn't parse UUID from %s", filterIpRouteTunnelID.Name)
|
|
}
|
|
f.tunnelID(u)
|
|
}
|
|
|
|
if vnetId := c.String(filterIpRouteByVnet.Name); vnetId != "" {
|
|
u, err := uuid.Parse(vnetId)
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "Couldn't parse UUID from %s", filterIpRouteByVnet.Name)
|
|
}
|
|
f.vnetID(u)
|
|
}
|
|
|
|
if maxFetch := c.Int("max-fetch-size"); maxFetch > 0 {
|
|
f.MaxFetchSize(uint(maxFetch))
|
|
}
|
|
|
|
return f, nil
|
|
}
|
|
|
|
// Parses a CIDR from the flag. If the flag was unset, returns (nil, nil).
|
|
func cidrFromFlag(c *cli.Context, flag cli.StringFlag) (*net.IPNet, error) {
|
|
if !c.IsSet(flag.Name) {
|
|
return nil, nil
|
|
}
|
|
|
|
_, subset, err := net.ParseCIDR(c.String(flag.Name))
|
|
if err != nil {
|
|
return nil, err
|
|
} else if subset == nil {
|
|
return nil, fmt.Errorf("Invalid CIDR supplied for %s", flag.Name)
|
|
}
|
|
|
|
return subset, nil
|
|
}
|
|
|
|
func (f *IpRouteFilter) commentIs(comment string) {
|
|
f.queryParams.Set("comment", comment)
|
|
}
|
|
|
|
func (f *IpRouteFilter) notDeleted() {
|
|
f.queryParams.Set("is_deleted", "false")
|
|
}
|
|
|
|
func (f *IpRouteFilter) deleted() {
|
|
f.queryParams.Set("is_deleted", "true")
|
|
}
|
|
|
|
func (f *IpRouteFilter) networkIsSubsetOf(superset net.IPNet) {
|
|
f.queryParams.Set("network_subset", superset.String())
|
|
}
|
|
|
|
func (f *IpRouteFilter) networkIsSupersetOf(subset net.IPNet) {
|
|
f.queryParams.Set("network_superset", subset.String())
|
|
}
|
|
|
|
func (f *IpRouteFilter) existedAt(existedAt time.Time) {
|
|
f.queryParams.Set("existed_at", existedAt.Format(time.RFC3339))
|
|
}
|
|
|
|
func (f *IpRouteFilter) tunnelID(id uuid.UUID) {
|
|
f.queryParams.Set("tunnel_id", id.String())
|
|
}
|
|
|
|
func (f *IpRouteFilter) vnetID(id uuid.UUID) {
|
|
f.queryParams.Set("virtual_network_id", id.String())
|
|
}
|
|
|
|
func (f *IpRouteFilter) MaxFetchSize(max uint) {
|
|
f.queryParams.Set("per_page", strconv.Itoa(int(max)))
|
|
}
|
|
|
|
func (f IpRouteFilter) Encode() string {
|
|
return f.queryParams.Encode()
|
|
}
|