filter.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. package teamnet
  2. import (
  3. "fmt"
  4. "net"
  5. "net/url"
  6. "time"
  7. "github.com/google/uuid"
  8. "github.com/pkg/errors"
  9. "github.com/urfave/cli/v2"
  10. )
  11. var (
  12. filterDeleted = cli.BoolFlag{
  13. Name: "filter-is-deleted",
  14. Usage: "If false (default), only show non-deleted routes. If true, only show deleted routes.",
  15. }
  16. filterTunnelID = cli.StringFlag{
  17. Name: "filter-tunnel-id",
  18. Usage: "Show only routes with the given tunnel ID.",
  19. }
  20. filterSubset = cli.StringFlag{
  21. Name: "filter-network-is-subset-of",
  22. Aliases: []string{"nsub"},
  23. Usage: "Show only routes whose network is a subset of the given network.",
  24. }
  25. filterSuperset = cli.StringFlag{
  26. Name: "filter-network-is-superset-of",
  27. Aliases: []string{"nsup"},
  28. Usage: "Show only routes whose network is a superset of the given network.",
  29. }
  30. filterComment = cli.StringFlag{
  31. Name: "filter-comment-is",
  32. Usage: "Show only routes with this comment.",
  33. }
  34. // Flags contains all filter flags.
  35. FilterFlags = []cli.Flag{
  36. &filterDeleted,
  37. &filterTunnelID,
  38. &filterSubset,
  39. &filterSuperset,
  40. &filterComment,
  41. }
  42. )
  43. // Filter which routes get queried.
  44. type Filter struct {
  45. queryParams url.Values
  46. }
  47. // NewFromCLI parses CLI flags to discover which filters should get applied.
  48. func NewFromCLI(c *cli.Context) (*Filter, error) {
  49. f := &Filter{
  50. queryParams: url.Values{},
  51. }
  52. // Set deletion filter
  53. if flag := filterDeleted.Name; c.IsSet(flag) && c.Bool(flag) {
  54. f.deleted()
  55. } else {
  56. f.notDeleted()
  57. }
  58. if subset, err := cidrFromFlag(c, filterSubset); err != nil {
  59. return nil, err
  60. } else if subset != nil {
  61. f.networkIsSupersetOf(*subset)
  62. }
  63. if superset, err := cidrFromFlag(c, filterSuperset); err != nil {
  64. return nil, err
  65. } else if superset != nil {
  66. f.networkIsSupersetOf(*superset)
  67. }
  68. if comment := c.String(filterComment.Name); comment != "" {
  69. f.commentIs(comment)
  70. }
  71. if tunnelID := c.String(filterTunnelID.Name); tunnelID != "" {
  72. u, err := uuid.Parse(tunnelID)
  73. if err != nil {
  74. return nil, errors.Wrap(err, "Couldn't parse UUID from --filter-tunnel-id")
  75. }
  76. f.tunnelID(u)
  77. }
  78. return f, nil
  79. }
  80. // Parses a CIDR from the flag. If the flag was unset, returns (nil, nil).
  81. func cidrFromFlag(c *cli.Context, flag cli.StringFlag) (*net.IPNet, error) {
  82. if !c.IsSet(flag.Name) {
  83. return nil, nil
  84. }
  85. _, subset, err := net.ParseCIDR(c.String(flag.Name))
  86. if err != nil {
  87. return nil, err
  88. } else if subset == nil {
  89. return nil, fmt.Errorf("Invalid CIDR supplied for %s", flag.Name)
  90. }
  91. return subset, nil
  92. }
  93. func (f *Filter) commentIs(comment string) {
  94. f.queryParams.Set("comment", comment)
  95. }
  96. func (f *Filter) notDeleted() {
  97. f.queryParams.Set("is_deleted", "false")
  98. }
  99. func (f *Filter) deleted() {
  100. f.queryParams.Set("is_deleted", "true")
  101. }
  102. func (f *Filter) networkIsSubsetOf(superset net.IPNet) {
  103. f.queryParams.Set("network_subset", superset.String())
  104. }
  105. func (f *Filter) networkIsSupersetOf(subset net.IPNet) {
  106. f.queryParams.Set("network_superset", subset.String())
  107. }
  108. func (f *Filter) existedAt(existedAt time.Time) {
  109. f.queryParams.Set("existed_at", existedAt.Format(time.RFC3339))
  110. }
  111. func (f *Filter) tunnelID(id uuid.UUID) {
  112. f.queryParams.Set("tunnel_id", id.String())
  113. }
  114. func (f Filter) Encode() string {
  115. return f.queryParams.Encode()
  116. }