Refactor table management to use a dedicated API and improve command handling.

This commit is contained in:
2025-10-19 22:50:14 +05:00
parent d056f5dbf8
commit 5b19993343
5 changed files with 107 additions and 52 deletions

View File

@@ -0,0 +1,37 @@
package command
import (
"errors"
"os/exec"
)
type NFT interface {
Run(arg ...string) error
}
type execNFT struct {
nftPath string
}
func New(path string) (NFT, error) {
if err := checkingNFT(path); err != nil {
return nil, err
}
return &execNFT{
nftPath: path,
}, nil
}
func (r *execNFT) Run(arg ...string) error {
cmd := exec.Command(r.nftPath, arg...)
out, err := cmd.CombinedOutput()
if err != nil {
if len(out) > 0 {
return errors.New(string(out))
}
return err
}
return nil
}

51
internal/command/utils.go Normal file
View File

@@ -0,0 +1,51 @@
package command
import (
"errors"
"fmt"
"os/exec"
"regexp"
"strings"
)
func checkingNFT(path string) error {
if path == "" {
return errors.New("path is empty")
}
cmd := exec.Command(path, "-V")
out, err := cmd.CombinedOutput()
if err != nil {
return errors.New("nftables not found")
}
lines := regexp.MustCompile("\r?\n").Split(strings.TrimSpace(string(out)), -1)
json := false
for index, line := range lines {
line = strings.TrimSpace(line)
if index == 0 {
if !strings.HasPrefix(line, "nftables") {
return errors.New("nftables not found")
}
continue
}
if strings.HasPrefix(line, "json:") && strings.HasSuffix(line, "yes") {
json = true
}
}
if !json {
return errors.New("nftables disabled json")
}
cmd = exec.Command(path, "list", "ruleset")
out, err = cmd.CombinedOutput()
if err != nil {
return fmt.Errorf("nftables is not available or not supported by the kernel: %s", string(out))
}
return nil
}

51
internal/table/table.go Normal file
View File

@@ -0,0 +1,51 @@
package table
import (
"git.kor-elf.net/kor-elf-shield/go-nftables-client/family"
"git.kor-elf.net/kor-elf-shield/go-nftables-client/internal/command"
)
type API interface {
// AddTable adds a new table.
//
// This command is equivalent to:
// nft add table (ip|ip6|inet|arp|bridge) {table_name}
Add(family family.Type, tableName string) error
// DeleteTable deletes a table.
//
// This command is equivalent to:
// nft delete table (ip|ip6|inet|arp|bridge) {table_name}
Delete(family family.Type, tableName string) error
// ClearTable clears all rules in a table.
//
// This command is equivalent to:
// nft flush table (ip|ip6|inet|arp|bridge) {table_name}
Clear(family family.Type, tableName string) error
}
type table struct {
command command.NFT
}
func New(command command.NFT) API {
return &table{
command: command,
}
}
func (t *table) Add(family family.Type, tableName string) error {
args := []string{"add", "table", family.String(), tableName}
return t.command.Run(args...)
}
func (t *table) Delete(family family.Type, tableName string) error {
args := []string{"delete", "table", family.String(), tableName}
return t.command.Run(args...)
}
func (t *table) Clear(family family.Type, tableName string) error {
args := []string{"flush", "table", family.String(), tableName}
return t.command.Run(args...)
}