Skip to content

Commit 81cd27a

Browse files
committed
iptables: simplify version handling
1 parent a735c97 commit 81cd27a

File tree

5 files changed

+46
-114
lines changed

5 files changed

+46
-114
lines changed

pkg/kubelet/dockershim/network/hostport/fake_iptables.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,10 +52,6 @@ func NewFakeIPTables() *fakeIPTables {
5252
}
5353
}
5454

55-
func (f *fakeIPTables) GetVersion() (string, error) {
56-
return "1.4.21", nil
57-
}
58-
5955
func (f *fakeIPTables) getTable(tableName utiliptables.Table) (*fakeTable, error) {
6056
table, ok := f.tables[string(tableName)]
6157
if !ok {

pkg/util/iptables/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ go_test(
4545
"@io_bazel_rules_go//go/platform:linux": [
4646
"//pkg/util/dbus:go_default_library",
4747
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
48+
"//staging/src/k8s.io/apimachinery/pkg/util/version:go_default_library",
4849
"//vendor/k8s.io/utils/exec:go_default_library",
4950
"//vendor/k8s.io/utils/exec/testing:go_default_library",
5051
],

pkg/util/iptables/iptables.go

Lines changed: 34 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,6 @@ const (
4343

4444
// An injectable interface for running iptables commands. Implementations must be goroutine-safe.
4545
type Interface interface {
46-
// GetVersion returns the "X.Y.Z" version string for iptables.
47-
GetVersion() (string, error)
4846
// EnsureChain checks if the specified chain exists and, if not, creates it. If the chain existed, return true.
4947
EnsureChain(table Table, chain Chain) (bool, error)
5048
// FlushChain clears the specified chain. If the chain did not exist, return error.
@@ -121,12 +119,13 @@ const NoFlushTables FlushFlag = false
121119

122120
// Versions of iptables less than this do not support the -C / --check flag
123121
// (test whether a rule exists).
124-
const MinCheckVersion = "1.4.11"
122+
var MinCheckVersion = utilversion.MustParseGeneric("1.4.11")
125123

126124
// Minimum iptables versions supporting the -w and -w<seconds> flags
127-
const WaitMinVersion = "1.4.20"
128-
const WaitSecondsMinVersion = "1.4.22"
129-
const WaitRestoreMinVersion = "1.6.2"
125+
var WaitMinVersion = utilversion.MustParseGeneric("1.4.20")
126+
var WaitSecondsMinVersion = utilversion.MustParseGeneric("1.4.22")
127+
var WaitRestoreMinVersion = utilversion.MustParseGeneric("1.6.2")
128+
130129
const WaitString = "-w"
131130
const WaitSecondsValue = "5"
132131

@@ -151,10 +150,10 @@ type runner struct {
151150
// newInternal returns a new Interface which will exec iptables, and allows the
152151
// caller to change the iptables-restore lockfile path
153152
func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Protocol, lockfilePath string) Interface {
154-
vstring, err := getIPTablesVersionString(exec, protocol)
153+
version, err := getIPTablesVersion(exec, protocol)
155154
if err != nil {
156155
klog.Warningf("Error checking iptables version, assuming version at least %s: %v", MinCheckVersion, err)
157-
vstring = MinCheckVersion
156+
version = MinCheckVersion
158157
}
159158

160159
if lockfilePath == "" {
@@ -165,10 +164,10 @@ func newInternal(exec utilexec.Interface, dbus utildbus.Interface, protocol Prot
165164
exec: exec,
166165
dbus: dbus,
167166
protocol: protocol,
168-
hasCheck: getIPTablesHasCheckCommand(vstring),
167+
hasCheck: version.AtLeast(MinCheckVersion),
169168
hasListener: false,
170-
waitFlag: getIPTablesWaitFlag(vstring),
171-
restoreWaitFlag: getIPTablesRestoreWaitFlag(vstring),
169+
waitFlag: getIPTablesWaitFlag(version),
170+
restoreWaitFlag: getIPTablesRestoreWaitFlag(version),
172171
lockfilePath: lockfilePath,
173172
}
174173
return runner
@@ -215,11 +214,6 @@ func (runner *runner) connectToFirewallD() {
215214
go runner.dbusSignalHandler(bus)
216215
}
217216

218-
// GetVersion returns the version string.
219-
func (runner *runner) GetVersion() (string, error) {
220-
return getIPTablesVersionString(runner.exec, runner.protocol)
221-
}
222-
223217
// EnsureChain is part of Interface.
224218
func (runner *runner) EnsureChain(table Table, chain Chain) (bool, error) {
225219
fullArgs := makeFullArgs(table, chain)
@@ -540,83 +534,46 @@ func makeFullArgs(table Table, chain Chain, args ...string) []string {
540534
return append([]string{string(chain), "-t", string(table)}, args...)
541535
}
542536

543-
// Checks if iptables has the "-C" flag
544-
func getIPTablesHasCheckCommand(vstring string) bool {
545-
minVersion, err := utilversion.ParseGeneric(MinCheckVersion)
546-
if err != nil {
547-
klog.Errorf("MinCheckVersion (%s) is not a valid version string: %v", MinCheckVersion, err)
548-
return true
549-
}
550-
version, err := utilversion.ParseGeneric(vstring)
551-
if err != nil {
552-
klog.Errorf("vstring (%s) is not a valid version string: %v", vstring, err)
553-
return true
554-
}
555-
return version.AtLeast(minVersion)
556-
}
557-
558-
// Checks if iptables version has a "wait" flag
559-
func getIPTablesWaitFlag(vstring string) []string {
560-
version, err := utilversion.ParseGeneric(vstring)
561-
if err != nil {
562-
klog.Errorf("vstring (%s) is not a valid version string: %v", vstring, err)
563-
return nil
564-
}
565-
566-
minVersion, err := utilversion.ParseGeneric(WaitMinVersion)
567-
if err != nil {
568-
klog.Errorf("WaitMinVersion (%s) is not a valid version string: %v", WaitMinVersion, err)
569-
return nil
570-
}
571-
if version.LessThan(minVersion) {
572-
return nil
573-
}
574-
575-
minVersion, err = utilversion.ParseGeneric(WaitSecondsMinVersion)
576-
if err != nil {
577-
klog.Errorf("WaitSecondsMinVersion (%s) is not a valid version string: %v", WaitSecondsMinVersion, err)
578-
return nil
579-
}
580-
if version.LessThan(minVersion) {
581-
return []string{WaitString}
582-
}
583-
return []string{WaitString, WaitSecondsValue}
584-
}
585-
586-
// getIPTablesVersionString runs "iptables --version" to get the version string
587-
// in the form "X.X.X"
588-
func getIPTablesVersionString(exec utilexec.Interface, protocol Protocol) (string, error) {
537+
// getIPTablesVersion runs "iptables --version" and parses the returned version
538+
func getIPTablesVersion(exec utilexec.Interface, protocol Protocol) (*utilversion.Version, error) {
589539
// this doesn't access mutable state so we don't need to use the interface / runner
590540
iptablesCmd := iptablesCommand(protocol)
591541
bytes, err := exec.Command(iptablesCmd, "--version").CombinedOutput()
592542
if err != nil {
593-
return "", err
543+
return nil, err
594544
}
595545
versionMatcher := regexp.MustCompile("v([0-9]+(\\.[0-9]+)+)")
596546
match := versionMatcher.FindStringSubmatch(string(bytes))
597547
if match == nil {
598-
return "", fmt.Errorf("no iptables version found in string: %s", bytes)
548+
return nil, fmt.Errorf("no iptables version found in string: %s", bytes)
599549
}
600-
return match[1], nil
601-
}
602-
603-
// Checks if iptables-restore has a "wait" flag
604-
func getIPTablesRestoreWaitFlag(vstring string) []string {
605-
version, err := utilversion.ParseGeneric(vstring)
550+
version, err := utilversion.ParseGeneric(match[1])
606551
if err != nil {
607-
klog.Errorf("vstring (%s) is not a valid version string: %v", vstring, err)
608-
return nil
552+
return nil, fmt.Errorf("iptables version %q is not a valid version string: %v", match[1], err)
609553
}
610554

611-
minVersion, err := utilversion.ParseGeneric(WaitRestoreMinVersion)
612-
if err != nil {
613-
klog.Errorf("WaitRestoreMinVersion (%s) is not a valid version string: %v", WaitRestoreMinVersion, err)
555+
return version, nil
556+
}
557+
558+
// Checks if iptables version has a "wait" flag
559+
func getIPTablesWaitFlag(version *utilversion.Version) []string {
560+
switch {
561+
case version.AtLeast(WaitSecondsMinVersion):
562+
return []string{WaitString, WaitSecondsValue}
563+
case version.AtLeast(WaitMinVersion):
564+
return []string{WaitString}
565+
default:
614566
return nil
615567
}
616-
if version.LessThan(minVersion) {
568+
}
569+
570+
// Checks if iptables-restore has a "wait" flag
571+
func getIPTablesRestoreWaitFlag(version *utilversion.Version) []string {
572+
if version.AtLeast(WaitRestoreMinVersion) {
573+
return []string{WaitString, WaitSecondsValue}
574+
} else {
617575
return nil
618576
}
619-
return []string{WaitString, WaitSecondsValue}
620577
}
621578

622579
// goroutine to listen for D-Bus signals

pkg/util/iptables/iptables_test.go

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"time"
3030

3131
"k8s.io/apimachinery/pkg/util/sets"
32+
utilversion "k8s.io/apimachinery/pkg/util/version"
3233
"k8s.io/kubernetes/pkg/util/dbus"
3334
"k8s.io/utils/exec"
3435
fakeexec "k8s.io/utils/exec/testing"
@@ -52,14 +53,11 @@ func testIPTablesVersionCmds(t *testing.T, protocol Protocol) {
5253
CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{
5354
// iptables version response (for runner instantiation)
5455
func() ([]byte, error) { return []byte(iptablesCmd + version), nil },
55-
// iptables version response (for call to runner.GetVersion())
56-
func() ([]byte, error) { return []byte(iptablesCmd + version), nil },
5756
},
5857
}
5958
fexec := fakeexec.FakeExec{
6059
CommandScript: []fakeexec.FakeCommandAction{
6160
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
62-
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
6361
},
6462
}
6563
runner := New(&fexec, dbus.NewFake(nil, nil), protocol)
@@ -69,16 +67,6 @@ func testIPTablesVersionCmds(t *testing.T, protocol Protocol) {
6967
if !sets.NewString(fcmd.CombinedOutputLog[0]...).HasAll(iptablesCmd, "--version") {
7068
t.Errorf("%s runner instantiate: Expected cmd '%s --version', Got '%s'", protoStr, iptablesCmd, fcmd.CombinedOutputLog[0])
7169
}
72-
73-
_, err := runner.GetVersion()
74-
if err != nil {
75-
t.Errorf("%s GetVersion: Expected success, got %v", protoStr, err)
76-
}
77-
78-
// Check that proper iptables version command was used for runner.GetVersion
79-
if !sets.NewString(fcmd.CombinedOutputLog[1]...).HasAll(iptablesCmd, "--version") {
80-
t.Errorf("%s GetVersion: Expected cmd '%s --version', Got '%s'", protoStr, iptablesCmd, fcmd.CombinedOutputLog[2])
81-
}
8270
}
8371

8472
func TestIPTablesVersionCmdsIPv4(t *testing.T) {
@@ -485,14 +473,13 @@ func TestDeleteRuleErrorDeleting(t *testing.T) {
485473
func TestGetIPTablesHasCheckCommand(t *testing.T) {
486474
testCases := []struct {
487475
Version string
488-
Err bool
489476
Expected bool
490477
}{
491-
{"iptables v1.4.7", false, false},
492-
{"iptables v1.4.11", false, true},
493-
{"iptables v1.4.19.1", false, true},
494-
{"iptables v2.0.0", false, true},
495-
{"total junk", true, false},
478+
{"iptables v1.4.7", false},
479+
{"iptables v1.4.11", true},
480+
{"iptables v1.4.19.1", true},
481+
{"iptables v2.0.0", true},
482+
{"total junk", true},
496483
}
497484

498485
for _, testCase := range testCases {
@@ -506,15 +493,10 @@ func TestGetIPTablesHasCheckCommand(t *testing.T) {
506493
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
507494
},
508495
}
509-
version, err := getIPTablesVersionString(&fexec, ProtocolIpv4)
510-
if (err != nil) != testCase.Err {
511-
t.Errorf("Expected error: %v, Got error: %v", testCase.Err, err)
512-
}
513-
if err == nil {
514-
check := getIPTablesHasCheckCommand(version)
515-
if testCase.Expected != check {
516-
t.Errorf("Expected result: %v, Got result: %v", testCase.Expected, check)
517-
}
496+
ipt := New(&fexec, nil, ProtocolIpv4)
497+
runner := ipt.(*runner)
498+
if testCase.Expected != runner.hasCheck {
499+
t.Errorf("Expected result: %v, Got result: %v", testCase.Expected, runner.hasCheck)
518500
}
519501
}
520502
}
@@ -645,7 +627,7 @@ func TestIPTablesWaitFlag(t *testing.T) {
645627
}
646628

647629
for _, testCase := range testCases {
648-
result := getIPTablesWaitFlag(testCase.Version)
630+
result := getIPTablesWaitFlag(utilversion.MustParseGeneric(testCase.Version))
649631
if !reflect.DeepEqual(result, testCase.Result) {
650632
t.Errorf("For %s expected %v got %v", testCase.Version, testCase.Result, result)
651633
}

pkg/util/iptables/testing/fake.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,10 +48,6 @@ func NewFake() *FakeIPTables {
4848
return &FakeIPTables{}
4949
}
5050

51-
func (*FakeIPTables) GetVersion() (string, error) {
52-
return "0.0.0", nil
53-
}
54-
5551
func (*FakeIPTables) EnsureChain(table iptables.Table, chain iptables.Chain) (bool, error) {
5652
return true, nil
5753
}

0 commit comments

Comments
 (0)