Skip to content

Commit

Permalink
Feat: support to specify IP or CIDR in config file for text input format
Browse files Browse the repository at this point in the history
  • Loading branch information
Loyalsoldier committed Aug 31, 2024
1 parent fca10e6 commit deff06a
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 10 deletions.
43 changes: 39 additions & 4 deletions configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,11 @@
- **type**:(必须)输入格式的名称
- **action**:(必须)操作类型,值为 `add`(添加 IP 地址)或 `remove`(移除 IP 地址)
- **args**:(必须)
- **name**:类别名称。(不能与 `inputDir` 同时使用;需要与 `uri` 同时使用)
- **uri**:纯文本 txt 文件路径,可为本地文件路径或远程 `http``https` 文件 URL。(不能与 `inputDir` 同时使用;需要与 `name` 同时使用)
- **inputDir**:需要遍历的输入目录(不遍历子目录)。(遍历的文件名作为类别名称;不能与 `name``uri` 同时使用)
- **wantedList**:(可选,数组)指定需要的类别/文件。(与 `inputDir` 同时使用)
- **name**:(可选)类别名称。(不能与 `inputDir` 同时使用;需要与 `uri``ipOrCIDR` 同时使用)
- **uri**:(可选)纯文本 txt 文件路径,可为本地文件路径或远程 `http``https` 文件 URL。(不能与 `inputDir` 同时使用;需要与 `name` 同时使用;可与 `ipOrCIDR` 同时使用)
- **ipOrCIDR**:(可选,数组)纯文本 IP 地址或 CIDR。(不能与 `inputDir` 同时使用;需要与 `name` 同时使用;可与 `uri` 同时使用)
- **inputDir**:(可选)需要遍历的输入目录(不遍历子目录)。(遍历的文件名作为类别名称;不能与 `name``uri``ipOrCIDR` 同时使用)
- **wantedList**:(可选,数组)指定需要的文件。(与 `inputDir` 同时使用)
- **onlyIPType**:(可选)只处理的 IP 地址类型,值为 `ipv4``ipv6`
- **removePrefixesInLine**:(可选,数组)每一行需要移除的字符串前缀
- **removeSuffixesInLine**:(可选,数组)每一行需要移除的字符串后缀
Expand All @@ -591,6 +592,40 @@
}
```

```jsonc
{
"type": "text",
"action": "add", // 添加 IP 地址
"args": {
"name": "cn",
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // 添加 IP 或 CIDR 到 cn 类别
}
}
```

```jsonc
{
"type": "text",
"action": "remove", // 移除 IP 地址
"args": {
"name": "cn",
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // 从 cn 类别移除 IP 或 CIDR
}
}
```

```jsonc
{
"type": "text",
"action": "add", // 添加 IP 地址
"args": {
"name": "cn",
"uri": "./cn.txt", // 读取本地文件 cn.txt 的 IPv4 和 IPv6 地址,并添加到 cn 类别中
"ipOrCIDR": ["1.0.0.1", "1.0.0.1/24"] // 添加 IP 或 CIDR 到 cn 类别
}
}
```

```jsonc
{
"type": "text",
Expand Down
1 change: 1 addition & 0 deletions plugin/plaintext/common_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type textIn struct {
Description string
Name string
URI string
IPOrCIDR []string
InputDir string
Want map[string]bool
OnlyIPType lib.IPType
Expand Down
50 changes: 44 additions & 6 deletions plugin/plaintext/text_in.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ func newTextIn(iType string, action lib.Action, data json.RawMessage) (lib.Input
var tmp struct {
Name string `json:"name"`
URI string `json:"uri"`
IPOrCIDR []string `json:"ipOrCIDR"`
InputDir string `json:"inputDir"`
Want []string `json:"wantedList"`
OnlyIPType lib.IPType `json:"onlyIPType"`
Expand All @@ -49,16 +50,23 @@ func newTextIn(iType string, action lib.Action, data json.RawMessage) (lib.Input
}
}

if tmp.Name == "" && tmp.URI == "" && tmp.InputDir == "" {
return nil, fmt.Errorf("type %s | action %s missing inputdir or name or uri", typeTextIn, action)
if iType != typeTextIn && len(tmp.IPOrCIDR) > 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] ipOrCIDR is invalid for this input format", iType, action)
}

if (tmp.Name != "" && tmp.URI == "") || (tmp.Name == "" && tmp.URI != "") {
return nil, fmt.Errorf("type %s | action %s name & uri must be specified together", typeTextIn, action)
if iType == typeJSONIn && len(tmp.JSONPath) == 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] missing jsonPath", typeJSONIn, action)
}

if iType == typeJSONIn && len(tmp.JSONPath) == 0 {
return nil, fmt.Errorf("type %s | action %s missing jsonPath", typeJSONIn, action)
if tmp.InputDir == "" {
if tmp.Name == "" {
return nil, fmt.Errorf("❌ [type %s | action %s] missing inputDir or name", iType, action)
}
if tmp.URI == "" && len(tmp.IPOrCIDR) == 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] missing uri or ipOrCIDR", iType, action)
}
} else if tmp.Name != "" || tmp.URI != "" || len(tmp.IPOrCIDR) > 0 {
return nil, fmt.Errorf("❌ [type %s | action %s] inputDir is not allowed to be used with name or uri or ipOrCIDR", iType, action)
}

// Filter want list
Expand All @@ -75,6 +83,7 @@ func newTextIn(iType string, action lib.Action, data json.RawMessage) (lib.Input
Description: descTextIn,
Name: tmp.Name,
URI: tmp.URI,
IPOrCIDR: tmp.IPOrCIDR,
InputDir: tmp.InputDir,
Want: wantList,
OnlyIPType: tmp.OnlyIPType,
Expand Down Expand Up @@ -104,13 +113,23 @@ func (t *textIn) Input(container lib.Container) (lib.Container, error) {
switch {
case t.InputDir != "":
err = t.walkDir(t.InputDir, entries)

case t.Name != "" && t.URI != "":
switch {
case strings.HasPrefix(strings.ToLower(t.URI), "http://"), strings.HasPrefix(strings.ToLower(t.URI), "https://"):
err = t.walkRemoteFile(t.URI, t.Name, entries)
default:
err = t.walkLocalFile(t.URI, t.Name, entries)
}
if err != nil {
return nil, err
}

fallthrough

case t.Name != "" && len(t.IPOrCIDR) > 0:
err = t.appendIPOrCIDR(t.IPOrCIDR, t.Name, entries)

default:
return nil, fmt.Errorf("config missing argument inputDir or name or uri")
}
Expand Down Expand Up @@ -238,3 +257,22 @@ func (t *textIn) walkRemoteFile(url, name string, entries map[string]*lib.Entry)

return nil
}

func (t *textIn) appendIPOrCIDR(ipOrCIDR []string, name string, entries map[string]*lib.Entry) error {
name = strings.ToUpper(name)

entry, found := entries[name]
if !found {
entry = lib.NewEntry(name)
}

for _, cidr := range ipOrCIDR {
if err := entry.AddPrefix(strings.TrimSpace(cidr)); err != nil {
return err
}
}

entries[name] = entry

return nil
}

0 comments on commit deff06a

Please sign in to comment.