istio.io/istio@v0.0.0-20240520182934-d79c90f27776/tools/istio-iptables/pkg/builder/iptables_builder_test.go (about)

     1  // Copyright Istio Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package builder
    16  
    17  import (
    18  	"reflect"
    19  	"testing"
    20  
    21  	"istio.io/istio/tools/istio-iptables/pkg/config"
    22  	"istio.io/istio/tools/istio-iptables/pkg/constants"
    23  	iptableslog "istio.io/istio/tools/istio-iptables/pkg/log"
    24  )
    25  
    26  // TODO(abhide): Add more testcases once BuildV6Restore() are implemented
    27  func TestBuildV6Restore(t *testing.T) {
    28  	iptables := NewIptablesRuleBuilder(nil)
    29  	expected := ""
    30  	actual := iptables.BuildV6Restore()
    31  	if expected != actual {
    32  		t.Errorf("Output didn't match: Got: %s, Expected: %s", actual, expected)
    33  	}
    34  }
    35  
    36  // TODO(abhide): Add more testcases once BuildV4Restore() are implemented
    37  func TestBuildV4Restore(t *testing.T) {
    38  	iptables := NewIptablesRuleBuilder(nil)
    39  	expected := ""
    40  	actual := iptables.BuildV4Restore()
    41  	if expected != actual {
    42  		t.Errorf("Output didn't match: Got: %s, Expected: %s", actual, expected)
    43  	}
    44  }
    45  
    46  func TestBuildV4InsertSingleRule(t *testing.T) {
    47  	iptables := NewIptablesRuleBuilder(nil)
    48  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
    49  	if err := len(iptables.rules.rulesv6) != 0; err {
    50  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
    51  	}
    52  	actual := iptables.BuildV4()
    53  	expected := [][]string{
    54  		{"-t", "table", "-N", "chain"},
    55  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
    56  	}
    57  	if !reflect.DeepEqual(actual, expected) {
    58  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
    59  	}
    60  	// V6 rules should be empty and return an empty slice
    61  	actual = iptables.BuildV6()
    62  	if !reflect.DeepEqual(actual, [][]string{}) {
    63  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
    64  	}
    65  }
    66  
    67  func TestBuildV4AppendSingleRule(t *testing.T) {
    68  	iptables := NewIptablesRuleBuilder(nil)
    69  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
    70  	if err := len(iptables.rules.rulesv6) != 0; err {
    71  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
    72  	}
    73  	actual := iptables.BuildV4()
    74  	expected := [][]string{
    75  		{"-t", "table", "-N", "chain"},
    76  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
    77  	}
    78  	if !reflect.DeepEqual(actual, expected) {
    79  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
    80  	}
    81  	// V6 rules should be empty and return an empty slice
    82  	actual = iptables.BuildV6()
    83  	if !reflect.DeepEqual(actual, [][]string{}) {
    84  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
    85  	}
    86  }
    87  
    88  func TestBuildV4AppendMultipleRules(t *testing.T) {
    89  	iptables := NewIptablesRuleBuilder(nil)
    90  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
    91  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "fu", "-b", "bar")
    92  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "baz")
    93  	if err := len(iptables.rules.rulesv6) != 0; err {
    94  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
    95  	}
    96  	actual := iptables.BuildV4()
    97  	expected := [][]string{
    98  		{"-t", "table", "-N", "chain"},
    99  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   100  		{"-t", "table", "-A", "chain", "-f", "fu", "-b", "bar"},
   101  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "baz"},
   102  	}
   103  	if !reflect.DeepEqual(actual, expected) {
   104  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   105  	}
   106  	// V6 rules should be empty and return an empty slice
   107  	actual = iptables.BuildV6()
   108  	if !reflect.DeepEqual(actual, [][]string{}) {
   109  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
   110  	}
   111  }
   112  
   113  func TestBuildV4InsertMultipleRules(t *testing.T) {
   114  	iptables := NewIptablesRuleBuilder(nil)
   115  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 1, "-f", "foo", "-b", "bar")
   116  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "baaz")
   117  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 3, "-f", "foo", "-b", "baz")
   118  	if err := len(iptables.rules.rulesv6) != 0; err {
   119  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
   120  	}
   121  	actual := iptables.BuildV4()
   122  	expected := [][]string{
   123  		{"-t", "table", "-N", "chain"},
   124  		{"-t", "table", "-I", "chain", "1", "-f", "foo", "-b", "bar"},
   125  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "baaz"},
   126  		{"-t", "table", "-I", "chain", "3", "-f", "foo", "-b", "baz"},
   127  	}
   128  	if !reflect.DeepEqual(actual, expected) {
   129  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   130  	}
   131  	// V6 rules should be empty and return an empty slice
   132  	actual = iptables.BuildV6()
   133  	if !reflect.DeepEqual(actual, [][]string{}) {
   134  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
   135  	}
   136  }
   137  
   138  func TestBuildV4AppendInsertMultipleRules(t *testing.T) {
   139  	iptables := NewIptablesRuleBuilder(nil)
   140  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   141  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
   142  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "baz")
   143  	if err := len(iptables.rules.rulesv6) != 0; err {
   144  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
   145  	}
   146  	actual := iptables.BuildV4()
   147  	expected := [][]string{
   148  		{"-t", "table", "-N", "chain"},
   149  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   150  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
   151  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "baz"},
   152  	}
   153  	if !reflect.DeepEqual(actual, expected) {
   154  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   155  	}
   156  	// V6 rules should be empty and return an empty slice
   157  	actual = iptables.BuildV6()
   158  	if !reflect.DeepEqual(actual, [][]string{}) {
   159  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
   160  	}
   161  }
   162  
   163  var IPv6Config = &config.Config{
   164  	EnableIPv6: true,
   165  }
   166  
   167  func TestBuildV6InsertSingleRule(t *testing.T) {
   168  	iptables := NewIptablesRuleBuilder(IPv6Config)
   169  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
   170  	if err := len(iptables.rules.rulesv4) != 0; err {
   171  		t.Errorf("Expected rulesV4 to be empty; but got %#v", iptables.rules.rulesv4)
   172  	}
   173  	actual := iptables.BuildV6()
   174  	expected := [][]string{
   175  		{"-t", "table", "-N", "chain"},
   176  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
   177  	}
   178  	if !reflect.DeepEqual(actual, expected) {
   179  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   180  	}
   181  	// V4 rules should be empty and return an empty slice
   182  	actual = iptables.BuildV4()
   183  	if !reflect.DeepEqual(actual, [][]string{}) {
   184  		t.Errorf("Expected V4 rules to be empty; but instead got Actual: %#v", actual)
   185  	}
   186  }
   187  
   188  func TestBuildV6AppendSingleRule(t *testing.T) {
   189  	iptables := NewIptablesRuleBuilder(IPv6Config)
   190  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   191  	if err := len(iptables.rules.rulesv4) != 0; err {
   192  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
   193  	}
   194  	actual := iptables.BuildV6()
   195  	expected := [][]string{
   196  		{"-t", "table", "-N", "chain"},
   197  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   198  	}
   199  	if !reflect.DeepEqual(actual, expected) {
   200  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   201  	}
   202  	// V6 rules should be empty and return an empty slice
   203  	actual = iptables.BuildV4()
   204  	if !reflect.DeepEqual(actual, [][]string{}) {
   205  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
   206  	}
   207  }
   208  
   209  func TestBuildV6AppendMultipleRules(t *testing.T) {
   210  	iptables := NewIptablesRuleBuilder(IPv6Config)
   211  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   212  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "fu", "-b", "bar")
   213  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "baz")
   214  	if err := len(iptables.rules.rulesv4) != 0; err {
   215  		t.Errorf("Expected rulesV6 to be empty; but got %#v", iptables.rules.rulesv6)
   216  	}
   217  	actual := iptables.BuildV6()
   218  	expected := [][]string{
   219  		{"-t", "table", "-N", "chain"},
   220  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   221  		{"-t", "table", "-A", "chain", "-f", "fu", "-b", "bar"},
   222  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "baz"},
   223  	}
   224  	if !reflect.DeepEqual(actual, expected) {
   225  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   226  	}
   227  	// V6 rules should be empty and return an empty slice
   228  	actual = iptables.BuildV4()
   229  	if !reflect.DeepEqual(actual, [][]string{}) {
   230  		t.Errorf("Expected V6 rules to be empty; but instead got Actual: %#v", actual)
   231  	}
   232  }
   233  
   234  func TestBuildV6InsertMultipleRules(t *testing.T) {
   235  	iptables := NewIptablesRuleBuilder(IPv6Config)
   236  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 1, "-f", "foo", "-b", "bar")
   237  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "baaz")
   238  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 3, "-f", "foo", "-b", "baz")
   239  	if err := len(iptables.rules.rulesv4) != 0; err {
   240  		t.Errorf("Expected rulesV4 to be empty; but got %#v", iptables.rules.rulesv4)
   241  	}
   242  	actual := iptables.BuildV6()
   243  	expected := [][]string{
   244  		{"-t", "table", "-N", "chain"},
   245  		{"-t", "table", "-I", "chain", "1", "-f", "foo", "-b", "bar"},
   246  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "baaz"},
   247  		{"-t", "table", "-I", "chain", "3", "-f", "foo", "-b", "baz"},
   248  	}
   249  	if !reflect.DeepEqual(actual, expected) {
   250  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   251  	}
   252  	// V4 rules should be empty and return an empty slice
   253  	actual = iptables.BuildV4()
   254  	if !reflect.DeepEqual(actual, [][]string{}) {
   255  		t.Errorf("Expected V4 rules to be empty; but instead got Actual: %#v", actual)
   256  	}
   257  }
   258  
   259  func TestBuildV6InsertAppendMultipleRules(t *testing.T) {
   260  	iptables := NewIptablesRuleBuilder(IPv6Config)
   261  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   262  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
   263  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 1, "-f", "foo", "-b", "bar")
   264  	if err := len(iptables.rules.rulesv4) != 0; err {
   265  		t.Errorf("Expected rulesV4 to be empty; but got %#v", iptables.rules.rulesv4)
   266  	}
   267  	actual := iptables.BuildV6()
   268  	expected := [][]string{
   269  		{"-t", "table", "-N", "chain"},
   270  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   271  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
   272  		{"-t", "table", "-I", "chain", "1", "-f", "foo", "-b", "bar"},
   273  	}
   274  	if !reflect.DeepEqual(actual, expected) {
   275  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actual, expected)
   276  	}
   277  	// V4 rules should be empty and return an empty slice
   278  	actual = iptables.BuildV4()
   279  	if !reflect.DeepEqual(actual, [][]string{}) {
   280  		t.Errorf("Expected V4 rules to be empty; but instead got Actual: %#v", actual)
   281  	}
   282  }
   283  
   284  func TestBuildV4V6MultipleRulesWithNewChain(t *testing.T) {
   285  	iptables := NewIptablesRuleBuilder(IPv6Config)
   286  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   287  	iptables.InsertRuleV4(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
   288  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "baz")
   289  	iptables.AppendRuleV6(iptableslog.UndefinedCommand, "chain", "table", "-f", "foo", "-b", "bar")
   290  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 2, "-f", "foo", "-b", "bar")
   291  	iptables.InsertRuleV6(iptableslog.UndefinedCommand, "chain", "table", 1, "-f", "foo", "-b", "bar")
   292  	iptables.AppendRuleV4(iptableslog.UndefinedCommand, constants.PREROUTING, constants.NAT, "-f", "foo", "-b", "bar")
   293  	actualV4 := iptables.BuildV4()
   294  	actualV6 := iptables.BuildV6()
   295  	expectedV6 := [][]string{
   296  		{"-t", "table", "-N", "chain"},
   297  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   298  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
   299  		{"-t", "table", "-I", "chain", "1", "-f", "foo", "-b", "bar"},
   300  	}
   301  	expectedV4 := [][]string{
   302  		{"-t", "table", "-N", "chain"},
   303  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "bar"},
   304  		{"-t", "table", "-I", "chain", "2", "-f", "foo", "-b", "bar"},
   305  		{"-t", "table", "-A", "chain", "-f", "foo", "-b", "baz"},
   306  		{"-t", "nat", "-A", "PREROUTING", "-f", "foo", "-b", "bar"},
   307  	}
   308  	if !reflect.DeepEqual(actualV4, expectedV4) {
   309  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actualV4, expectedV4)
   310  	}
   311  	if !reflect.DeepEqual(actualV6, expectedV6) {
   312  		t.Errorf("Actual and expected output mismatch; but instead got Actual: %#v ; Expected: %#v", actualV6, expectedV6)
   313  	}
   314  }