ソースを参照

Merge pull request #57 from mars1024/bugfix/isnotexist_ip6tables

make iptables Error judge with protocal to adapt both ipv4 and ipv6
Casey Callendrello 6 年 前
コミット
8b3e48f1b4
3 ファイル変更69 行追加4 行削除
  1. 1 0
      .gitignore
  2. 6 4
      iptables/iptables.go
  3. 62 0
      iptables/iptables_test.go

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+.idea

+ 6 - 4
iptables/iptables.go

@@ -31,6 +31,7 @@ type Error struct {
 	exec.ExitError
 	cmd        exec.Cmd
 	msg        string
+	proto      Protocol
 	exitStatus *int //for overriding
 }
 
@@ -48,8 +49,8 @@ func (e *Error) Error() string {
 // IsNotExist returns true if the error is due to the chain or rule not existing
 func (e *Error) IsNotExist() bool {
 	return e.ExitStatus() == 1 &&
-		(e.msg == "iptables: Bad rule (does a matching rule exist in that chain?).\n" ||
-			e.msg == "iptables: No chain/target/match by that name.\n")
+		(e.msg == fmt.Sprintf("%s: Bad rule (does a matching rule exist in that chain?).\n", getIptablesCommand(e.proto)) ||
+			e.msg == fmt.Sprintf("%s: No chain/target/match by that name.\n", getIptablesCommand(e.proto)))
 }
 
 // Protocol to differentiate between IPv4 and IPv6
@@ -282,7 +283,8 @@ func (ipt *IPTables) executeList(args []string) ([]string, error) {
 		v := 1
 		return nil, &Error{
 			cmd:        exec.Cmd{Args: args},
-			msg:        "iptables: No chain/target/match by that name.",
+			msg:        fmt.Sprintf("%s: No chain/target/match by that name.\n", getIptablesCommand(ipt.proto)),
+			proto:      ipt.proto,
 			exitStatus: &v,
 		}
 	}
@@ -385,7 +387,7 @@ func (ipt *IPTables) runWithOutput(args []string, stdout io.Writer) error {
 	if err := cmd.Run(); err != nil {
 		switch e := err.(type) {
 		case *exec.ExitError:
-			return &Error{*e, cmd, stderr.String(), nil}
+			return &Error{*e, cmd, stderr.String(), ipt.proto, nil}
 		default:
 			return err
 		}

+ 62 - 0
iptables/iptables_test.go

@@ -418,6 +418,68 @@ func TestIsNotExist(t *testing.T) {
 	}
 }
 
+func TestIsNotExistForIPv6(t *testing.T) {
+	ipt, err := NewWithProtocol(ProtocolIPv6)
+	if err != nil {
+		t.Fatalf("failed to init: %v", err)
+	}
+	// Create a chain, add a rule
+	chainName := randChain(t)
+	err = ipt.NewChain("filter", chainName)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer func() {
+		ipt.ClearChain("filter", chainName)
+		ipt.DeleteChain("filter", chainName)
+	}()
+
+	err = ipt.Append("filter", chainName, "-p", "tcp", "-j", "DROP")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Delete rule twice
+	err = ipt.Delete("filter", chainName, "-p", "tcp", "-j", "DROP")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = ipt.Delete("filter", chainName, "-p", "tcp", "-j", "DROP")
+	if err == nil {
+		t.Fatal("delete twice got no error...")
+	}
+
+	e, ok := err.(*Error)
+	if !ok {
+		t.Fatalf("Got wrong error type, expected iptables.Error, got %T", err)
+	}
+
+	if !e.IsNotExist() {
+		t.Fatal("IsNotExist returned false, expected true")
+	}
+
+	// Delete chain
+	err = ipt.DeleteChain("filter", chainName)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = ipt.DeleteChain("filter", chainName)
+	if err == nil {
+		t.Fatal("deletechain twice got no error...")
+	}
+
+	e, ok = err.(*Error)
+	if !ok {
+		t.Fatalf("Got wrong error type, expected iptables.Error, got %T", err)
+	}
+
+	if !e.IsNotExist() {
+		t.Fatal("IsNotExist returned false, expected true")
+	}
+}
+
 func TestFilterRuleOutput(t *testing.T) {
 	testCases := []struct {
 		name string