github.com/zhyoulun/cilium@v1.6.12/pkg/policy/l4_test.go (about)

     1  // Copyright 2017-2019 Authors of Cilium
     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  // +build !privileged_tests
    16  
    17  package policy
    18  
    19  import (
    20  	"sort"
    21  
    22  	"github.com/cilium/cilium/api/v1/models"
    23  	"github.com/cilium/cilium/pkg/checker"
    24  	"github.com/cilium/cilium/pkg/labels"
    25  	"github.com/cilium/cilium/pkg/policy/api"
    26  	"github.com/kr/pretty"
    27  
    28  	. "gopkg.in/check.v1"
    29  )
    30  
    31  func (s *PolicyTestSuite) TestCreateL4Filter(c *C) {
    32  	tuple := api.PortProtocol{Port: "80", Protocol: api.ProtoTCP}
    33  	portrule := api.PortRule{
    34  		Ports: []api.PortProtocol{tuple},
    35  		Rules: &api.L7Rules{
    36  			HTTP: []api.PortRuleHTTP{
    37  				{Path: "/public", Method: "GET"},
    38  			},
    39  		},
    40  	}
    41  	selectors := []api.EndpointSelector{
    42  		api.NewESFromLabels(),
    43  		api.NewESFromLabels(labels.ParseSelectLabel("bar")),
    44  	}
    45  
    46  	for _, selector := range selectors {
    47  		eps := []api.EndpointSelector{selector}
    48  		// Regardless of ingress/egress, we should end up with
    49  		// a single L7 rule whether the selector is wildcarded
    50  		// or if it is based on specific labels.
    51  		filter := createL4IngressFilter(eps, false, portrule, tuple, tuple.Protocol, nil, testSelectorCache)
    52  		c.Assert(len(filter.L7RulesPerEp), Equals, 1)
    53  		c.Assert(filter.IsEnvoyRedirect(), Equals, true)
    54  		c.Assert(filter.IsProxylibRedirect(), Equals, false)
    55  
    56  		filter = createL4EgressFilter(eps, portrule, tuple, tuple.Protocol, nil, testSelectorCache, nil)
    57  		c.Assert(len(filter.L7RulesPerEp), Equals, 1)
    58  		c.Assert(filter.IsEnvoyRedirect(), Equals, true)
    59  		c.Assert(filter.IsProxylibRedirect(), Equals, false)
    60  	}
    61  }
    62  
    63  type SortablePolicyRules []*models.PolicyRule
    64  
    65  func (a SortablePolicyRules) Len() int           { return len(a) }
    66  func (a SortablePolicyRules) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
    67  func (a SortablePolicyRules) Less(i, j int) bool { return a[i].Rule < a[j].Rule }
    68  
    69  func (s *PolicyTestSuite) TestJSONMarshal(c *C) {
    70  	model := &models.L4Policy{}
    71  	c.Assert(pretty.Sprintf("%+ v", model.Egress), checker.DeepEquals, "[]")
    72  	c.Assert(pretty.Sprintf("%+ v", model.Ingress), checker.DeepEquals, "[]")
    73  
    74  	policy := L4Policy{
    75  		Egress: L4PolicyMap{
    76  			"8080/TCP": {
    77  				Port:     8080,
    78  				Protocol: api.ProtoTCP,
    79  				Ingress:  false,
    80  			},
    81  		},
    82  		Ingress: L4PolicyMap{
    83  			"80/TCP": {
    84  				Port: 80, Protocol: api.ProtoTCP,
    85  				CachedSelectors: CachedSelectorSlice{cachedFooSelector},
    86  				L7Parser:        "http",
    87  				L7RulesPerEp: L7DataMap{
    88  					cachedFooSelector: api.L7Rules{
    89  						HTTP: []api.PortRuleHTTP{{Path: "/", Method: "GET"}},
    90  					},
    91  				},
    92  				Ingress: true,
    93  			},
    94  			"9090/TCP": {
    95  				Port: 9090, Protocol: api.ProtoTCP,
    96  				CachedSelectors: CachedSelectorSlice{cachedFooSelector},
    97  				L7Parser:        "tester",
    98  				L7RulesPerEp: L7DataMap{
    99  					cachedFooSelector: api.L7Rules{
   100  						L7Proto: "tester",
   101  						L7: []api.PortRuleL7{
   102  							map[string]string{
   103  								"method": "PUT",
   104  								"path":   "/"},
   105  							map[string]string{
   106  								"method": "GET",
   107  								"path":   "/"},
   108  						},
   109  					},
   110  				},
   111  				Ingress: true,
   112  			},
   113  			"8080/TCP": {
   114  				Port: 8080, Protocol: api.ProtoTCP,
   115  				CachedSelectors: CachedSelectorSlice{cachedFooSelector},
   116  				L7Parser:        "http",
   117  				L7RulesPerEp: L7DataMap{
   118  					cachedFooSelector: api.L7Rules{
   119  						HTTP: []api.PortRuleHTTP{
   120  							{Path: "/", Method: "GET"},
   121  							{Path: "/bar", Method: "GET"},
   122  						},
   123  					},
   124  					wildcardCachedSelector: api.L7Rules{
   125  						HTTP: []api.PortRuleHTTP{{Path: "/", Method: "GET"}},
   126  					},
   127  				},
   128  				Ingress: true,
   129  			},
   130  		},
   131  	}
   132  
   133  	model = policy.GetModel()
   134  	c.Assert(model, NotNil)
   135  
   136  	expectedEgress := []string{`{
   137    "port": 8080,
   138    "protocol": "TCP"
   139  }`}
   140  	sort.StringSlice(expectedEgress).Sort()
   141  	sort.Sort(SortablePolicyRules(model.Egress))
   142  	c.Assert(len(expectedEgress), Equals, len(model.Egress))
   143  	for i := range expectedEgress {
   144  		c.Assert(model.Egress[i].Rule, Equals, expectedEgress[i])
   145  	}
   146  
   147  	expectedIngress := []string{`{
   148    "port": 80,
   149    "protocol": "TCP",
   150    "l7-rules": [
   151      {
   152        "\u0026LabelSelector{MatchLabels:map[string]string{any.foo: ,},MatchExpressions:[]LabelSelectorRequirement{},}": {
   153          "http": [
   154            {
   155              "path": "/",
   156              "method": "GET"
   157            }
   158          ]
   159        }
   160      }
   161    ]
   162  }`,
   163  		`{
   164    "port": 9090,
   165    "protocol": "TCP",
   166    "l7-rules": [
   167      {
   168        "\u0026LabelSelector{MatchLabels:map[string]string{any.foo: ,},MatchExpressions:[]LabelSelectorRequirement{},}": {
   169          "l7proto": "tester",
   170          "l7": [
   171            {
   172              "method": "PUT",
   173              "path": "/"
   174            },
   175            {
   176              "method": "GET",
   177              "path": "/"
   178            }
   179          ]
   180        }
   181      }
   182    ]
   183  }`,
   184  		`{
   185    "port": 8080,
   186    "protocol": "TCP",
   187    "l7-rules": [
   188      {
   189        "\u0026LabelSelector{MatchLabels:map[string]string{any.foo: ,},MatchExpressions:[]LabelSelectorRequirement{},}": {
   190          "http": [
   191            {
   192              "path": "/",
   193              "method": "GET"
   194            },
   195            {
   196              "path": "/bar",
   197              "method": "GET"
   198            }
   199          ]
   200        }
   201      },
   202      {
   203        "\u0026LabelSelector{MatchLabels:map[string]string{},MatchExpressions:[]LabelSelectorRequirement{},}": {
   204          "http": [
   205            {
   206              "path": "/",
   207              "method": "GET"
   208            }
   209          ]
   210        }
   211      }
   212    ]
   213  }`}
   214  	sort.StringSlice(expectedIngress).Sort()
   215  	sort.Sort(SortablePolicyRules(model.Ingress))
   216  	c.Assert(len(expectedIngress), Equals, len(model.Ingress))
   217  	for i := range expectedIngress {
   218  		c.Assert(model.Ingress[i].Rule, Equals, expectedIngress[i])
   219  	}
   220  
   221  	c.Assert(policy.HasEnvoyRedirect(), Equals, true)
   222  	c.Assert(policy.HasProxylibRedirect(), Equals, true)
   223  }