ip_route_filter.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. package cfapi
  2. import (
  3. "fmt"
  4. "net"
  5. "net/url"
  6. "strconv"
  7. "time"
  8. "github.com/google/uuid"
  9. "github.com/pkg/errors"
  10. "github.com/urfave/cli/v2"
  11. )
  12. var (
  13. filterIpRouteDeleted = cli.BoolFlag{
  14. Name: "filter-is-deleted",
  15. Usage: "If false (default), only show non-deleted routes. If true, only show deleted routes.",
  16. }
  17. filterIpRouteTunnelID = cli.StringFlag{
  18. Name: "filter-tunnel-id",
  19. Usage: "Show only routes with the given tunnel ID.",
  20. }
  21. filterSubsetIpRoute = cli.StringFlag{
  22. Name: "filter-network-is-subset-of",
  23. Aliases: []string{"nsub"},
  24. Usage: "Show only routes whose network is a subset of the given network.",
  25. }
  26. filterSupersetIpRoute = cli.StringFlag{
  27. Name: "filter-network-is-superset-of",
  28. Aliases: []string{"nsup"},
  29. Usage: "Show only routes whose network is a superset of the given network.",
  30. }
  31. filterIpRouteComment = cli.StringFlag{
  32. Name: "filter-comment-is",
  33. Usage: "Show only routes with this comment.",
  34. }
  35. filterIpRouteByVnet = cli.StringFlag{
  36. Name: "filter-vnet-id",
  37. Usage: "Show only routes that are attached to the given virtual network ID.",
  38. }
  39. // Flags contains all filter flags.
  40. IpRouteFilterFlags = []cli.Flag{
  41. &filterIpRouteDeleted,
  42. &filterIpRouteTunnelID,
  43. &filterSubsetIpRoute,
  44. &filterSupersetIpRoute,
  45. &filterIpRouteComment,
  46. &filterIpRouteByVnet,
  47. }
  48. )
  49. // IpRouteFilter which routes get queried.
  50. type IpRouteFilter struct {
  51. queryParams url.Values
  52. }
  53. // NewIpRouteFilterFromCLI parses CLI flags to discover which filters should get applied.
  54. func NewIpRouteFilterFromCLI(c *cli.Context) (*IpRouteFilter, error) {
  55. f := NewIPRouteFilter()
  56. // Set deletion filter
  57. if flag := filterIpRouteDeleted.Name; c.IsSet(flag) && c.Bool(flag) {
  58. f.Deleted()
  59. } else {
  60. f.NotDeleted()
  61. }
  62. if subset, err := cidrFromFlag(c, filterSubsetIpRoute); err != nil {
  63. return nil, err
  64. } else if subset != nil {
  65. f.NetworkIsSupersetOf(*subset)
  66. }
  67. if superset, err := cidrFromFlag(c, filterSupersetIpRoute); err != nil {
  68. return nil, err
  69. } else if superset != nil {
  70. f.NetworkIsSupersetOf(*superset)
  71. }
  72. if comment := c.String(filterIpRouteComment.Name); comment != "" {
  73. f.CommentIs(comment)
  74. }
  75. if tunnelID := c.String(filterIpRouteTunnelID.Name); tunnelID != "" {
  76. u, err := uuid.Parse(tunnelID)
  77. if err != nil {
  78. return nil, errors.Wrapf(err, "Couldn't parse UUID from %s", filterIpRouteTunnelID.Name)
  79. }
  80. f.TunnelID(u)
  81. }
  82. if vnetId := c.String(filterIpRouteByVnet.Name); vnetId != "" {
  83. u, err := uuid.Parse(vnetId)
  84. if err != nil {
  85. return nil, errors.Wrapf(err, "Couldn't parse UUID from %s", filterIpRouteByVnet.Name)
  86. }
  87. f.VNetID(u)
  88. }
  89. if maxFetch := c.Int("max-fetch-size"); maxFetch > 0 {
  90. f.MaxFetchSize(uint(maxFetch))
  91. }
  92. return f, nil
  93. }
  94. // Parses a CIDR from the flag. If the flag was unset, returns (nil, nil).
  95. func cidrFromFlag(c *cli.Context, flag cli.StringFlag) (*net.IPNet, error) {
  96. if !c.IsSet(flag.Name) {
  97. return nil, nil
  98. }
  99. _, subset, err := net.ParseCIDR(c.String(flag.Name))
  100. if err != nil {
  101. return nil, err
  102. } else if subset == nil {
  103. return nil, fmt.Errorf("Invalid CIDR supplied for %s", flag.Name)
  104. }
  105. return subset, nil
  106. }
  107. func NewIPRouteFilter() *IpRouteFilter {
  108. values := &IpRouteFilter{queryParams: url.Values{}}
  109. // always list cfd_tunnel routes only
  110. values.queryParams.Set("tun_types", "cfd_tunnel")
  111. return values
  112. }
  113. func (f *IpRouteFilter) CommentIs(comment string) {
  114. f.queryParams.Set("comment", comment)
  115. }
  116. func (f *IpRouteFilter) NotDeleted() {
  117. f.queryParams.Set("is_deleted", "false")
  118. }
  119. func (f *IpRouteFilter) Deleted() {
  120. f.queryParams.Set("is_deleted", "true")
  121. }
  122. func (f *IpRouteFilter) NetworkIsSubsetOf(superset net.IPNet) {
  123. f.queryParams.Set("network_subset", superset.String())
  124. }
  125. func (f *IpRouteFilter) NetworkIsSupersetOf(subset net.IPNet) {
  126. f.queryParams.Set("network_superset", subset.String())
  127. }
  128. func (f *IpRouteFilter) ExistedAt(existedAt time.Time) {
  129. f.queryParams.Set("existed_at", existedAt.Format(time.RFC3339))
  130. }
  131. func (f *IpRouteFilter) TunnelID(id uuid.UUID) {
  132. f.queryParams.Set("tunnel_id", id.String())
  133. }
  134. func (f *IpRouteFilter) VNetID(id uuid.UUID) {
  135. f.queryParams.Set("virtual_network_id", id.String())
  136. }
  137. func (f *IpRouteFilter) MaxFetchSize(max uint) {
  138. f.queryParams.Set("per_page", strconv.Itoa(int(max)))
  139. }
  140. func (f *IpRouteFilter) Page(page int) {
  141. f.queryParams.Set("page", strconv.Itoa(page))
  142. }
  143. func (f IpRouteFilter) Encode() string {
  144. return f.queryParams.Encode()
  145. }