util/iptables: check for and use new iptables-restore 'wait' argument

iptables-restore did not previously perform any locking, meaning that
when callers (like kube-proxy) asked iptables-restore to write large
numbers of rules, the iptables-restore process might run in parallel
with other 'iptables' invocations in kubelet (hostports), docker,
and other software.  This causes errors like:

"CNI request failed with status 400: 'Failed to ensure that nat chain
POSTROUTING jumps to MASQUERADE: error checking rule: exit status 4:
iptables: Resource temporarily  unavailable."

or from Docker

"Failed to allocate and map port 1095-1095: iptables failed:
iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 1095
-j DNAT --to-destination 10.1.0.2:1095 ! -i lbr0: iptables:
Resource temporarily unavailable.\n (exit status 4)"

iptables-restore "wait" functionality was added in iptables git
commit 999eaa241212d3952ddff39a99d0d55a74e3639e but is NOT YET
in a released version of iptables.

See also https://bugzilla.redhat.com/show_bug.cgi?id=1417234
pull/6/head
Dan Williams 2017-03-23 11:54:34 -05:00
parent ad964e717f
commit 4cd6d34a0b
2 changed files with 301 additions and 98 deletions

View File

@ -124,12 +124,13 @@ const MinWait2Version = "1.4.22"
// runner implements Interface in terms of exec("iptables").
type runner struct {
mu sync.Mutex
exec utilexec.Interface
dbus utildbus.Interface
protocol Protocol
hasCheck bool
waitFlag []string
mu sync.Mutex
exec utilexec.Interface
dbus utildbus.Interface
protocol Protocol
hasCheck bool
waitFlag []string
restoreWaitFlag []string
reloadFuncs []func()
signal chan *godbus.Signal
@ -142,12 +143,14 @@ func New(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol) In
glog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err)
vstring = MinCheckVersion
}
runner := &runner{
exec: exec,
dbus: dbus,
protocol: protocol,
hasCheck: getIPTablesHasCheckCommand(vstring),
waitFlag: getIPTablesWaitFlag(vstring),
exec: exec,
dbus: dbus,
protocol: protocol,
hasCheck: getIPTablesHasCheckCommand(vstring),
waitFlag: getIPTablesWaitFlag(vstring),
restoreWaitFlag: getIPTablesRestoreWaitFlag(exec),
}
runner.connectToFirewallD()
return runner
@ -335,8 +338,9 @@ func (runner *runner) restoreInternal(args []string, data []byte, flush FlushFla
}
// run the command and return the output or an error including the output and error
glog.V(4).Infof("running iptables-restore %v", args)
cmd := runner.exec.Command(cmdIPTablesRestore, args...)
fullArgs := append(runner.restoreWaitFlag, args...)
glog.V(4).Infof("running iptables-restore %v", fullArgs)
cmd := runner.exec.Command(cmdIPTablesRestore, fullArgs...)
cmd.SetStdin(bytes.NewBuffer(data))
b, err := cmd.CombinedOutput()
if err != nil {
@ -519,6 +523,46 @@ func getIPTablesVersionString(exec utilexec.Interface) (string, error) {
return match[1], nil
}
// Checks if iptables-restore has a "wait" flag
// --wait support landed in v1.6.1+ right before --version support, so
// any version of iptables-restore that supports --version will also
// support --wait
func getIPTablesRestoreWaitFlag(exec utilexec.Interface) []string {
vstring, err := getIPTablesRestoreVersionString(exec)
if err != nil || vstring == "" {
glog.V(3).Infof("couldn't get iptables-restore version; assuming it doesn't support --wait")
return nil
}
if _, err := utilversion.ParseGeneric(vstring); err != nil {
glog.V(3).Infof("couldn't parse iptables-restore version; assuming it doesn't support --wait")
return nil
}
return []string{"--wait=2"}
}
// getIPTablesRestoreVersionString runs "iptables-restore --version" to get the version string
// in the form "X.X.X"
func getIPTablesRestoreVersionString(exec utilexec.Interface) (string, error) {
// this doesn't access mutable state so we don't need to use the interface / runner
// iptables-restore hasn't always had --version, and worse complains
// about unrecognized commands but doesn't exit when it gets them.
// Work around that by setting stdin to nothing so it exits immediately.
cmd := exec.Command(cmdIPTablesRestore, "--version")
cmd.SetStdin(bytes.NewReader([]byte{}))
bytes, err := cmd.CombinedOutput()
if err != nil {
return "", err
}
versionMatcher := regexp.MustCompile("v([0-9]+(\\.[0-9]+)+)")
match := versionMatcher.FindStringSubmatch(string(bytes))
if match == nil {
return "", fmt.Errorf("no iptables version found in string: %s", bytes)
}
return match[1], nil
}
// goroutine to listen for D-Bus signals
func (runner *runner) dbusSignalHandler(bus utildbus.Connection) {
firewalld := bus.Object(firewalldName, firewalldPath)

View File

@ -41,6 +41,8 @@ func testEnsureChain(t *testing.T, protocol Protocol) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
// Exists.
@ -55,6 +57,7 @@ func testEnsureChain(t *testing.T, protocol Protocol) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), protocol)
@ -67,12 +70,12 @@ func testEnsureChain(t *testing.T, protocol Protocol) {
if exists {
t.Errorf("expected exists = false")
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
cmd := getIPTablesCommand(protocol)
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll(cmd, "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll(cmd, "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
// Exists.
exists, err = runner.EnsureChain(TableNAT, Chain("FOOBAR"))
@ -102,6 +105,8 @@ func TestFlushChain(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
// Failure.
@ -113,6 +118,7 @@ func TestFlushChain(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -122,11 +128,11 @@ func TestFlushChain(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-F", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-F", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
// Failure.
err = runner.FlushChain(TableNAT, Chain("FOOBAR"))
@ -140,6 +146,8 @@ func TestDeleteChain(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
// Failure.
@ -151,6 +159,7 @@ func TestDeleteChain(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -160,11 +169,11 @@ func TestDeleteChain(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-X", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-X", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
// Failure.
err = runner.DeleteChain(TableNAT, Chain("FOOBAR"))
@ -178,6 +187,8 @@ func TestEnsureRuleAlreadyExists(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
},
@ -186,6 +197,8 @@ func TestEnsureRuleAlreadyExists(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Success of that exec means "done".
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
@ -199,11 +212,11 @@ func TestEnsureRuleAlreadyExists(t *testing.T) {
if !exists {
t.Errorf("expected exists = true")
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
}
@ -212,6 +225,8 @@ func TestEnsureRuleNew(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Status 1 on the first call.
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
// Success on the second call.
@ -222,6 +237,8 @@ func TestEnsureRuleNew(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Failure of that means create it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
@ -236,11 +253,11 @@ func TestEnsureRuleNew(t *testing.T) {
if exists {
t.Errorf("expected exists = false")
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 4 {
t.Errorf("expected 4 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3])
}
}
@ -249,6 +266,8 @@ func TestEnsureRuleErrorChecking(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Status 2 on the first call.
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 2} },
},
@ -257,6 +276,8 @@ func TestEnsureRuleErrorChecking(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Failure of that means create it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
@ -267,8 +288,8 @@ func TestEnsureRuleErrorChecking(t *testing.T) {
if err == nil {
t.Errorf("expected failure")
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
}
@ -277,6 +298,8 @@ func TestEnsureRuleErrorCreating(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Status 1 on the first call.
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
// Status 1 on the second call.
@ -287,6 +310,8 @@ func TestEnsureRuleErrorCreating(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Failure of that means create it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
@ -298,8 +323,8 @@ func TestEnsureRuleErrorCreating(t *testing.T) {
if err == nil {
t.Errorf("expected failure")
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 4 {
t.Errorf("expected 4 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
}
@ -308,6 +333,8 @@ func TestDeleteRuleAlreadyExists(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Status 1 on the first call.
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
@ -316,6 +343,8 @@ func TestDeleteRuleAlreadyExists(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Failure of that exec means "does not exist".
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
@ -326,11 +355,11 @@ func TestDeleteRuleAlreadyExists(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
}
@ -339,6 +368,8 @@ func TestDeleteRuleNew(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success on the first call.
func() ([]byte, error) { return []byte{}, nil },
// Success on the second call.
@ -349,6 +380,8 @@ func TestDeleteRuleNew(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Success of that means delete it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
@ -360,11 +393,11 @@ func TestDeleteRuleNew(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 4 {
t.Errorf("expected 4 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-D", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-D", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3])
}
}
@ -373,6 +406,8 @@ func TestDeleteRuleErrorChecking(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Status 2 on the first call.
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 2} },
},
@ -381,6 +416,8 @@ func TestDeleteRuleErrorChecking(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Failure of that means create it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
@ -391,8 +428,8 @@ func TestDeleteRuleErrorChecking(t *testing.T) {
if err == nil {
t.Errorf("expected failure")
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
}
@ -401,6 +438,8 @@ func TestDeleteRuleErrorCreating(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success on the first call.
func() ([]byte, error) { return []byte{}, nil },
// Status 1 on the second call.
@ -411,6 +450,8 @@ func TestDeleteRuleErrorCreating(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// The second Command() call is checking the rule. Success of that means delete it.
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
@ -422,8 +463,8 @@ func TestDeleteRuleErrorCreating(t *testing.T) {
if err == nil {
t.Errorf("expected failure")
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 4 {
t.Errorf("expected 4 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
}
@ -573,12 +614,17 @@ func TestWaitFlagUnavailable(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.4.19"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
},
}
fexec := exec.FakeExec{
CommandScript: []exec.FakeCommandAction{
// iptables version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
// iptables-restore version check
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
@ -589,11 +635,11 @@ func TestWaitFlagUnavailable(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w", "-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if sets.NewString(fcmd.CombinedOutputLog[2]...).HasAny("-w", "-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
}
@ -602,6 +648,8 @@ func TestWaitFlagOld(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.4.20"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
},
@ -610,6 +658,7 @@ func TestWaitFlagOld(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -618,14 +667,14 @@ func TestWaitFlagOld(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-w") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-w") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if sets.NewString(fcmd.CombinedOutputLog[2]...).HasAny("-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
}
@ -634,6 +683,8 @@ func TestWaitFlagNew(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.4.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// Success.
func() ([]byte, error) { return []byte{}, nil },
},
@ -642,6 +693,7 @@ func TestWaitFlagNew(t *testing.T) {
CommandScript: []exec.FakeCommandAction{
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -650,14 +702,14 @@ func TestWaitFlagNew(t *testing.T) {
if err != nil {
t.Errorf("expected success, got %v", err)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-w2") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if sets.NewString(fcmd.CombinedOutputLog[1]...).HasAny("-w") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if sets.NewString(fcmd.CombinedOutputLog[2]...).HasAny("-w") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
}
@ -673,6 +725,8 @@ func TestReload(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.4.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
// first reload
// EnsureChain
@ -700,6 +754,7 @@ func TestReload(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
@ -732,25 +787,25 @@ func TestReload(t *testing.T) {
<-reloaded
<-reloaded
if fcmd.CombinedOutputCalls != 4 {
t.Errorf("expected 4 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 5 {
t.Errorf("expected 5 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
}
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
if !sets.NewString(fcmd.CombinedOutputLog[3]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3])
}
if !sets.NewString(fcmd.CombinedOutputLog[4]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[4])
}
go func() { time.Sleep(time.Second / 100); reloaded <- true }()
dbusConn.EmitSignal(firewalldName, firewalldPath, firewalldInterface, "DefaultZoneChanged", "public")
dbusConn.EmitSignal("org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "NameOwnerChanged", "io.k8s.Something", "", ":1.1")
<-reloaded
if fcmd.CombinedOutputCalls != 4 {
if fcmd.CombinedOutputCalls != 5 {
t.Errorf("Incorrect signal caused a reload")
}
@ -758,18 +813,18 @@ func TestReload(t *testing.T) {
<-reloaded
<-reloaded
if fcmd.CombinedOutputCalls != 7 {
t.Errorf("expected 7 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 8 {
t.Errorf("expected 8 CombinedOutput() calls total, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[4]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[4])
}
if !sets.NewString(fcmd.CombinedOutputLog[5]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
if !sets.NewString(fcmd.CombinedOutputLog[5]...).HasAll("iptables", "-t", "nat", "-N", "FOOBAR") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[5])
}
if !sets.NewString(fcmd.CombinedOutputLog[6]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
if !sets.NewString(fcmd.CombinedOutputLog[6]...).HasAll("iptables", "-t", "nat", "-C", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[6])
}
if !sets.NewString(fcmd.CombinedOutputLog[7]...).HasAll("iptables", "-t", "nat", "-A", "OUTPUT", "abc", "123") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[7])
}
}
func TestSave(t *testing.T) {
@ -785,6 +840,8 @@ COMMIT
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
func() ([]byte, error) { return []byte(output), nil },
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
@ -794,6 +851,7 @@ COMMIT
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -808,11 +866,11 @@ COMMIT
t.Errorf("expected output to be equal to mocked one, got %v", o)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables-save", "-t", "nat") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables-save", "-t", "nat") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
// Failure.
@ -835,6 +893,8 @@ COMMIT
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
func() ([]byte, error) { return []byte(output), nil },
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
@ -844,6 +904,7 @@ COMMIT
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -858,11 +919,11 @@ COMMIT
t.Errorf("expected output to be equal to mocked one, got %v", o)
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll("iptables-save") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
if !sets.NewString(fcmd.CombinedOutputLog[2]...).HasAll("iptables-save") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
// Failure.
@ -877,6 +938,8 @@ func TestRestore(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
func() ([]byte, error) { return []byte{}, nil },
func() ([]byte, error) { return []byte{}, nil },
func() ([]byte, error) { return []byte{}, nil },
@ -892,6 +955,7 @@ func TestRestore(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -903,7 +967,7 @@ func TestRestore(t *testing.T) {
t.Errorf("expected success, got %v", err)
}
commandSet := sets.NewString(fcmd.CombinedOutputLog[1]...)
commandSet := sets.NewString(fcmd.CombinedOutputLog[2]...)
if !commandSet.HasAll("iptables-restore", "-T", string(TableNAT), "--counters") || commandSet.HasAny("--noflush") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
}
@ -914,7 +978,7 @@ func TestRestore(t *testing.T) {
t.Errorf("expected success, got %v", err)
}
commandSet = sets.NewString(fcmd.CombinedOutputLog[2]...)
commandSet = sets.NewString(fcmd.CombinedOutputLog[3]...)
if !commandSet.HasAll("iptables-restore", "-T", string(TableNAT)) || commandSet.HasAny("--noflush", "--counters") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
@ -925,7 +989,7 @@ func TestRestore(t *testing.T) {
t.Errorf("expected success, got %v", err)
}
commandSet = sets.NewString(fcmd.CombinedOutputLog[3]...)
commandSet = sets.NewString(fcmd.CombinedOutputLog[4]...)
if !commandSet.HasAll("iptables-restore", "-T", string(TableNAT), "--noflush", "--counters") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[3])
}
@ -936,13 +1000,13 @@ func TestRestore(t *testing.T) {
t.Errorf("expected success, got %v", err)
}
commandSet = sets.NewString(fcmd.CombinedOutputLog[4]...)
commandSet = sets.NewString(fcmd.CombinedOutputLog[5]...)
if !commandSet.HasAll("iptables-restore", "-T", string(TableNAT), "--noflush") || commandSet.HasAny("--counters") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[4])
}
if fcmd.CombinedOutputCalls != 5 {
t.Errorf("expected 5 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 6 {
t.Errorf("expected 6 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
// Failure.
@ -958,6 +1022,8 @@ func TestRestoreAll(t *testing.T) {
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
func() ([]byte, error) { return []byte{}, nil },
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
@ -967,6 +1033,7 @@ func TestRestoreAll(t *testing.T) {
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
@ -977,13 +1044,105 @@ func TestRestoreAll(t *testing.T) {
t.Errorf("expected success, got %v", err)
}
commandSet := sets.NewString(fcmd.CombinedOutputLog[1]...)
commandSet := sets.NewString(fcmd.CombinedOutputLog[2]...)
if !commandSet.HasAll("iptables-restore", "--counters", "--noflush") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[1])
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if fcmd.CombinedOutputCalls != 2 {
t.Errorf("expected 2 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
// Failure.
err = runner.Restore(TableNAT, []byte{}, FlushTables, RestoreCounters)
if err == nil {
t.Errorf("expected failure")
}
}
// TestRestoreAllWait tests that the "wait" flag is passed to a compatible iptables-restore
func TestRestoreAllWait(t *testing.T) {
fcmd := exec.FakeCmd{
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("iptables-restore v1.9.22"), nil },
func() ([]byte, error) { return []byte{}, nil },
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
}
fexec := exec.FakeExec{
CommandScript: []exec.FakeCommandAction{
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
defer runner.Destroy()
err := runner.RestoreAll([]byte{}, NoFlushTables, RestoreCounters)
if err != nil {
t.Errorf("expected success, got %v", err)
}
commandSet := sets.NewString(fcmd.CombinedOutputLog[2]...)
if !commandSet.HasAll("iptables-restore", "--wait=2", "--counters", "--noflush") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
// Failure.
err = runner.Restore(TableNAT, []byte{}, FlushTables, RestoreCounters)
if err == nil {
t.Errorf("expected failure")
}
}
// TestRestoreAllWaitOldIptablesRestore tests that the "wait" flag is not passed
// to a in-compatible iptables-restore
func TestRestoreAllWaitOldIptablesRestore(t *testing.T) {
fcmd := exec.FakeCmd{
CombinedOutputScript: []exec.FakeCombinedOutputAction{
// iptables version check
func() ([]byte, error) { return []byte("iptables v1.9.22"), nil },
// iptables-restore version check
func() ([]byte, error) { return []byte("unrecognized option: --version"), nil },
func() ([]byte, error) { return []byte{}, nil },
func() ([]byte, error) { return nil, &exec.FakeExitError{Status: 1} },
},
}
fexec := exec.FakeExec{
CommandScript: []exec.FakeCommandAction{
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
func(cmd string, args ...string) exec.Cmd { return exec.InitFakeCmd(&fcmd, cmd, args...) },
},
}
runner := New(&fexec, dbus.NewFake(nil, nil), ProtocolIpv4)
defer runner.Destroy()
err := runner.RestoreAll([]byte{}, NoFlushTables, RestoreCounters)
if err != nil {
t.Errorf("expected success, got %v", err)
}
commandSet := sets.NewString(fcmd.CombinedOutputLog[2]...)
if !commandSet.HasAll("iptables-restore", "--counters", "--noflush") {
t.Errorf("wrong CombinedOutput() log, got %s", fcmd.CombinedOutputLog[2])
}
if commandSet.HasAny("--wait=2") {
t.Errorf("wrong CombinedOutput() log (unexpected --wait=2 option), got %s", fcmd.CombinedOutputLog[2])
}
if fcmd.CombinedOutputCalls != 3 {
t.Errorf("expected 3 CombinedOutput() calls, got %d", fcmd.CombinedOutputCalls)
}
// Failure.