github.com/cilium/cilium@v1.16.2/pkg/policy/api/utils_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package api
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/cilium/proxy/pkg/policy/api/kafka"
    10  	"github.com/stretchr/testify/require"
    11  
    12  	"github.com/cilium/cilium/pkg/defaults"
    13  	"github.com/cilium/cilium/pkg/fqdn/re"
    14  )
    15  
    16  func setUpSuite(_ testing.TB) {
    17  	re.InitRegexCompileLRU(defaults.FQDNRegexCompileLRUSize)
    18  }
    19  
    20  func TestHTTPEqual(t *testing.T) {
    21  	setUpSuite(t)
    22  
    23  	rule1 := PortRuleHTTP{Path: "/foo$", Method: "GET", Headers: []string{"X-Test: Foo"}}
    24  	rule2 := PortRuleHTTP{Path: "/bar$", Method: "GET", Headers: []string{"X-Test: Foo"}}
    25  	rule3 := PortRuleHTTP{Path: "/foo$", Method: "GET", Headers: []string{"X-Test: Bar"}}
    26  
    27  	require.Equal(t, true, rule1.Equal(rule1))
    28  	require.Equal(t, false, rule1.Equal(rule2))
    29  	require.Equal(t, false, rule1.Equal(rule3))
    30  
    31  	rules := L7Rules{
    32  		HTTP: []PortRuleHTTP{rule1, rule2},
    33  	}
    34  
    35  	require.Equal(t, true, rule1.Exists(rules))
    36  	require.Equal(t, true, rule2.Exists(rules))
    37  	require.Equal(t, false, rule3.Exists(rules))
    38  }
    39  
    40  func TestKafkaEqual(t *testing.T) {
    41  	setUpSuite(t)
    42  
    43  	rule1 := kafka.PortRule{APIVersion: "1", APIKey: "foo", Topic: "topic1"}
    44  	rule2 := kafka.PortRule{APIVersion: "1", APIKey: "bar", Topic: "topic1"}
    45  	rule3 := kafka.PortRule{APIVersion: "1", APIKey: "foo", Topic: "topic2"}
    46  
    47  	require.Equal(t, rule1, rule1)
    48  	require.NotEqual(t, rule2, rule1)
    49  	require.NotEqual(t, rule3, rule1)
    50  
    51  	rules := L7Rules{
    52  		Kafka: []kafka.PortRule{rule1, rule2},
    53  	}
    54  
    55  	require.Equal(t, true, rule1.Exists(rules.Kafka))
    56  	require.Equal(t, true, rule2.Exists(rules.Kafka))
    57  	require.Equal(t, false, rule3.Exists(rules.Kafka))
    58  }
    59  
    60  func TestL7Equal(t *testing.T) {
    61  	setUpSuite(t)
    62  
    63  	rule1 := PortRuleL7{"Path": "/foo$", "Method": "GET"}
    64  	rule2 := PortRuleL7{"Path": "/bar$", "Method": "GET"}
    65  	rule3 := PortRuleL7{"Path": "/foo$", "Method": "GET", "extra": ""}
    66  
    67  	require.Equal(t, true, rule1.Equal(rule1))
    68  	require.Equal(t, true, rule2.Equal(rule2))
    69  	require.Equal(t, true, rule3.Equal(rule3))
    70  	require.Equal(t, false, rule1.Equal(rule2))
    71  	require.Equal(t, false, rule2.Equal(rule1))
    72  	require.Equal(t, false, rule1.Equal(rule3))
    73  	require.Equal(t, false, rule3.Equal(rule1))
    74  	require.Equal(t, false, rule2.Equal(rule3))
    75  	require.Equal(t, false, rule3.Equal(rule2))
    76  
    77  	rules := L7Rules{
    78  		L7Proto: "testing",
    79  		L7:      []PortRuleL7{rule1, rule2},
    80  	}
    81  
    82  	require.Equal(t, true, rule1.Exists(rules))
    83  	require.Equal(t, true, rule2.Exists(rules))
    84  	require.Equal(t, false, rule3.Exists(rules))
    85  }
    86  
    87  func TestValidateL4Proto(t *testing.T) {
    88  	setUpSuite(t)
    89  
    90  	require.Nil(t, L4Proto("TCP").Validate())
    91  	require.Nil(t, L4Proto("UDP").Validate())
    92  	require.Nil(t, L4Proto("ANY").Validate())
    93  	require.NotNil(t, L4Proto("TCP2").Validate())
    94  	require.NotNil(t, L4Proto("t").Validate())
    95  }
    96  
    97  func TestParseL4Proto(t *testing.T) {
    98  	setUpSuite(t)
    99  
   100  	p, err := ParseL4Proto("tcp")
   101  	require.Equal(t, ProtoTCP, p)
   102  	require.Nil(t, err)
   103  
   104  	p, err = ParseL4Proto("Any")
   105  	require.Equal(t, ProtoAny, p)
   106  	require.Nil(t, err)
   107  
   108  	p, err = ParseL4Proto("")
   109  	require.Equal(t, ProtoAny, p)
   110  	require.Nil(t, err)
   111  
   112  	_, err = ParseL4Proto("foo2")
   113  	require.NotNil(t, err)
   114  }
   115  
   116  func TestResourceQualifiedName(t *testing.T) {
   117  	setUpSuite(t)
   118  
   119  	// Empty resource name is passed through
   120  	name, updated := ResourceQualifiedName("", "", "")
   121  	require.Equal(t, "", name)
   122  	require.Equal(t, false, updated)
   123  
   124  	name, updated = ResourceQualifiedName("a", "", "")
   125  	require.Equal(t, "", name)
   126  	require.Equal(t, false, updated)
   127  
   128  	name, updated = ResourceQualifiedName("", "b", "")
   129  	require.Equal(t, "", name)
   130  	require.Equal(t, false, updated)
   131  
   132  	name, updated = ResourceQualifiedName("", "", "", ForceNamespace)
   133  	require.Equal(t, "", name)
   134  	require.Equal(t, false, updated)
   135  
   136  	name, updated = ResourceQualifiedName("a", "", "", ForceNamespace)
   137  	require.Equal(t, "", name)
   138  	require.Equal(t, false, updated)
   139  
   140  	name, updated = ResourceQualifiedName("", "b", "", ForceNamespace)
   141  	require.Equal(t, "", name)
   142  	require.Equal(t, false, updated)
   143  
   144  	// Cluster-scope resources have no namespace
   145  	name, updated = ResourceQualifiedName("", "", "test-resource")
   146  	require.Equal(t, "//test-resource", name)
   147  	require.Equal(t, true, updated)
   148  
   149  	// Every resource has a name of a CEC they originate from
   150  	name, updated = ResourceQualifiedName("", "test-name", "test-resource")
   151  	require.Equal(t, "/test-name/test-resource", name)
   152  	require.Equal(t, true, updated)
   153  
   154  	// namespaced resources have a namespace
   155  	name, updated = ResourceQualifiedName("test-namespace", "", "test-resource")
   156  	require.Equal(t, "test-namespace//test-resource", name)
   157  	require.Equal(t, true, updated)
   158  
   159  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "test-resource")
   160  	require.Equal(t, "test-namespace/test-name/test-resource", name)
   161  	require.Equal(t, true, updated)
   162  
   163  	// resource names with slashes is considered to already be qualified, and will not be prepended with namespace/cec-name
   164  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "test/resource")
   165  	require.Equal(t, "test/resource", name)
   166  	require.Equal(t, false, updated)
   167  
   168  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "/resource")
   169  	require.Equal(t, "/resource", name)
   170  	require.Equal(t, false, updated)
   171  
   172  	name, updated = ResourceQualifiedName("", "test-name", "test/resource")
   173  	require.Equal(t, "test/resource", name)
   174  	require.Equal(t, false, updated)
   175  
   176  	name, updated = ResourceQualifiedName("", "test-name", "/resource")
   177  	require.Equal(t, "/resource", name)
   178  	require.Equal(t, false, updated)
   179  
   180  	// forceNamespacing has no effect when the resource name is non-qualified
   181  	name, updated = ResourceQualifiedName("", "", "test-resource", ForceNamespace)
   182  	require.Equal(t, "//test-resource", name)
   183  	require.Equal(t, true, updated)
   184  
   185  	name, updated = ResourceQualifiedName("", "test-name", "test-resource", ForceNamespace)
   186  	require.Equal(t, "/test-name/test-resource", name)
   187  	require.Equal(t, true, updated)
   188  
   189  	name, updated = ResourceQualifiedName("test-namespace", "", "test-resource", ForceNamespace)
   190  	require.Equal(t, "test-namespace//test-resource", name)
   191  	require.Equal(t, true, updated)
   192  
   193  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "test-resource", ForceNamespace)
   194  	require.Equal(t, "test-namespace/test-name/test-resource", name)
   195  	require.Equal(t, true, updated)
   196  
   197  	// forceNamespacing qualifies names in foreign namespaces
   198  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "test/resource", ForceNamespace)
   199  	require.Equal(t, "test-namespace/test-name/test/resource", name)
   200  	require.Equal(t, true, updated)
   201  
   202  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "/resource", ForceNamespace)
   203  	require.Equal(t, "test-namespace/test-name//resource", name)
   204  	require.Equal(t, true, updated)
   205  
   206  	name, updated = ResourceQualifiedName("", "test-name", "test/resource", ForceNamespace)
   207  	require.Equal(t, "/test-name/test/resource", name)
   208  	require.Equal(t, true, updated)
   209  
   210  	// forceNamespacing skips prepending if namespace matches
   211  	name, updated = ResourceQualifiedName("test-namespace", "test-name", "test-namespace/resource", ForceNamespace)
   212  	require.Equal(t, "test-namespace/resource", name)
   213  	require.Equal(t, false, updated)
   214  	name, updated = ResourceQualifiedName("", "test-name", "/resource", ForceNamespace)
   215  	require.Equal(t, "/resource", name)
   216  	require.Equal(t, false, updated)
   217  }
   218  
   219  func TestParseQualifiedName(t *testing.T) {
   220  	setUpSuite(t)
   221  
   222  	// Empty name is passed through
   223  	namespace, name, resourceName := ParseQualifiedName("")
   224  	require.Equal(t, "", namespace)
   225  	require.Equal(t, "", name)
   226  	require.Equal(t, "", resourceName)
   227  
   228  	// Unqualified name is passed through
   229  	namespace, name, resourceName = ParseQualifiedName("resource")
   230  	require.Equal(t, "", namespace)
   231  	require.Equal(t, "", name)
   232  	require.Equal(t, "resource", resourceName)
   233  
   234  	// Cluster-scope resources have no namespace
   235  	namespace, name, resourceName = ParseQualifiedName("//test-resource")
   236  	require.Equal(t, "", namespace)
   237  	require.Equal(t, "", name)
   238  	require.Equal(t, "test-resource", resourceName)
   239  
   240  	// Every resource has a name of a CEC they originate from
   241  	namespace, name, resourceName = ParseQualifiedName("/test-name/test-resource")
   242  	require.Equal(t, "", namespace)
   243  	require.Equal(t, "test-name", name)
   244  	require.Equal(t, "test-resource", resourceName)
   245  
   246  	// namespaced resources have a namespace
   247  	namespace, name, resourceName = ParseQualifiedName("test-namespace//test-resource")
   248  	require.Equal(t, "test-namespace", namespace)
   249  	require.Equal(t, "", name)
   250  	require.Equal(t, "test-resource", resourceName)
   251  
   252  	namespace, name, resourceName = ParseQualifiedName("test-namespace/test-name/test-resource")
   253  	require.Equal(t, "test-namespace", namespace)
   254  	require.Equal(t, "test-name", name)
   255  	require.Equal(t, "test-resource", resourceName)
   256  
   257  	// resource names with slashes is considered to already be qualified, and will not be prepended with namespace/cec-name
   258  	namespace, name, resourceName = ParseQualifiedName("test/resource")
   259  	require.Equal(t, "", namespace)
   260  	require.Equal(t, "", name)
   261  	require.Equal(t, "test/resource", resourceName)
   262  
   263  	namespace, name, resourceName = ParseQualifiedName("/resource")
   264  	require.Equal(t, "", namespace)
   265  	require.Equal(t, "", name)
   266  	require.Equal(t, "/resource", resourceName)
   267  
   268  	// extra slashes are part of the resource name
   269  	namespace, name, resourceName = ParseQualifiedName("test-namespace/test-name//resource")
   270  	require.Equal(t, "test-namespace", namespace)
   271  	require.Equal(t, "test-name", name)
   272  	require.Equal(t, "/resource", resourceName)
   273  
   274  	namespace, name, resourceName = ParseQualifiedName("/test-name/test/resource")
   275  	require.Equal(t, "", namespace)
   276  	require.Equal(t, "test-name", name)
   277  	require.Equal(t, "test/resource", resourceName)
   278  }