github.com/looshlee/cilium@v1.6.12/pkg/k8s/rule_translate_test.go (about)

     1  // Copyright 2016-2017 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 k8s
    18  
    19  import (
    20  	"sort"
    21  
    22  	"github.com/cilium/cilium/pkg/checker"
    23  	"github.com/cilium/cilium/pkg/labels"
    24  	"github.com/cilium/cilium/pkg/loadbalancer"
    25  	"github.com/cilium/cilium/pkg/policy"
    26  	"github.com/cilium/cilium/pkg/policy/api"
    27  	"github.com/cilium/cilium/pkg/service"
    28  
    29  	. "gopkg.in/check.v1"
    30  )
    31  
    32  func (s *K8sSuite) TestTranslatorDirect(c *C) {
    33  	repo := policy.NewPolicyRepository()
    34  
    35  	tag1 := labels.LabelArray{labels.ParseLabel("tag1")}
    36  	serviceInfo := ServiceID{
    37  		Name:      "svc",
    38  		Namespace: "default",
    39  	}
    40  
    41  	epIP := "10.1.1.1"
    42  
    43  	endpointInfo := Endpoints{
    44  		Backends: map[string]service.PortConfiguration{
    45  			epIP: map[string]*loadbalancer.L4Addr{
    46  				"port": {
    47  					Protocol: loadbalancer.TCP,
    48  					Port:     80,
    49  				},
    50  			},
    51  		},
    52  	}
    53  
    54  	rule1 := api.Rule{
    55  		EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")),
    56  		Egress: []api.EgressRule{
    57  			{
    58  				ToServices: []api.Service{
    59  					{
    60  						K8sService: &api.K8sServiceNamespace{
    61  							ServiceName: serviceInfo.Name,
    62  							Namespace:   serviceInfo.Namespace,
    63  						},
    64  					},
    65  				},
    66  			},
    67  		},
    68  		Labels: tag1,
    69  	}
    70  
    71  	translator := NewK8sTranslator(serviceInfo, endpointInfo, false, map[string]string{}, nil)
    72  
    73  	_, _, err := repo.Add(rule1, []policy.Endpoint{})
    74  	c.Assert(err, IsNil)
    75  
    76  	result, err := repo.TranslateRules(translator)
    77  	c.Assert(err, IsNil)
    78  	c.Assert(result.NumToServicesRules, Equals, 1)
    79  
    80  	rule := repo.SearchRLocked(tag1)[0].Egress[0]
    81  
    82  	c.Assert(len(rule.ToCIDRSet), Equals, 1)
    83  	c.Assert(string(rule.ToCIDRSet[0].Cidr), Equals, epIP+"/32")
    84  
    85  	translator = NewK8sTranslator(serviceInfo, endpointInfo, true, map[string]string{}, nil)
    86  	result, err = repo.TranslateRules(translator)
    87  	c.Assert(result.NumToServicesRules, Equals, 1)
    88  
    89  	rule = repo.SearchRLocked(tag1)[0].Egress[0]
    90  
    91  	c.Assert(err, IsNil)
    92  	c.Assert(len(rule.ToCIDRSet), Equals, 0)
    93  }
    94  
    95  func (s *K8sSuite) TestServiceMatches(c *C) {
    96  	svcLabels := map[string]string{
    97  		"app": "tested-service",
    98  	}
    99  
   100  	serviceInfo := ServiceID{
   101  		Name:      "doesn't matter",
   102  		Namespace: "default",
   103  	}
   104  
   105  	epIP := "10.1.1.1"
   106  	endpointInfo := Endpoints{
   107  		Backends: map[string]service.PortConfiguration{
   108  			epIP: map[string]*loadbalancer.L4Addr{
   109  				"port": {
   110  					Protocol: loadbalancer.TCP,
   111  					Port:     80,
   112  				},
   113  			},
   114  		},
   115  	}
   116  
   117  	selector := api.ServiceSelector(api.NewESFromMatchRequirements(svcLabels, nil))
   118  	service := api.Service{
   119  		K8sServiceSelector: &api.K8sServiceSelectorNamespace{
   120  			Selector:  selector,
   121  			Namespace: "",
   122  		},
   123  	}
   124  
   125  	translator := NewK8sTranslator(serviceInfo, endpointInfo, false, svcLabels, nil)
   126  	c.Assert(translator.serviceMatches(service), Equals, true)
   127  }
   128  
   129  func (s *K8sSuite) TestTranslatorLabels(c *C) {
   130  	repo := policy.NewPolicyRepository()
   131  	svcLabels := map[string]string{
   132  		"app": "tested-service",
   133  	}
   134  
   135  	tag1 := labels.LabelArray{labels.ParseLabel("tag1")}
   136  	serviceInfo := ServiceID{
   137  		Name:      "doesn't matter",
   138  		Namespace: "default",
   139  	}
   140  
   141  	epIP := "10.1.1.1"
   142  
   143  	endpointInfo := Endpoints{
   144  		Backends: map[string]service.PortConfiguration{
   145  			epIP: map[string]*loadbalancer.L4Addr{
   146  				"port": {
   147  					Protocol: loadbalancer.TCP,
   148  					Port:     80,
   149  				},
   150  			},
   151  		},
   152  	}
   153  
   154  	selector := api.ServiceSelector(api.NewESFromMatchRequirements(svcLabels, nil))
   155  	rule1 := api.Rule{
   156  		EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")),
   157  		Egress: []api.EgressRule{{
   158  			ToServices: []api.Service{
   159  				{
   160  					K8sServiceSelector: &api.K8sServiceSelectorNamespace{
   161  						Selector:  selector,
   162  						Namespace: "",
   163  					},
   164  				},
   165  			}},
   166  		},
   167  		Labels: tag1,
   168  	}
   169  
   170  	translator := NewK8sTranslator(serviceInfo, endpointInfo, false, svcLabels, nil)
   171  
   172  	_, _, err := repo.Add(rule1, []policy.Endpoint{})
   173  	c.Assert(err, IsNil)
   174  
   175  	result, err := repo.TranslateRules(translator)
   176  	c.Assert(err, IsNil)
   177  	c.Assert(result.NumToServicesRules, Equals, 1)
   178  
   179  	rule := repo.SearchRLocked(tag1)[0].Egress[0]
   180  
   181  	c.Assert(len(rule.ToCIDRSet), Equals, 1)
   182  	c.Assert(string(rule.ToCIDRSet[0].Cidr), Equals, epIP+"/32")
   183  
   184  	translator = NewK8sTranslator(serviceInfo, endpointInfo, true, svcLabels, nil)
   185  	result, err = repo.TranslateRules(translator)
   186  
   187  	rule = repo.SearchRLocked(tag1)[0].Egress[0]
   188  
   189  	c.Assert(err, IsNil)
   190  	c.Assert(len(rule.ToCIDRSet), Equals, 0)
   191  	c.Assert(result.NumToServicesRules, Equals, 1)
   192  }
   193  
   194  func (s *K8sSuite) TestGenerateToCIDRFromEndpoint(c *C) {
   195  	rule := &api.EgressRule{}
   196  
   197  	epIP1 := "10.1.1.1"
   198  	epIP2 := "10.1.1.2"
   199  
   200  	endpointInfo := Endpoints{
   201  		Backends: map[string]service.PortConfiguration{
   202  			epIP1: map[string]*loadbalancer.L4Addr{
   203  				"port": {
   204  					Protocol: loadbalancer.TCP,
   205  					Port:     80,
   206  				},
   207  			},
   208  			epIP2: map[string]*loadbalancer.L4Addr{
   209  				"port": {
   210  					Protocol: loadbalancer.TCP,
   211  					Port:     80,
   212  				},
   213  			},
   214  		},
   215  	}
   216  
   217  	err := generateToCidrFromEndpoint(rule, endpointInfo, nil)
   218  	c.Assert(err, IsNil)
   219  
   220  	cidrs := rule.ToCIDRSet.StringSlice()
   221  	sort.Strings(cidrs)
   222  	c.Assert(len(cidrs), Equals, 2)
   223  	c.Assert(cidrs, checker.DeepEquals, []string{
   224  		epIP1 + "/32",
   225  		epIP2 + "/32",
   226  	})
   227  
   228  	// second run, to make sure there are no duplicates added
   229  	err = generateToCidrFromEndpoint(rule, endpointInfo, nil)
   230  	c.Assert(err, IsNil)
   231  
   232  	cidrs = rule.ToCIDRSet.StringSlice()
   233  	sort.Strings(cidrs)
   234  	c.Assert(len(cidrs), Equals, 2)
   235  	c.Assert(cidrs, checker.DeepEquals, []string{
   236  		epIP1 + "/32",
   237  		epIP2 + "/32",
   238  	})
   239  
   240  	err = deleteToCidrFromEndpoint(rule, endpointInfo, nil)
   241  	c.Assert(err, IsNil)
   242  	c.Assert(len(rule.ToCIDRSet), Equals, 0)
   243  
   244  	// third run, to make sure there are no duplicates added
   245  	err = generateToCidrFromEndpoint(rule, endpointInfo, nil)
   246  	c.Assert(err, IsNil)
   247  
   248  	cidrs = rule.ToCIDRSet.StringSlice()
   249  	sort.Strings(cidrs)
   250  	c.Assert(len(cidrs), Equals, 2)
   251  	c.Assert(cidrs, checker.DeepEquals, []string{
   252  		epIP1 + "/32",
   253  		epIP2 + "/32",
   254  	})
   255  
   256  	err = deleteToCidrFromEndpoint(rule, endpointInfo, nil)
   257  	c.Assert(err, IsNil)
   258  	c.Assert(len(rule.ToCIDRSet), Equals, 0)
   259  }
   260  
   261  func (s *K8sSuite) TestPreprocessRules(c *C) {
   262  	tag1 := labels.LabelArray{labels.ParseLabel("tag1")}
   263  	serviceInfo := ServiceID{
   264  		Name:      "svc",
   265  		Namespace: "default",
   266  	}
   267  
   268  	epIP := "10.1.1.1"
   269  
   270  	cache := NewServiceCache()
   271  
   272  	endpointInfo := Endpoints{
   273  		Backends: map[string]service.PortConfiguration{
   274  			epIP: map[string]*loadbalancer.L4Addr{
   275  				"port": {
   276  					Protocol: loadbalancer.TCP,
   277  					Port:     80,
   278  				},
   279  			},
   280  		},
   281  	}
   282  
   283  	service := Service{IsHeadless: true}
   284  
   285  	rule1 := api.Rule{
   286  		EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")),
   287  		Egress: []api.EgressRule{{
   288  			ToServices: []api.Service{
   289  				{
   290  					K8sService: &api.K8sServiceNamespace{
   291  						ServiceName: serviceInfo.Name,
   292  						Namespace:   serviceInfo.Namespace,
   293  					},
   294  				},
   295  			}},
   296  		},
   297  		Labels: tag1,
   298  	}
   299  
   300  	cache.endpoints = map[ServiceID]*Endpoints{
   301  		serviceInfo: &endpointInfo,
   302  	}
   303  
   304  	cache.services = map[ServiceID]*Service{
   305  		serviceInfo: &service,
   306  	}
   307  
   308  	rules := api.Rules{&rule1}
   309  
   310  	err := PreprocessRules(rules, &cache)
   311  	c.Assert(err, IsNil)
   312  
   313  	c.Assert(len(rule1.Egress[0].ToCIDRSet), Equals, 1)
   314  	c.Assert(string(rule1.Egress[0].ToCIDRSet[0].Cidr), Equals, epIP+"/32")
   315  }
   316  
   317  func (s *K8sSuite) TestDontDeleteUserRules(c *C) {
   318  	userCIDR := api.CIDR("10.1.1.2/32")
   319  	rule := &api.EgressRule{
   320  		ToCIDRSet: []api.CIDRRule{
   321  			{
   322  				Cidr: userCIDR,
   323  			},
   324  		},
   325  	}
   326  
   327  	epIP := "10.1.1.1"
   328  
   329  	endpointInfo := Endpoints{
   330  		Backends: map[string]service.PortConfiguration{
   331  			epIP: map[string]*loadbalancer.L4Addr{
   332  				"port": {
   333  					Protocol: loadbalancer.TCP,
   334  					Port:     80,
   335  				},
   336  			},
   337  		},
   338  	}
   339  
   340  	err := generateToCidrFromEndpoint(rule, endpointInfo, nil)
   341  	c.Assert(err, IsNil)
   342  
   343  	c.Assert(len(rule.ToCIDRSet), Equals, 2)
   344  	c.Assert(string(rule.ToCIDRSet[1].Cidr), Equals, epIP+"/32")
   345  
   346  	// second run, to make sure there are no duplicates added
   347  	err = generateToCidrFromEndpoint(rule, endpointInfo, nil)
   348  	c.Assert(err, IsNil)
   349  
   350  	c.Assert(len(rule.ToCIDRSet), Equals, 2)
   351  	c.Assert(string(rule.ToCIDRSet[1].Cidr), Equals, epIP+"/32")
   352  
   353  	err = deleteToCidrFromEndpoint(rule, endpointInfo, nil)
   354  	c.Assert(err, IsNil)
   355  	c.Assert(len(rule.ToCIDRSet), Equals, 1)
   356  	c.Assert(string(rule.ToCIDRSet[0].Cidr), Equals, string(userCIDR))
   357  }