From bcfae7e1ed93d5c2000aebdbb2e89f32352dc422 Mon Sep 17 00:00:00 2001 From: Wojciech Tyczynski Date: Thu, 18 May 2017 11:51:07 +0200 Subject: [PATCH] Extend Iptables interface with SaveInto --- pkg/kubelet/network/hostport/fake_iptables.go | 19 ++++++++++++------- pkg/kubelet/prober/prober.go | 8 ++++++++ pkg/probe/exec/exec_test.go | 6 ++++++ pkg/util/exec/exec.go | 12 ++++++++++++ pkg/util/exec/fake_exec.go | 9 +++++++++ pkg/util/iptables/iptables.go | 16 ++++++++++++++++ pkg/util/iptables/testing/fake.go | 6 ++++++ 7 files changed, 69 insertions(+), 7 deletions(-) diff --git a/pkg/kubelet/network/hostport/fake_iptables.go b/pkg/kubelet/network/hostport/fake_iptables.go index e6dde8f52c..08faa77dd8 100644 --- a/pkg/kubelet/network/hostport/fake_iptables.go +++ b/pkg/kubelet/network/hostport/fake_iptables.go @@ -228,22 +228,27 @@ func saveChain(chain *fakeChain, data *bytes.Buffer) { } func (f *fakeIPTables) Save(tableName utiliptables.Table) ([]byte, error) { + data := bytes.NewBuffer(nil) + err := f.SaveInto(tableName, data) + return data.Bytes(), err +} + +func (f *fakeIPTables) SaveInto(tableName utiliptables.Table, buffer *bytes.Buffer) error { table, err := f.getTable(tableName) if err != nil { - return nil, err + return err } - data := bytes.NewBuffer(nil) - data.WriteString(fmt.Sprintf("*%s\n", table.name)) + buffer.WriteString(fmt.Sprintf("*%s\n", table.name)) rules := bytes.NewBuffer(nil) for _, chain := range table.chains { - data.WriteString(fmt.Sprintf(":%s - [0:0]\n", string(chain.name))) + buffer.WriteString(fmt.Sprintf(":%s - [0:0]\n", string(chain.name))) saveChain(chain, rules) } - data.Write(rules.Bytes()) - data.WriteString("COMMIT\n") - return data.Bytes(), nil + buffer.Write(rules.Bytes()) + buffer.WriteString("COMMIT\n") + return nil } func (f *fakeIPTables) restore(restoreTableName utiliptables.Table, data []byte, flush utiliptables.FlushFlag) error { diff --git a/pkg/kubelet/prober/prober.go b/pkg/kubelet/prober/prober.go index acd70bb1ae..827c1dab89 100644 --- a/pkg/kubelet/prober/prober.go +++ b/pkg/kubelet/prober/prober.go @@ -237,6 +237,10 @@ func (pb *prober) newExecInContainer(container v1.Container, containerID kubecon }} } +func (eic execInContainer) Run() error { + return fmt.Errorf("unimplemented") +} + func (eic execInContainer) CombinedOutput() ([]byte, error) { return eic.run() } @@ -257,6 +261,10 @@ func (eic execInContainer) SetStdout(out io.Writer) { //unimplemented } +func (eic execInContainer) SetStderr(out io.Writer) { + //unimplemented +} + func (eic execInContainer) Stop() { //unimplemented } diff --git a/pkg/probe/exec/exec_test.go b/pkg/probe/exec/exec_test.go index bd86777d9e..3621983059 100644 --- a/pkg/probe/exec/exec_test.go +++ b/pkg/probe/exec/exec_test.go @@ -30,6 +30,10 @@ type FakeCmd struct { err error } +func (f *FakeCmd) Run() error { + return nil +} + func (f *FakeCmd) CombinedOutput() ([]byte, error) { return f.out, f.err } @@ -44,6 +48,8 @@ func (f *FakeCmd) SetStdin(in io.Reader) {} func (f *FakeCmd) SetStdout(out io.Writer) {} +func (f *FakeCmd) SetStderr(out io.Writer) {} + func (f *FakeCmd) Stop() {} type fakeExitError struct { diff --git a/pkg/util/exec/exec.go b/pkg/util/exec/exec.go index 327ddf5bce..f43bfa7a17 100644 --- a/pkg/util/exec/exec.go +++ b/pkg/util/exec/exec.go @@ -41,6 +41,8 @@ type Interface interface { // As more functionality is needed, this can grow. Since Cmd is a struct, we will have // to replace fields with get/set method pairs. type Cmd interface { + // Run runs the command to the completion. + Run() error // CombinedOutput runs the command and returns its combined standard output // and standard error. This follows the pattern of package os/exec. CombinedOutput() ([]byte, error) @@ -49,6 +51,7 @@ type Cmd interface { SetDir(dir string) SetStdin(in io.Reader) SetStdout(out io.Writer) + SetStderr(out io.Writer) // Stops the command by sending SIGTERM. It is not guaranteed the // process will stop before this function returns. If the process is not // responding, an internal timer function will send a SIGKILL to force @@ -99,6 +102,15 @@ func (cmd *cmdWrapper) SetStdout(out io.Writer) { cmd.Stdout = out } +func (cmd *cmdWrapper) SetStderr(out io.Writer) { + cmd.Stderr = out +} + +// Run is part of the Cmd interface. +func (cmd *cmdWrapper) Run() error { + return (*osexec.Cmd)(cmd).Run() +} + // CombinedOutput is part of the Cmd interface. func (cmd *cmdWrapper) CombinedOutput() ([]byte, error) { out, err := (*osexec.Cmd)(cmd).CombinedOutput() diff --git a/pkg/util/exec/fake_exec.go b/pkg/util/exec/fake_exec.go index b87265099a..e3741dca42 100644 --- a/pkg/util/exec/fake_exec.go +++ b/pkg/util/exec/fake_exec.go @@ -52,6 +52,7 @@ type FakeCmd struct { Dirs []string Stdin io.Reader Stdout io.Writer + Stderr io.Writer } func InitFakeCmd(fake *FakeCmd, cmd string, args ...string) Cmd { @@ -73,6 +74,14 @@ func (fake *FakeCmd) SetStdout(out io.Writer) { fake.Stdout = out } +func (fake *FakeCmd) SetStderr(out io.Writer) { + fake.Stderr = out +} + +func (fake *FakeCmd) Run() error { + return fmt.Errorf("unimplemented") +} + func (fake *FakeCmd) CombinedOutput() ([]byte, error) { if fake.CombinedOutputCalls > len(fake.CombinedOutputScript)-1 { panic("ran out of CombinedOutput() actions") diff --git a/pkg/util/iptables/iptables.go b/pkg/util/iptables/iptables.go index 1b369b3294..d6a679a11a 100644 --- a/pkg/util/iptables/iptables.go +++ b/pkg/util/iptables/iptables.go @@ -56,6 +56,8 @@ type Interface interface { IsIpv6() bool // Save calls `iptables-save` for table. Save(table Table) ([]byte, error) + // SaveInto calls `iptables-save` for table and stores result in a given buffer. + SaveInto(table Table, buffer *bytes.Buffer) error // Restore runs `iptables-restore` passing data through []byte. // table is the Table to restore // data should be formatted like the output of Save() @@ -315,6 +317,20 @@ func (runner *runner) Save(table Table) ([]byte, error) { return runner.exec.Command(cmdIPTablesSave, args...).CombinedOutput() } +// SaveInto is part of Interface. +func (runner *runner) SaveInto(table Table, buffer *bytes.Buffer) error { + runner.mu.Lock() + defer runner.mu.Unlock() + + // run and return + args := []string{"-t", string(table)} + glog.V(4).Infof("running iptables-save %v", args) + cmd := runner.exec.Command(cmdIPTablesSave, args...) + cmd.SetStdout(buffer) + cmd.SetStderr(buffer) + return cmd.Run() +} + // Restore is part of Interface. func (runner *runner) Restore(table Table, data []byte, flush FlushFlag, counters RestoreCountersFlag) error { // setup args diff --git a/pkg/util/iptables/testing/fake.go b/pkg/util/iptables/testing/fake.go index 3ab40cf6dc..8d9ac7c070 100644 --- a/pkg/util/iptables/testing/fake.go +++ b/pkg/util/iptables/testing/fake.go @@ -17,6 +17,7 @@ limitations under the License. package testing import ( + "bytes" "fmt" "strings" @@ -78,6 +79,11 @@ func (f *FakeIPTables) Save(table iptables.Table) ([]byte, error) { return lines, nil } +func (f *FakeIPTables) SaveInto(table iptables.Table, buffer *bytes.Buffer) error { + buffer.Write(f.Lines) + return nil +} + func (*FakeIPTables) Restore(table iptables.Table, data []byte, flush iptables.FlushFlag, counters iptables.RestoreCountersFlag) error { return nil }