diff options
Diffstat (limited to 'plugin/special')
| -rw-r--r-- | plugin/special/cutter.go | 94 | ||||
| -rw-r--r-- | plugin/special/lookup.go | 81 | ||||
| -rw-r--r-- | plugin/special/private.go | 60 | ||||
| -rw-r--r-- | plugin/special/stdin.go | 81 | ||||
| -rw-r--r-- | plugin/special/stdout.go | 84 | ||||
| -rw-r--r-- | plugin/special/test.go | 20 |
6 files changed, 282 insertions, 138 deletions
diff --git a/plugin/special/cutter.go b/plugin/special/cutter.go index 509cddbb..589fc3f2 100644 --- a/plugin/special/cutter.go +++ b/plugin/special/cutter.go @@ -3,6 +3,7 @@ package special import ( "encoding/json" "fmt" + "log" "strings" "github.com/Loyalsoldier/geoip/lib" @@ -15,14 +16,61 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeCutter, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newCutter(action, data) + return NewCutterFromBytes(action, data) }) - lib.RegisterInputConverter(TypeCutter, &Cutter{ + lib.RegisterInputConverter(TypeCutter, &cutter{ Description: DescCutter, }) } -func newCutter(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { +type cutter struct { + Type string + Action lib.Action + Description string + Want map[string]bool + OnlyIPType lib.IPType +} + +func NewCutter(action lib.Action, opts ...lib.InputOption) lib.InputConverter { + c := &cutter{ + Type: TypeCutter, + Action: action, + Description: DescCutter, + } + + for _, opt := range opts { + if opt != nil { + opt(c) + } + } + + return c +} + +func WithCutterWantedList(lists []string) lib.InputOption { + return func(s lib.InputConverter) { + wantList := make(map[string]bool) + for _, want := range lists { + if want = strings.ToUpper(strings.TrimSpace(want)); want != "" { + wantList[want] = true + } + } + + if len(wantList) == 0 { + log.Fatalf("❌ [type %s] wantedList must be specified", TypeCutter) + } + + s.(*cutter).Want = wantList + } +} + +func WithCutterOnlyIPType(onlyIPType lib.IPType) lib.InputOption { + return func(s lib.InputConverter) { + s.(*cutter).OnlyIPType = onlyIPType + } +} + +func NewCutterFromBytes(action lib.Action, data []byte) (lib.InputConverter, error) { var tmp struct { Want []string `json:"wantedList"` OnlyIPType lib.IPType `json:"onlyIPType"` @@ -38,48 +86,26 @@ func newCutter(action lib.Action, data json.RawMessage) (lib.InputConverter, err return nil, fmt.Errorf("❌ [type %s] only supports `remove` action", TypeCutter) } - // Filter want list - wantList := make(map[string]bool) - for _, want := range tmp.Want { - if want = strings.ToUpper(strings.TrimSpace(want)); want != "" { - wantList[want] = true - } - } - - if len(wantList) == 0 { - return nil, fmt.Errorf("❌ [type %s] wantedList must be specified", TypeCutter) - } - - return &Cutter{ - Type: TypeCutter, - Action: action, - Description: DescCutter, - Want: wantList, - OnlyIPType: tmp.OnlyIPType, - }, nil -} - -type Cutter struct { - Type string - Action lib.Action - Description string - Want map[string]bool - OnlyIPType lib.IPType + return NewCutter( + action, + WithCutterWantedList(tmp.Want), + WithCutterOnlyIPType(tmp.OnlyIPType), + ), nil } -func (c *Cutter) GetType() string { +func (c *cutter) GetType() string { return c.Type } -func (c *Cutter) GetAction() lib.Action { +func (c *cutter) GetAction() lib.Action { return c.Action } -func (c *Cutter) GetDescription() string { +func (c *cutter) GetDescription() string { return c.Description } -func (c *Cutter) Input(container lib.Container) (lib.Container, error) { +func (c *cutter) Input(container lib.Container) (lib.Container, error) { ignoreIPType := lib.GetIgnoreIPType(c.OnlyIPType) for entry := range container.Loop() { diff --git a/plugin/special/lookup.go b/plugin/special/lookup.go index 96735146..ddf96ecd 100644 --- a/plugin/special/lookup.go +++ b/plugin/special/lookup.go @@ -4,6 +4,7 @@ import ( "encoding/json" "errors" "fmt" + "log" "net/netip" "slices" "strings" @@ -18,14 +19,55 @@ const ( func init() { lib.RegisterOutputConfigCreator(TypeLookup, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newLookup(action, data) + return NewLookupFromBytes(action, data) }) - lib.RegisterOutputConverter(TypeLookup, &Lookup{ + lib.RegisterOutputConverter(TypeLookup, &lookup{ Description: DescLookup, }) } -func newLookup(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { +type lookup struct { + Type string + Action lib.Action + Description string + Search string + SearchList []string +} + +func NewLookup(action lib.Action, opts ...lib.OutputOption) lib.OutputConverter { + l := &lookup{ + Type: TypeLookup, + Action: action, + Description: DescLookup, + } + + for _, opt := range opts { + if opt != nil { + opt(l) + } + } + + return l +} + +func WithLookupSearch(search string) lib.OutputOption { + return func(s lib.OutputConverter) { + search = strings.TrimSpace(search) + if search == "" { + log.Fatalf("❌ [type %s | action %s] please specify an IP or a CIDR as search target", TypeLookup, s.(*lookup).Action) + } + + s.(*lookup).Search = search + } +} + +func WithLookupSearchList(lists []string) lib.OutputOption { + return func(s lib.OutputConverter) { + s.(*lookup).SearchList = lists + } +} + +func NewLookupFromBytes(action lib.Action, data []byte) (lib.OutputConverter, error) { var tmp struct { Search string `json:"search"` SearchList []string `json:"searchList"` @@ -37,41 +79,26 @@ func newLookup(action lib.Action, data json.RawMessage) (lib.OutputConverter, er } } - tmp.Search = strings.TrimSpace(tmp.Search) - if tmp.Search == "" { - return nil, fmt.Errorf("❌ [type %s | action %s] please specify an IP or a CIDR as search target", TypeLookup, action) - } - - return &Lookup{ - Type: TypeLookup, - Action: action, - Description: DescLookup, - Search: tmp.Search, - SearchList: tmp.SearchList, - }, nil -} - -type Lookup struct { - Type string - Action lib.Action - Description string - Search string - SearchList []string + return NewLookup( + action, + WithLookupSearch(tmp.Search), + WithLookupSearchList(tmp.SearchList), + ), nil } -func (l *Lookup) GetType() string { +func (l *lookup) GetType() string { return l.Type } -func (l *Lookup) GetAction() lib.Action { +func (l *lookup) GetAction() lib.Action { return l.Action } -func (l *Lookup) GetDescription() string { +func (l *lookup) GetDescription() string { return l.Description } -func (l *Lookup) Output(container lib.Container) error { +func (l *lookup) Output(container lib.Container) error { switch strings.Contains(l.Search, "/") { case true: // CIDR if _, err := netip.ParsePrefix(l.Search); err != nil { diff --git a/plugin/special/private.go b/plugin/special/private.go index 1bc170bc..eee31bd7 100644 --- a/plugin/special/private.go +++ b/plugin/special/private.go @@ -38,14 +38,43 @@ var privateCIDRs = []string{ func init() { lib.RegisterInputConfigCreator(TypePrivate, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newPrivate(action, data) + return NewPrivateFromBytes(action, data) }) - lib.RegisterInputConverter(TypePrivate, &Private{ + lib.RegisterInputConverter(TypePrivate, &private{ Description: DescPrivate, }) } -func newPrivate(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { +type private struct { + Type string + Action lib.Action + Description string + OnlyIPType lib.IPType +} + +func NewPrivate(action lib.Action, opts ...lib.InputOption) lib.InputConverter { + p := &private{ + Type: TypePrivate, + Action: action, + Description: DescPrivate, + } + + for _, opt := range opts { + if opt != nil { + opt(p) + } + } + + return p +} + +func WithPrivateOnlyIPType(onlyIPType lib.IPType) lib.InputOption { + return func(s lib.InputConverter) { + s.(*private).OnlyIPType = onlyIPType + } +} + +func NewPrivateFromBytes(action lib.Action, data []byte) (lib.InputConverter, error) { var tmp struct { OnlyIPType lib.IPType `json:"onlyIPType"` } @@ -56,34 +85,25 @@ func newPrivate(action lib.Action, data json.RawMessage) (lib.InputConverter, er } } - return &Private{ - Type: TypePrivate, - Action: action, - Description: DescPrivate, - OnlyIPType: tmp.OnlyIPType, - }, nil -} - -type Private struct { - Type string - Action lib.Action - Description string - OnlyIPType lib.IPType + return NewPrivate( + action, + WithPrivateOnlyIPType(tmp.OnlyIPType), + ), nil } -func (p *Private) GetType() string { +func (p *private) GetType() string { return p.Type } -func (p *Private) GetAction() lib.Action { +func (p *private) GetAction() lib.Action { return p.Action } -func (p *Private) GetDescription() string { +func (p *private) GetDescription() string { return p.Description } -func (p *Private) Input(container lib.Container) (lib.Container, error) { +func (p *private) Input(container lib.Container) (lib.Container, error) { entry, found := container.GetEntry(entryNamePrivate) if !found { entry = lib.NewEntry(entryNamePrivate) diff --git a/plugin/special/stdin.go b/plugin/special/stdin.go index f2f9cf9c..459bdf9f 100644 --- a/plugin/special/stdin.go +++ b/plugin/special/stdin.go @@ -3,7 +3,7 @@ package special import ( "bufio" "encoding/json" - "fmt" + "log" "os" "strings" @@ -17,14 +17,55 @@ const ( func init() { lib.RegisterInputConfigCreator(TypeStdin, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newStdin(action, data) + return NewStdinFromBytes(action, data) }) - lib.RegisterInputConverter(TypeStdin, &Stdin{ + lib.RegisterInputConverter(TypeStdin, &stdin{ Description: DescStdin, }) } -func newStdin(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { +type stdin struct { + Type string + Action lib.Action + Description string + Name string + OnlyIPType lib.IPType +} + +func NewStdin(action lib.Action, opts ...lib.InputOption) lib.InputConverter { + s := &stdin{ + Type: TypeStdin, + Action: action, + Description: DescStdin, + } + + for _, opt := range opts { + if opt != nil { + opt(s) + } + } + + return s +} + +func WithStdinName(name string) lib.InputOption { + return func(s lib.InputConverter) { + name = strings.TrimSpace(name) + if name == "" { + log.Fatalf("❌ [type %s | action %s] missing name", TypeStdin, s.(*stdin).Action) + } + + s.(*stdin).Name = name + } +} + +func WithStdinOnlyIPType(onlyIPType lib.IPType) lib.InputOption { + return func(s lib.InputConverter) { + s.(*stdin).OnlyIPType = onlyIPType + } +} + +func NewStdinFromBytes(action lib.Action, data []byte) (lib.InputConverter, error) { var tmp struct { Name string `json:"name"` OnlyIPType lib.IPType `json:"onlyIPType"` @@ -36,40 +77,26 @@ func newStdin(action lib.Action, data json.RawMessage) (lib.InputConverter, erro } } - if tmp.Name == "" { - return nil, fmt.Errorf("❌ [type %s | action %s] missing name", TypeStdin, action) - } - - return &Stdin{ - Type: TypeStdin, - Action: action, - Description: DescStdin, - Name: tmp.Name, - OnlyIPType: tmp.OnlyIPType, - }, nil -} - -type Stdin struct { - Type string - Action lib.Action - Description string - Name string - OnlyIPType lib.IPType + return NewStdin( + action, + WithStdinName(tmp.Name), + WithStdinOnlyIPType(tmp.OnlyIPType), + ), nil } -func (s *Stdin) GetType() string { +func (s *stdin) GetType() string { return s.Type } -func (s *Stdin) GetAction() lib.Action { +func (s *stdin) GetAction() lib.Action { return s.Action } -func (s *Stdin) GetDescription() string { +func (s *stdin) GetDescription() string { return s.Description } -func (s *Stdin) Input(container lib.Container) (lib.Container, error) { +func (s *stdin) Input(container lib.Container) (lib.Container, error) { entry := lib.NewEntry(s.Name) scanner := bufio.NewScanner(os.Stdin) diff --git a/plugin/special/stdout.go b/plugin/special/stdout.go index 614deaac..e356c577 100644 --- a/plugin/special/stdout.go +++ b/plugin/special/stdout.go @@ -18,14 +18,57 @@ const ( func init() { lib.RegisterOutputConfigCreator(TypeStdout, func(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { - return newStdout(action, data) + return NewStdoutFromBytes(action, data) }) - lib.RegisterOutputConverter(TypeStdout, &Stdout{ + lib.RegisterOutputConverter(TypeStdout, &stdout{ Description: DescStdout, }) } -func newStdout(action lib.Action, data json.RawMessage) (lib.OutputConverter, error) { +type stdout struct { + Type string + Action lib.Action + Description string + Want []string + Exclude []string + OnlyIPType lib.IPType +} + +func NewStdout(action lib.Action, opts ...lib.OutputOption) lib.OutputConverter { + s := &stdout{ + Type: TypeStdout, + Action: action, + Description: DescStdout, + } + + for _, opt := range opts { + if opt != nil { + opt(s) + } + } + + return s +} + +func WithStdoutWantedList(lists []string) lib.OutputOption { + return func(s lib.OutputConverter) { + s.(*stdout).Want = lists + } +} + +func WithStdoutExcludedList(lists []string) lib.OutputOption { + return func(s lib.OutputConverter) { + s.(*stdout).Exclude = lists + } +} + +func WithStdoutOnlyIPType(onlyIPType lib.IPType) lib.OutputOption { + return func(s lib.OutputConverter) { + s.(*stdout).OnlyIPType = onlyIPType + } +} + +func NewStdoutFromBytes(action lib.Action, data []byte) (lib.OutputConverter, error) { var tmp struct { Want []string `json:"wantedList"` Exclude []string `json:"excludedList"` @@ -38,38 +81,27 @@ func newStdout(action lib.Action, data json.RawMessage) (lib.OutputConverter, er } } - return &Stdout{ - Type: TypeStdout, - Action: action, - Description: DescStdout, - Want: tmp.Want, - Exclude: tmp.Exclude, - OnlyIPType: tmp.OnlyIPType, - }, nil -} - -type Stdout struct { - Type string - Action lib.Action - Description string - Want []string - Exclude []string - OnlyIPType lib.IPType + return NewStdout( + action, + WithStdoutWantedList(tmp.Want), + WithStdoutExcludedList(tmp.Exclude), + WithStdoutOnlyIPType(tmp.OnlyIPType), + ), nil } -func (s *Stdout) GetType() string { +func (s *stdout) GetType() string { return s.Type } -func (s *Stdout) GetAction() lib.Action { +func (s *stdout) GetAction() lib.Action { return s.Action } -func (s *Stdout) GetDescription() string { +func (s *stdout) GetDescription() string { return s.Description } -func (s *Stdout) Output(container lib.Container) error { +func (s *stdout) Output(container lib.Container) error { for _, name := range s.filterAndSortList(container) { entry, found := container.GetEntry(name) if !found { @@ -89,7 +121,7 @@ func (s *Stdout) Output(container lib.Container) error { return nil } -func (s *Stdout) filterAndSortList(container lib.Container) []string { +func (s *stdout) filterAndSortList(container lib.Container) []string { excludeMap := make(map[string]bool) for _, exclude := range s.Exclude { if exclude = strings.ToUpper(strings.TrimSpace(exclude)); exclude != "" { @@ -125,7 +157,7 @@ func (s *Stdout) filterAndSortList(container lib.Container) []string { return list } -func (s *Stdout) generateCIDRList(entry *lib.Entry) ([]string, error) { +func (s *stdout) generateCIDRList(entry *lib.Entry) ([]string, error) { entryList, err := entry.MarshalText(lib.GetIgnoreIPType(s.OnlyIPType)) if err != nil { return nil, err diff --git a/plugin/special/test.go b/plugin/special/test.go index cf83ed83..6425ca93 100644 --- a/plugin/special/test.go +++ b/plugin/special/test.go @@ -18,19 +18,31 @@ var testCIDRs = []string{ func init() { lib.RegisterInputConfigCreator(typeTest, func(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return newTest(action, data) + return NewTestFromBytes(action, data) }) lib.RegisterInputConverter(typeTest, &test{ Description: descTest, }) } -func newTest(action lib.Action, data json.RawMessage) (lib.InputConverter, error) { - return &test{ +func NewTest(action lib.Action, opts ...lib.InputOption) lib.InputConverter { + t := &test{ Type: typeTest, Action: action, Description: descTest, - }, nil + } + + for _, opt := range opts { + if opt != nil { + opt(t) + } + } + + return t +} + +func NewTestFromBytes(action lib.Action, data []byte) (lib.InputConverter, error) { + return NewTest(action), nil } type test struct { |
