...

Source file src/k8s.io/kubernetes/pkg/util/iptables/testing/fake_test.go

Documentation: k8s.io/kubernetes/pkg/util/iptables/testing

     1  //go:build linux
     2  // +build linux
     3  
     4  /*
     5  Copyright 2022 The Kubernetes Authors.
     6  
     7  Licensed under the Apache License, Version 2.0 (the "License");
     8  you may not use this file except in compliance with the License.
     9  You may obtain a copy of the License at
    10  
    11      http://www.apache.org/licenses/LICENSE-2.0
    12  
    13  Unless required by applicable law or agreed to in writing, software
    14  distributed under the License is distributed on an "AS IS" BASIS,
    15  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    16  See the License for the specific language governing permissions and
    17  limitations under the License.
    18  */
    19  
    20  package testing
    21  
    22  import (
    23  	"bytes"
    24  	"strings"
    25  	"testing"
    26  
    27  	"github.com/lithammer/dedent"
    28  
    29  	"k8s.io/kubernetes/pkg/util/iptables"
    30  )
    31  
    32  func TestFakeIPTables(t *testing.T) {
    33  	fake := NewFake()
    34  	buf := bytes.NewBuffer(nil)
    35  
    36  	err := fake.SaveInto("", buf)
    37  	if err != nil {
    38  		t.Fatalf("unexpected error from SaveInto: %v", err)
    39  	}
    40  	expected := dedent.Dedent(strings.Trim(`
    41  		*nat
    42  		:PREROUTING - [0:0]
    43  		:INPUT - [0:0]
    44  		:OUTPUT - [0:0]
    45  		:POSTROUTING - [0:0]
    46  		COMMIT
    47  		*filter
    48  		:INPUT - [0:0]
    49  		:FORWARD - [0:0]
    50  		:OUTPUT - [0:0]
    51  		COMMIT
    52  		*mangle
    53  		COMMIT
    54  		`, "\n"))
    55  	if buf.String() != expected {
    56  		t.Fatalf("bad initial dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
    57  	}
    58  
    59  	// EnsureChain
    60  	existed, err := fake.EnsureChain(iptables.Table("blah"), iptables.Chain("KUBE-TEST"))
    61  	if err == nil {
    62  		t.Errorf("did not get expected error creating chain in non-existent table")
    63  	} else if existed {
    64  		t.Errorf("wrong return value from EnsureChain with non-existent table")
    65  	}
    66  	existed, err = fake.EnsureChain(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
    67  	if err != nil {
    68  		t.Errorf("unexpected error creating chain: %v", err)
    69  	} else if existed {
    70  		t.Errorf("wrong return value from EnsureChain with non-existent chain")
    71  	}
    72  	existed, err = fake.EnsureChain(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
    73  	if err != nil {
    74  		t.Errorf("unexpected error creating chain: %v", err)
    75  	} else if !existed {
    76  		t.Errorf("wrong return value from EnsureChain with existing chain")
    77  	}
    78  
    79  	// ChainExists
    80  	exists, err := fake.ChainExists(iptables.TableNAT, iptables.Chain("KUBE-TEST"))
    81  	if err != nil {
    82  		t.Errorf("unexpected error checking chain: %v", err)
    83  	} else if !exists {
    84  		t.Errorf("wrong return value from ChainExists with existing chain")
    85  	}
    86  	exists, err = fake.ChainExists(iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"))
    87  	if err != nil {
    88  		t.Errorf("unexpected error checking chain: %v", err)
    89  	} else if exists {
    90  		t.Errorf("wrong return value from ChainExists with non-existent chain")
    91  	}
    92  
    93  	// EnsureRule
    94  	existed, err = fake.EnsureRule(iptables.Append, iptables.Table("blah"), iptables.Chain("KUBE-TEST"), "-j", "ACCEPT")
    95  	if err == nil {
    96  		t.Errorf("did not get expected error creating rule in non-existent table")
    97  	} else if existed {
    98  		t.Errorf("wrong return value from EnsureRule with non-existent table")
    99  	}
   100  	existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"), "-j", "ACCEPT")
   101  	if err == nil {
   102  		t.Errorf("did not get expected error creating rule in non-existent chain")
   103  	} else if existed {
   104  		t.Errorf("wrong return value from EnsureRule with non-existent chain")
   105  	}
   106  	existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "ACCEPT")
   107  	if err != nil {
   108  		t.Errorf("unexpected error creating rule: %v", err)
   109  	} else if existed {
   110  		t.Errorf("wrong return value from EnsureRule with non-existent rule")
   111  	}
   112  	existed, err = fake.EnsureRule(iptables.Prepend, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
   113  	if err != nil {
   114  		t.Errorf("unexpected error creating rule: %v", err)
   115  	} else if existed {
   116  		t.Errorf("wrong return value from EnsureRule with non-existent rule")
   117  	}
   118  	existed, err = fake.EnsureRule(iptables.Append, iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
   119  	if err != nil {
   120  		t.Errorf("unexpected error creating rule: %v", err)
   121  	} else if !existed {
   122  		t.Errorf("wrong return value from EnsureRule with already-existing rule")
   123  	}
   124  
   125  	// Sanity-check...
   126  	buf.Reset()
   127  	err = fake.SaveInto("", buf)
   128  	if err != nil {
   129  		t.Fatalf("unexpected error from SaveInto: %v", err)
   130  	}
   131  	expected = dedent.Dedent(strings.Trim(`
   132  		*nat
   133  		:PREROUTING - [0:0]
   134  		:INPUT - [0:0]
   135  		:OUTPUT - [0:0]
   136  		:POSTROUTING - [0:0]
   137  		:KUBE-TEST - [0:0]
   138  		-A KUBE-TEST -j DROP
   139  		-A KUBE-TEST -j ACCEPT
   140  		COMMIT
   141  		*filter
   142  		:INPUT - [0:0]
   143  		:FORWARD - [0:0]
   144  		:OUTPUT - [0:0]
   145  		COMMIT
   146  		*mangle
   147  		COMMIT
   148  		`, "\n"))
   149  	if buf.String() != expected {
   150  		t.Fatalf("bad sanity-check dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
   151  	}
   152  
   153  	// DeleteRule
   154  	err = fake.DeleteRule(iptables.Table("blah"), iptables.Chain("KUBE-TEST"), "-j", "DROP")
   155  	if err == nil {
   156  		t.Errorf("did not get expected error deleting rule in non-existent table")
   157  	}
   158  	err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST-NOT"), "-j", "DROP")
   159  	if err == nil {
   160  		t.Errorf("did not get expected error deleting rule in non-existent chain")
   161  	}
   162  	err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROPLET")
   163  	if err != nil {
   164  		t.Errorf("unexpected error deleting non-existent rule: %v", err)
   165  	}
   166  	err = fake.DeleteRule(iptables.TableNAT, iptables.Chain("KUBE-TEST"), "-j", "DROP")
   167  	if err != nil {
   168  		t.Errorf("unexpected error deleting rule: %v", err)
   169  	}
   170  
   171  	// Restore
   172  	rules := dedent.Dedent(strings.Trim(`
   173  		*nat
   174  		:KUBE-RESTORED - [0:0]
   175  		:KUBE-MISC-CHAIN - [0:0]
   176  		:KUBE-MISC-TWO - [0:0]
   177  		:KUBE-EMPTY - [0:0]
   178  		-A KUBE-RESTORED -m comment --comment "restored chain" -j ACCEPT
   179  		-A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
   180  		-A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
   181  		-A KUBE-MISC-TWO -j ACCEPT
   182  		COMMIT
   183  		`, "\n"))
   184  	err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.NoRestoreCounters)
   185  	if err != nil {
   186  		t.Fatalf("unexpected error from Restore: %v", err)
   187  	}
   188  
   189  	// We used NoFlushTables, so this should leave KUBE-TEST unchanged
   190  	buf.Reset()
   191  	err = fake.SaveInto("", buf)
   192  	if err != nil {
   193  		t.Fatalf("unexpected error from SaveInto: %v", err)
   194  	}
   195  	expected = dedent.Dedent(strings.Trim(`
   196  		*nat
   197  		:PREROUTING - [0:0]
   198  		:INPUT - [0:0]
   199  		:OUTPUT - [0:0]
   200  		:POSTROUTING - [0:0]
   201  		:KUBE-TEST - [0:0]
   202  		:KUBE-RESTORED - [0:0]
   203  		:KUBE-MISC-CHAIN - [0:0]
   204  		:KUBE-MISC-TWO - [0:0]
   205  		:KUBE-EMPTY - [0:0]
   206  		-A KUBE-TEST -j ACCEPT
   207  		-A KUBE-RESTORED -m comment --comment "restored chain" -j ACCEPT
   208  		-A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
   209  		-A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
   210  		-A KUBE-MISC-TWO -j ACCEPT
   211  		COMMIT
   212  		*filter
   213  		:INPUT - [0:0]
   214  		:FORWARD - [0:0]
   215  		:OUTPUT - [0:0]
   216  		COMMIT
   217  		*mangle
   218  		COMMIT
   219  		`, "\n"))
   220  	if buf.String() != expected {
   221  		t.Fatalf("bad post-restore dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
   222  	}
   223  
   224  	// Trying to use Restore to delete a chain that another chain jumps to will fail
   225  	rules = dedent.Dedent(strings.Trim(`
   226  		*nat
   227  		:KUBE-MISC-TWO - [0:0]
   228  		-X KUBE-MISC-TWO
   229  		COMMIT
   230  		`, "\n"))
   231  	err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
   232  	if err == nil || !strings.Contains(err.Error(), "referenced by existing rules") {
   233  		t.Fatalf("Expected 'referenced by existing rules' error from Restore, got %v", err)
   234  	}
   235  
   236  	// Trying to use Restore to add a jump to a non-existent chain will fail
   237  	rules = dedent.Dedent(strings.Trim(`
   238  		*nat
   239  		:KUBE-MISC-TWO - [0:0]
   240  		-A KUBE-MISC-TWO -j KUBE-MISC-THREE
   241  		COMMIT
   242  		`, "\n"))
   243  	err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
   244  	if err == nil || !strings.Contains(err.Error(), "non-existent chain") {
   245  		t.Fatalf("Expected 'non-existent chain' error from Restore, got %v", err)
   246  	}
   247  
   248  	// more Restore; empty out one chain and delete another, but also update its counters
   249  	rules = dedent.Dedent(strings.Trim(`
   250  		*nat
   251  		:KUBE-RESTORED - [0:0]
   252  		:KUBE-TEST - [99:9999]
   253  		-X KUBE-RESTORED
   254  		COMMIT
   255  		`, "\n"))
   256  	err = fake.Restore(iptables.TableNAT, []byte(rules), iptables.NoFlushTables, iptables.RestoreCounters)
   257  	if err != nil {
   258  		t.Fatalf("unexpected error from Restore: %v", err)
   259  	}
   260  
   261  	buf.Reset()
   262  	err = fake.SaveInto("", buf)
   263  	if err != nil {
   264  		t.Fatalf("unexpected error from SaveInto: %v", err)
   265  	}
   266  	expected = dedent.Dedent(strings.Trim(`
   267  		*nat
   268  		:PREROUTING - [0:0]
   269  		:INPUT - [0:0]
   270  		:OUTPUT - [0:0]
   271  		:POSTROUTING - [0:0]
   272  		:KUBE-TEST - [99:9999]
   273  		:KUBE-MISC-CHAIN - [0:0]
   274  		:KUBE-MISC-TWO - [0:0]
   275  		:KUBE-EMPTY - [0:0]
   276  		-A KUBE-MISC-CHAIN -s 1.2.3.4 -j KUBE-MISC-TWO
   277  		-A KUBE-MISC-CHAIN -d 5.6.7.8 -j MASQUERADE
   278  		-A KUBE-MISC-TWO -j ACCEPT
   279  		COMMIT
   280  		*filter
   281  		:INPUT - [0:0]
   282  		:FORWARD - [0:0]
   283  		:OUTPUT - [0:0]
   284  		COMMIT
   285  		*mangle
   286  		COMMIT
   287  		`, "\n"))
   288  	if buf.String() != expected {
   289  		t.Fatalf("bad post-second-restore dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
   290  	}
   291  
   292  	// RestoreAll, FlushTables
   293  	rules = dedent.Dedent(strings.Trim(`
   294  		*filter
   295  		:INPUT - [0:0]
   296  		:FORWARD - [0:0]
   297  		:OUTPUT - [0:0]
   298  		:KUBE-TEST - [0:0]
   299  		-A KUBE-TEST -m comment --comment "filter table KUBE-TEST" -j ACCEPT
   300  		COMMIT
   301  		*nat
   302  		:PREROUTING - [0:0]
   303  		:INPUT - [0:0]
   304  		:OUTPUT - [0:0]
   305  		:POSTROUTING - [0:0]
   306  		:KUBE-TEST - [88:8888]
   307  		:KUBE-NEW-CHAIN - [0:0]
   308  		-A KUBE-NEW-CHAIN -d 172.30.0.1 -j DNAT --to-destination 10.0.0.1
   309  		-A KUBE-NEW-CHAIN -d 172.30.0.2 -j DNAT --to-destination 10.0.0.2
   310  		-A KUBE-NEW-CHAIN -d 172.30.0.3 -j DNAT --to-destination 10.0.0.3
   311  		COMMIT
   312  		`, "\n"))
   313  	err = fake.RestoreAll([]byte(rules), iptables.FlushTables, iptables.NoRestoreCounters)
   314  	if err != nil {
   315  		t.Fatalf("unexpected error from RestoreAll: %v", err)
   316  	}
   317  
   318  	buf.Reset()
   319  	err = fake.SaveInto("", buf)
   320  	if err != nil {
   321  		t.Fatalf("unexpected error from SaveInto: %v", err)
   322  	}
   323  	expected = dedent.Dedent(strings.Trim(`
   324  		*nat
   325  		:PREROUTING - [0:0]
   326  		:INPUT - [0:0]
   327  		:OUTPUT - [0:0]
   328  		:POSTROUTING - [0:0]
   329  		:KUBE-TEST - [88:8888]
   330  		:KUBE-NEW-CHAIN - [0:0]
   331  		-A KUBE-NEW-CHAIN -d 172.30.0.1 -j DNAT --to-destination 10.0.0.1
   332  		-A KUBE-NEW-CHAIN -d 172.30.0.2 -j DNAT --to-destination 10.0.0.2
   333  		-A KUBE-NEW-CHAIN -d 172.30.0.3 -j DNAT --to-destination 10.0.0.3
   334  		COMMIT
   335  		*filter
   336  		:INPUT - [0:0]
   337  		:FORWARD - [0:0]
   338  		:OUTPUT - [0:0]
   339  		:KUBE-TEST - [0:0]
   340  		-A KUBE-TEST -m comment --comment "filter table KUBE-TEST" -j ACCEPT
   341  		COMMIT
   342  		*mangle
   343  		COMMIT
   344  		`, "\n"))
   345  	if buf.String() != expected {
   346  		t.Fatalf("bad post-restore-all dump. expected:\n%s\n\ngot:\n%s\n", expected, buf.Bytes())
   347  	}
   348  }
   349  

View as plain text