17 Commits
Author SHA1 Message Date
kor-elf 2037ac6034 Add rule implementation with Add, Insert, Replace, and Delete methods 2026-04-26 16:13:09 +05:00
kor-elf 8d9c3e7f7b Refactor rule commands to use nftCommand utilities for improved code reuse 2026-04-26 16:12:24 +05:00
kor-elf bc00e46865 Add chain implementation with Add, Create, Delete, Clear, and Rename methods 2026-04-26 16:05:58 +05:00
kor-elf 7dc8436ad8 Refactor chain commands to use nftCommand utilities for improved code reuse 2026-04-26 16:05:16 +05:00
kor-elf 8fdecbcd8d Add table implementation with Add, Delete, and Clear methods 2026-04-26 15:59:53 +05:00
kor-elf a56dcc2952 Switch to fmt.Sprintf for appending a newline in CommandRun for consistency 2026-04-26 15:58:38 +05:00
kor-elf fedf0966bc Refactor table commands to use nftCommand utilities for improved code reuse 2026-04-26 15:47:48 +05:00
kor-elf 04b70ce5ec BatchBuilder implements the Clear method 2026-04-26 15:40:47 +05:00
kor-elf 7d6dcf1ece Refactor Clear method to use nftCommand.Clear for improved code reuse 2026-04-26 15:38:05 +05:00
kor-elf 8fb0306b1b Switch from fmt.Sprintf to strings.Join for writing arguments in CommandRun 2026-04-26 15:37:17 +05:00
kor-elf 9cd17572b2 Add BatchBuilder for constructing and managing nftables batch commands 2026-04-26 15:28:17 +05:00
kor-elf 6d62b280a1 Add Batch implementation with Args, Check, Close, and MoveFile methods 2026-04-26 15:27:31 +05:00
kor-elf 53d8854ab4 Add CommandRun implementation for executing batch commands 2026-04-26 15:27:11 +05:00
kor-elf 321f24e915 Add File utility to create, write, move, and remove temporary files 2026-04-26 15:26:47 +05:00
kor-elf b36479c0ae Extend Batch interface with Close, Check, and MoveFile methods for enhanced functionality 2026-04-26 15:26:15 +05:00
kor-elf c4bd51d9bc Refactor Command interface to embed CommandRun for improved structure and consistency 2026-04-26 15:25:50 +05:00
kor-elf 94405fbb53 Add ExecuteBatchAfterCheck method to NFT interface for pre-checking and executing batch commands 2026-04-26 15:25:15 +05:00
18 changed files with 414 additions and 22 deletions
+72
View File
@@ -0,0 +1,72 @@
package nft
import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
contractBatch "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/batch"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/rule"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/batch/table"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
)
type batchBuilder struct {
command contract.CommandRun
file *pkg.File
table contractBatch.Table
chain contractBatch.Chain
rule contractBatch.Rule
isBuildBatch bool
}
func NewBatchBuilder(dir string) (contract.BatchBuilder, error) {
file, err := pkg.CreateRandomTmpFile(dir)
if err != nil {
return nil, err
}
command := batch.NewCommand(file)
return &batchBuilder{
command: command,
file: file,
table: table.New(command),
chain: chain.New(command),
rule: rule.New(command),
isBuildBatch: false,
}, nil
}
func (b *batchBuilder) Clear() error {
args := nftCommand.Clear()
return b.command.Run(args...)
}
func (b *batchBuilder) Table() contractBatch.Table {
return b.table
}
func (b *batchBuilder) Chain() contractBatch.Chain {
return b.chain
}
func (b *batchBuilder) Rule() contractBatch.Rule {
return b.rule
}
func (b *batchBuilder) Build() contract.Batch {
b.isBuildBatch = true
return batch.NewBatch(b.file)
}
func (b *batchBuilder) Close() error {
if b.isBuildBatch {
return nil
}
return b.file.Remove()
}
+12
View File
@@ -23,9 +23,21 @@ type BatchBuilder interface {
// Build returns a batch of commands. // Build returns a batch of commands.
Build() Batch Build() Batch
// Close closes the batch.
Close() error
} }
type Batch interface { type Batch interface {
// Args returns the arguments of the batch. // Args returns the arguments of the batch.
Args() []string Args() []string
// Check checks the validity of the batch.
Check(command Command) error
// Close closes the batch.
Close() error
// MoveFile moves the batch file to the specified path.
MoveFile(path string) error
} }
+5 -4
View File
@@ -1,11 +1,12 @@
package contract package contract
// Run is a function that executes nft command. type CommandRun interface {
type Run func(arg ...string) error // Run executes nft command.
Run(arg ...string) error
}
type Command interface { type Command interface {
// Run nft command. CommandRun
Run(arg ...string) error
// RunWithOutput Run nft command with output. // RunWithOutput Run nft command with output.
RunWithOutput(arg ...string) (string, error) RunWithOutput(arg ...string) (string, error)
+3
View File
@@ -8,6 +8,9 @@ type NFT interface {
// You can execute your raw request. // You can execute your raw request.
Command() Command Command() Command
// ExecuteBatchAfterCheck executes a batch of commands after checking the validity of the batch.
ExecuteBatchAfterCheck(batch Batch) error
// ExecuteBatch executes a batch of commands. // ExecuteBatch executes a batch of commands.
ExecuteBatch(batch Batch) error ExecuteBatch(batch Batch) error
+32
View File
@@ -0,0 +1,32 @@
package batch
import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
)
type batch struct {
file *pkg.File
}
func NewBatch(file *pkg.File) contract.Batch {
return &batch{
file: file,
}
}
func (b *batch) Args() []string {
return []string{"-f", b.file.Path()}
}
func (b *batch) Check(command contract.Command) error {
return command.Run("-c", "-f", b.file.Path())
}
func (b *batch) Close() error {
return b.file.Remove()
}
func (b *batch) MoveFile(path string) error {
return b.file.Move(path)
}
+44
View File
@@ -0,0 +1,44 @@
package chain
import (
chain2 "git.kor-elf.net/kor-elf-shield/go-nftables-client/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
)
type chain struct {
command contract.CommandRun
}
func New(command contract.CommandRun) nft.Chain {
return &chain{
command: command,
}
}
func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
args := nftCommand.ChainAdd(family, tableName, chainName, baseChain)
return c.command.Run(args...)
}
func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
args := nftCommand.ChainCreate(family, tableName, chainName, baseChain)
return c.command.Run(args...)
}
func (c *chain) Delete(family family.Type, tableName string, chainName string) error {
args := nftCommand.ChainDelete(family, tableName, chainName)
return c.command.Run(args...)
}
func (c *chain) Clear(family family.Type, tableName string, chainName string) error {
args := nftCommand.ChainClear(family, tableName, chainName)
return c.command.Run(args...)
}
func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error {
args := nftCommand.ChainRename(family, tableName, oldChainName, newChainName)
return c.command.Run(args...)
}
+24
View File
@@ -0,0 +1,24 @@
package batch
import (
"fmt"
"strings"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg"
)
type commandRun struct {
file *pkg.File
}
func NewCommand(file *pkg.File) contract.CommandRun {
return &commandRun{
file: file,
}
}
func (c *commandRun) Run(args ...string) error {
_, err := c.file.Write([]byte(fmt.Sprintf("%s\n", strings.Join(args, " "))))
return err
}
+38
View File
@@ -0,0 +1,38 @@
package rule
import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
)
type rule struct {
command contract.CommandRun
}
func New(command contract.CommandRun) nft.Rule {
return &rule{
command: command,
}
}
func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error {
args := nftCommand.RuleAdd(family, tableName, chainName, expr...)
return r.command.Run(args...)
}
func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error {
args := nftCommand.RuleInsert(family, tableName, chainName, expr...)
return r.command.Run(args...)
}
func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error {
args := nftCommand.RuleReplace(family, tableName, chainName, handle, expr...)
return r.command.Run(args...)
}
func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error {
args := nftCommand.RuleDelete(family, tableName, chainName, handle)
return r.command.Run(args...)
}
+33
View File
@@ -0,0 +1,33 @@
package table
import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
)
type table struct {
command contract.CommandRun
}
func New(command contract.CommandRun) nft.Table {
return &table{
command: command,
}
}
func (t *table) Add(family family.Type, tableName string) error {
args := nftCommand.TableAdd(family, tableName)
return t.command.Run(args...)
}
func (t *table) Delete(family family.Type, tableName string) error {
args := nftCommand.TableDelete(family, tableName)
return t.command.Run(args...)
}
func (t *table) Clear(family family.Type, tableName string) error {
args := nftCommand.TableClear(family, tableName)
return t.command.Run(args...)
}
+6 -5
View File
@@ -5,6 +5,7 @@ import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
) )
type chain struct { type chain struct {
@@ -18,26 +19,26 @@ func New(command contract.Command) nft.Chain {
} }
func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error { func (c *chain) Add(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
args := []string{"add", "chain", family.String(), tableName, chainName, baseChain.String()} args := nftCommand.ChainAdd(family, tableName, chainName, baseChain)
return c.command.Run(args...) return c.command.Run(args...)
} }
func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error { func (c *chain) Create(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) error {
args := []string{"create", "chain", family.String(), tableName, chainName, baseChain.String()} args := nftCommand.ChainCreate(family, tableName, chainName, baseChain)
return c.command.Run(args...) return c.command.Run(args...)
} }
func (c *chain) Delete(family family.Type, tableName string, chainName string) error { func (c *chain) Delete(family family.Type, tableName string, chainName string) error {
args := []string{"delete", "chain", family.String(), tableName, chainName} args := nftCommand.ChainDelete(family, tableName, chainName)
return c.command.Run(args...) return c.command.Run(args...)
} }
func (c *chain) Clear(family family.Type, tableName string, chainName string) error { func (c *chain) Clear(family family.Type, tableName string, chainName string) error {
args := []string{"flush", "chain", family.String(), tableName, chainName} args := nftCommand.ChainClear(family, tableName, chainName)
return c.command.Run(args...) return c.command.Run(args...)
} }
func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error { func (c *chain) Rename(family family.Type, tableName string, oldChainName string, newChainName string) error {
args := []string{"rename", "chain", family.String(), tableName, oldChainName, newChainName} args := nftCommand.ChainRename(family, tableName, oldChainName, newChainName)
return c.command.Run(args...) return c.command.Run(args...)
} }
+51
View File
@@ -0,0 +1,51 @@
package pkg
import (
"crypto/rand"
"os"
"path/filepath"
"time"
)
type File struct {
filepath string
file *os.File
isMoved bool
}
func CreateRandomTmpFile(dir string) (*File, error) {
if err := os.MkdirAll(dir, 0750); err != nil {
return nil, err
}
tmpFile := filepath.Join(dir, time.Now().Format(time.RFC3339)+"_"+rand.Text()+".tmp")
file, err := os.Create(tmpFile)
if err != nil {
return nil, err
}
return &File{
filepath: tmpFile,
file: file,
}, nil
}
func (f *File) Write(p []byte) (n int, err error) {
return f.file.Write(p)
}
func (f *File) Path() string {
return f.filepath
}
func (f *File) Remove() error {
if f.isMoved {
return nil
}
return os.Remove(f.filepath)
}
func (f *File) Move(path string) error {
return os.Rename(f.filepath, path)
}
+26
View File
@@ -0,0 +1,26 @@
package nft
import (
chain2 "git.kor-elf.net/kor-elf-shield/go-nftables-client/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
)
func ChainAdd(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) []string {
return []string{"add", "chain", family.String(), tableName, chainName, baseChain.String()}
}
func ChainCreate(family family.Type, tableName string, chainName string, baseChain chain2.ChainOptions) []string {
return []string{"create", "chain", family.String(), tableName, chainName, baseChain.String()}
}
func ChainDelete(family family.Type, tableName string, chainName string) []string {
return []string{"delete", "chain", family.String(), tableName, chainName}
}
func ChainClear(family family.Type, tableName string, chainName string) []string {
return []string{"flush", "chain", family.String(), tableName, chainName}
}
func ChainRename(family family.Type, tableName string, oldChainName string, newChainName string) []string {
return []string{"rename", "chain", family.String(), tableName, oldChainName, newChainName}
}
+5
View File
@@ -0,0 +1,5 @@
package nft
func Clear() []string {
return []string{"flush", "ruleset"}
}
+30
View File
@@ -0,0 +1,30 @@
package nft
import (
"strconv"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
)
func RuleAdd(family family.Type, tableName string, chainName string, expr ...string) []string {
args := []string{"add", "rule", family.String(), tableName, chainName}
args = append(args, expr...)
return args
}
func RuleInsert(family family.Type, tableName string, chainName string, expr ...string) []string {
args := []string{"insert", "rule", family.String(), tableName, chainName}
args = append(args, expr...)
return args
}
func RuleReplace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) []string {
args := []string{"replace", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
args = append(args, expr...)
return args
}
func RuleDelete(family family.Type, tableName string, chainName string, handle uint64) []string {
args := []string{"delete", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))}
return args
}
+15
View File
@@ -0,0 +1,15 @@
package nft
import "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
func TableAdd(family family.Type, tableName string) []string {
return []string{"add", "table", family.String(), tableName}
}
func TableDelete(family family.Type, tableName string) []string {
return []string{"delete", "table", family.String(), tableName}
}
func TableClear(family family.Type, tableName string) []string {
return []string{"flush", "table", family.String(), tableName}
}
+5 -9
View File
@@ -1,11 +1,10 @@
package rule package rule
import ( import (
"strconv"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
) )
type rule struct { type rule struct {
@@ -19,24 +18,21 @@ func New(command contract.Command) nft.Rule {
} }
func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error { func (r *rule) Add(family family.Type, tableName string, chainName string, expr ...string) error {
args := []string{"add", "rule", family.String(), tableName, chainName} args := nftCommand.RuleAdd(family, tableName, chainName, expr...)
args = append(args, expr...)
return r.command.Run(args...) return r.command.Run(args...)
} }
func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error { func (r *rule) Insert(family family.Type, tableName string, chainName string, expr ...string) error {
args := []string{"insert", "rule", family.String(), tableName, chainName} args := nftCommand.RuleInsert(family, tableName, chainName, expr...)
args = append(args, expr...)
return r.command.Run(args...) return r.command.Run(args...)
} }
func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error { func (r *rule) Replace(family family.Type, tableName string, chainName string, handle uint64, expr ...string) error {
args := []string{"replace", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))} args := nftCommand.RuleReplace(family, tableName, chainName, handle, expr...)
args = append(args, expr...)
return r.command.Run(args...) return r.command.Run(args...)
} }
func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error { func (r *rule) Delete(family family.Type, tableName string, chainName string, handle uint64) error {
args := []string{"delete", "rule", family.String(), tableName, chainName, "handle", strconv.Itoa(int(handle))} args := nftCommand.RuleDelete(family, tableName, chainName, handle)
return r.command.Run(args...) return r.command.Run(args...)
} }
+4 -3
View File
@@ -4,6 +4,7 @@ import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft" "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family" "git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
) )
type table struct { type table struct {
@@ -17,16 +18,16 @@ func New(command contract.Command) nft.Table {
} }
func (t *table) Add(family family.Type, tableName string) error { func (t *table) Add(family family.Type, tableName string) error {
args := []string{"add", "table", family.String(), tableName} args := nftCommand.TableAdd(family, tableName)
return t.command.Run(args...) return t.command.Run(args...)
} }
func (t *table) Delete(family family.Type, tableName string) error { func (t *table) Delete(family family.Type, tableName string) error {
args := []string{"delete", "table", family.String(), tableName} args := nftCommand.TableDelete(family, tableName)
return t.command.Run(args...) return t.command.Run(args...)
} }
func (t *table) Clear(family family.Type, tableName string) error { func (t *table) Clear(family family.Type, tableName string) error {
args := []string{"flush", "table", family.String(), tableName} args := nftCommand.TableClear(family, tableName)
return t.command.Run(args...) return t.command.Run(args...)
} }
+9 -1
View File
@@ -9,6 +9,7 @@ import (
nftContract "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft" nftContract "git.kor-elf.net/kor-elf-shield/go-nftables-client/contract/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/chain" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/chain"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
nftCommand "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/pkg/nft"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/rule" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/rule"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/table" "git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/table"
) )
@@ -50,7 +51,7 @@ func NewWithPath(path string) (contract.NFT, error) {
} }
func (n *nft) Clear() error { func (n *nft) Clear() error {
args := []string{"flush", "ruleset"} args := nftCommand.Clear()
return n.command.Run(args...) return n.command.Run(args...)
} }
@@ -104,6 +105,13 @@ func (n *nft) Command() contract.Command {
return n.command return n.command
} }
func (n *nft) ExecuteBatchAfterCheck(batch contract.Batch) error {
if err := batch.Check(n.command); err != nil {
return err
}
return n.command.Run(batch.Args()...)
}
func (n *nft) ExecuteBatch(batch contract.Batch) error { func (n *nft) ExecuteBatch(batch contract.Batch) error {
return n.command.Run(batch.Args()...) return n.command.Run(batch.Args()...)
} }