From bae09f7cc9605544f8bedd4f5b37e1e7fb00026d Mon Sep 17 00:00:00 2001 From: Maciej Kwiek Date: Tue, 24 Oct 2017 14:41:43 +0200 Subject: [PATCH] Move ToCIDR gen logic to k8s package policy.Translator interface is created to allow policy repo to accept custom policy rule manipulation logic Signed-off-by: Maciej Kwiek --- daemon/k8s_watcher.go | 9 +- pkg/k8s/rule_translate.go | 180 ++++++++++++++++++++++++++++++ pkg/k8s/rule_translate_test.go | 170 ++++++++++++++++++++++++++++ pkg/policy/api/utils.go | 196 --------------------------------- pkg/policy/api/utils_test.go | 74 ------------- pkg/policy/policy.go | 6 + pkg/policy/repository.go | 59 +--------- pkg/policy/repository_test.go | 62 ----------- 8 files changed, 366 insertions(+), 390 deletions(-) create mode 100644 pkg/k8s/rule_translate.go create mode 100644 pkg/k8s/rule_translate_test.go diff --git a/daemon/k8s_watcher.go b/daemon/k8s_watcher.go index 1ace7080e184..ca5d335b993e 100644 --- a/daemon/k8s_watcher.go +++ b/daemon/k8s_watcher.go @@ -521,7 +521,8 @@ func (d *Daemon) endpointAddFn(obj interface{}) { svc, ok := d.loadBalancer.K8sServices[svcns] if ok && svc.IsHeadless { - err := d.policy.RegenerateToK8sServiceRules(svcns, *newSvcEP) + translator := k8s.NewK8sTranslator(svcns, *newSvcEP, false) + err := d.policy.TranslateRules(translator) if err != nil { log.Errorf("Unable to repopulate egress policies from ToService rules: %v", err) } @@ -560,7 +561,8 @@ func (d *Daemon) endpointDelFn(obj interface{}) { svc, ok := d.loadBalancer.K8sServices[*svcns] if ok && svc.IsHeadless { - err := d.policy.DeleteEndpointGeneratedEgressRulesWithLock(*svcns, endpoint) + translator := k8s.NewK8sTranslator(*svcns, endpoint, true) + err := d.policy.TranslateRules(translator) if err != nil { log.Errorf("Unable to depopulate egress policies from ToService rules: %v", err) } @@ -1065,7 +1067,8 @@ func (d *Daemon) addCiliumNetworkPolicy(obj interface{}) { rules, err := rule.Parse() if err == nil && len(rules) > 0 { - err = rules.GenerateEgressRulesFromEndpoints( + err = k8s.PreprocessRules( + rules, d.loadBalancer.K8sEndpoints, d.loadBalancer.K8sServices) if err == nil { diff --git a/pkg/k8s/rule_translate.go b/pkg/k8s/rule_translate.go new file mode 100644 index 000000000000..0de3ab1ed1e2 --- /dev/null +++ b/pkg/k8s/rule_translate.go @@ -0,0 +1,180 @@ +// Copyright 2016-2017 Authors of Cilium +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package k8s + +import ( + "fmt" + "net" + + "github.com/cilium/cilium/common/types" + "github.com/cilium/cilium/pkg/policy" + "github.com/cilium/cilium/pkg/policy/api" +) + +var _ policy.Translator = RuleTranslator{} + +// RuleTranslator implements pkg/policy.Translator interface +// Translate populates/depopulates given rule with ToCIDR rules +// Based on provided service/endpoint +type RuleTranslator struct { + Service types.K8sServiceNamespace + Endpoint types.K8sServiceEndpoint + Revert bool +} + +// Translate calls TranslateEgress on all r.Egress rules +func (k RuleTranslator) Translate(r *api.Rule) error { + for egressIndex := range r.Egress { + err := k.TranslateEgress(&r.Egress[egressIndex]) + if err != nil { + return err + } + } + return nil +} + +// TranslateEgress populates/depopulates egress rules with ToCIDR entries based +// on toService entries +func (k RuleTranslator) TranslateEgress(r *api.EgressRule) error { + err := k.depopulateEgress(r) + if err != nil { + return err + } + if !k.Revert { + err := k.populateEgress(r) + if err != nil { + return err + } + } + return nil +} + +func (k RuleTranslator) populateEgress(r *api.EgressRule) error { + for _, service := range r.ToServices { + // TODO: match services by labels + if service.K8sService == api.K8sServiceNamespace(k.Service) { + if err := generateToCidrFromEndpoint(r, k.Endpoint); err != nil { + return err + } + // TODO: generateToPortsFromEndpoint when ToPorts and ToCIDR are compatible + } + } + return nil +} + +func (k RuleTranslator) depopulateEgress(r *api.EgressRule) error { + for _, service := range r.ToServices { + // TODO: match services by labels + if service.K8sService == api.K8sServiceNamespace(k.Service) { + if err := deleteToCidrFromEndpoint(r, k.Endpoint); err != nil { + return err + } + // TODO: generateToPortsFromEndpoint when ToPorts and ToCIDR are compatible + } + } + return nil +} + +// generateToCidrFromEndpoint takes an egress rule and populates it with +// ToCIDR rules based on provided endpoint object +func generateToCidrFromEndpoint( + egress *api.EgressRule, endpoint types.K8sServiceEndpoint) error { + + // This will generate one-address CIDRs consisting of endpoint backend ip + mask := net.CIDRMask(128, 128) + for ip := range endpoint.BEIPs { + epIP := net.ParseIP(ip) + if epIP == nil { + return fmt.Errorf("Unable to parse ip: %s", ip) + } + + found := false + for _, c := range egress.ToCIDR { + _, cidr, err := net.ParseCIDR(string(c)) + if err != nil { + return err + } + if cidr.Contains(epIP) { + found = true + break + } + } + if !found { + cidr := net.IPNet{IP: epIP.Mask(mask), Mask: mask} + egress.ToCIDR = append(egress.ToCIDR, api.CIDR(cidr.String())) + } + } + return nil +} + +// deleteToCidrFromEndpoint takes an egress rule and removes +// ToCIDR rules matching endpoint +func deleteToCidrFromEndpoint( + egress *api.EgressRule, endpoint types.K8sServiceEndpoint) error { + + newToCIDR := make([]api.CIDR, 0, len(egress.ToCIDR)) + + for ip := range endpoint.BEIPs { + epIP := net.ParseIP(ip) + if epIP == nil { + return fmt.Errorf("Unable to parse ip: %s", ip) + } + + for _, c := range egress.ToCIDR { + _, cidr, err := net.ParseCIDR(string(c)) + if err != nil { + return err + } + if !cidr.Contains(epIP) { + //if endpoint is not in CIDR it's ok to retain it + newToCIDR = append(newToCIDR, c) + } + } + } + + egress.ToCIDR = newToCIDR + + return nil +} + +// PreprocessRules translates rules that apply to headless services +func PreprocessRules( + r api.Rules, + endpoints map[types.K8sServiceNamespace]*types.K8sServiceEndpoint, + services map[types.K8sServiceNamespace]*types.K8sServiceInfo) error { + + for _, rule := range r { + for ns, ep := range endpoints { + svc, ok := services[ns] + if ok && svc.IsHeadless { + t := NewK8sTranslator(ns, *ep, false) + err := t.Translate(rule) + if err != nil { + return err + } + } + } + } + return nil +} + +// NewK8sTranslator returns RuleTranslator +func NewK8sTranslator( + serviceInfo types.K8sServiceNamespace, + endpoint types.K8sServiceEndpoint, + revert bool) RuleTranslator { + + return RuleTranslator{serviceInfo, endpoint, revert} +} diff --git a/pkg/k8s/rule_translate_test.go b/pkg/k8s/rule_translate_test.go new file mode 100644 index 000000000000..0f61b44b992c --- /dev/null +++ b/pkg/k8s/rule_translate_test.go @@ -0,0 +1,170 @@ +// Copyright 2016-2017 Authors of Cilium +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package k8s + +import ( + "github.com/cilium/cilium/common/types" + "github.com/cilium/cilium/pkg/labels" + "github.com/cilium/cilium/pkg/policy" + "github.com/cilium/cilium/pkg/policy/api" + + . "gopkg.in/check.v1" +) + +func (s *K8sSuite) TestTranslator(c *C) { + repo := policy.NewPolicyRepository() + + tag1 := labels.LabelArray{labels.ParseLabel("tag1")} + serviceInfo := types.K8sServiceNamespace{ + ServiceName: "svc", + Namespace: "default", + } + + epIP := "10.1.1.1" + + endpointInfo := types.K8sServiceEndpoint{ + BEIPs: map[string]bool{ + epIP: true, + }, + Ports: map[types.FEPortName]*types.L4Addr{ + "port": { + Protocol: types.TCP, + Port: 80, + }, + }, + } + + rule1 := api.Rule{ + EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")), + Egress: []api.EgressRule{{ + ToServices: []api.Service{ + { + K8sService: api.K8sServiceNamespace(serviceInfo), + }, + }}, + }, + Labels: tag1, + } + + translator := NewK8sTranslator(serviceInfo, endpointInfo, false) + + _, err := repo.Add(rule1) + c.Assert(err, IsNil) + + err = repo.TranslateRules(translator) + c.Assert(err, IsNil) + + rule := repo.SearchRLocked(tag1)[0].Egress[0] + + c.Assert(len(rule.ToCIDR), Equals, 1) + c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") + + translator = NewK8sTranslator(serviceInfo, endpointInfo, true) + err = repo.TranslateRules(translator) + + rule = repo.SearchRLocked(tag1)[0].Egress[0] + + c.Assert(err, IsNil) + c.Assert(len(rule.ToCIDR), Equals, 0) +} + +func (s *K8sSuite) TestGenerateToCIDRFromEndpoint(c *C) { + rule := &api.EgressRule{} + + epIP := "10.1.1.1" + + endpointInfo := types.K8sServiceEndpoint{ + BEIPs: map[string]bool{ + epIP: true, + }, + Ports: map[types.FEPortName]*types.L4Addr{ + "port": { + Protocol: types.TCP, + Port: 80, + }, + }, + } + + err := generateToCidrFromEndpoint(rule, endpointInfo) + c.Assert(err, IsNil) + + c.Assert(len(rule.ToCIDR), Equals, 1) + c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") + + // second run, to make sure there are no duplicates added + err = generateToCidrFromEndpoint(rule, endpointInfo) + c.Assert(err, IsNil) + + c.Assert(len(rule.ToCIDR), Equals, 1) + c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") + + err = deleteToCidrFromEndpoint(rule, endpointInfo) + c.Assert(err, IsNil) + c.Assert(len(rule.ToCIDR), Equals, 0) +} + +func (s *K8sSuite) TestPreprocessRules(c *C) { + tag1 := labels.LabelArray{labels.ParseLabel("tag1")} + serviceInfo := types.K8sServiceNamespace{ + ServiceName: "svc", + Namespace: "default", + } + + epIP := "10.1.1.1" + + endpointInfo := types.K8sServiceEndpoint{ + BEIPs: map[string]bool{ + epIP: true, + }, + Ports: map[types.FEPortName]*types.L4Addr{ + "port": { + Protocol: types.TCP, + Port: 80, + }, + }, + } + + service := types.K8sServiceInfo{ + IsHeadless: true, + } + + rule1 := api.Rule{ + EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")), + Egress: []api.EgressRule{{ + ToServices: []api.Service{ + { + K8sService: api.K8sServiceNamespace(serviceInfo), + }, + }}, + }, + Labels: tag1, + } + + endpoints := map[types.K8sServiceNamespace]*types.K8sServiceEndpoint{ + serviceInfo: &endpointInfo, + } + + services := map[types.K8sServiceNamespace]*types.K8sServiceInfo{ + serviceInfo: &service, + } + + rules := api.Rules{&rule1} + + err := PreprocessRules(rules, endpoints, services) + c.Assert(err, IsNil) + + c.Assert(len(rule1.Egress[0].ToCIDR), Equals, 1) + c.Assert(string(rule1.Egress[0].ToCIDR[0]), Equals, epIP+"/32") +} diff --git a/pkg/policy/api/utils.go b/pkg/policy/api/utils.go index 53ec1afc9025..9b20639a1a0b 100644 --- a/pkg/policy/api/utils.go +++ b/pkg/policy/api/utils.go @@ -16,11 +16,7 @@ package api import ( "fmt" - "net" - "strconv" "strings" - - "github.com/cilium/cilium/common/types" ) // Len returns the total number of rules inside `L7Rules`. @@ -101,195 +97,3 @@ func ParseL4Proto(proto string) (L4Proto, error) { p := L4Proto(strings.ToUpper(proto)) return p, p.Validate() } - -// GenerateToServiceRulesFromEndpoint populates egress rule with ToCIDR rules -// based on ToServices defined in egress rule and provided endpoint -func (e *EgressRule) GenerateToServiceRulesFromEndpoint( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - - for _, service := range e.ToServices { - // TODO: match services by labels - if service.K8sService == K8sServiceNamespace(serviceInfo) { - if err := generateToCidrFromEndpoint(e, endpoint); err != nil { - return err - } - // TODO: generateToPortsFromEndpoint when ToPorts and ToCIDR are compatible - } - } - return nil -} - -// generateToCidrFromEndpoint takes an egress rule and populates it with -// ToCIDR rules based on provided endpoint object -func generateToCidrFromEndpoint( - egress *EgressRule, endpoint types.K8sServiceEndpoint) error { - - // This will generate one-address CIDRs consisting of endpoint backend ip - mask := net.CIDRMask(128, 128) - for ip := range endpoint.BEIPs { - epIP := net.ParseIP(ip) - if epIP == nil { - return fmt.Errorf("Unable to parse ip: %s", ip) - } - - found := false - for _, c := range egress.ToCIDR { - _, cidr, err := net.ParseCIDR(string(c)) - if err != nil { - return err - } - if cidr.Contains(epIP) { - found = true - break - } - } - if !found { - cidr := net.IPNet{IP: epIP.Mask(mask), Mask: mask} - egress.ToCIDR = append(egress.ToCIDR, CIDR(cidr.String())) - } - } - return nil -} - -// generateToPortsFromEndpoint takes an egress rule and populates it with ToPorts -// rules based on provided endpoint object -func generateToPortsFromEndpoint( - egress *EgressRule, endpoint types.K8sServiceEndpoint) error { - - // additional port rule that will contain all endpoint ports - portRule := PortRule{} - for _, port := range endpoint.Ports { - found := false - loop: - for _, portRule := range egress.ToPorts { - for _, portProtocol := range portRule.Ports { - numericPort, err := strconv.Atoi(portProtocol.Port) - if err != nil { - return err - } - - ruleProt := strings.ToLower(string(portProtocol.Protocol)) - endpointProt := strings.ToLower(string(port.Protocol)) - - if ruleProt == endpointProt && int(port.Port) == numericPort { - found = true - break loop - } - } - } - if !found { - portRule.Ports = append(portRule.Ports, PortProtocol{ - Port: strconv.Itoa(int(port.Port)), - Protocol: L4Proto(strings.ToUpper(string(port.Protocol))), - }) - } - } - - if len(portRule.Ports) > 0 { - egress.ToPorts = append(egress.ToPorts, portRule) - } - - return nil -} - -// DeleteGeneratedToServiceRulesFromEndpoint removes all ToService-based ToCIDR -// rules generated from endpoint -func (e *EgressRule) DeleteGeneratedToServiceRulesFromEndpoint( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - - for _, service := range e.ToServices { - // TODO: match services by labels - if service.K8sService == K8sServiceNamespace(serviceInfo) { - if err := deleteToCidrFromEndpoint(e, endpoint); err != nil { - return err - } - // TODO: deleteToPortsFromEndpoint when ToPorts and ToCIDR are compatible - } - } - return nil -} - -// deleteToCidrFromEndpoint takes an egress rule and removes -// ToCIDR rules matching endpoint -func deleteToCidrFromEndpoint( - egress *EgressRule, endpoint types.K8sServiceEndpoint) error { - - newToCIDR := make([]CIDR, 0, len(egress.ToCIDR)) - - for ip := range endpoint.BEIPs { - epIP := net.ParseIP(ip) - if epIP == nil { - return fmt.Errorf("Unable to parse ip: %s", ip) - } - - for _, c := range egress.ToCIDR { - _, cidr, err := net.ParseCIDR(string(c)) - if err != nil { - return err - } - if !cidr.Contains(epIP) { - //if endpoint is not in CIDR it's ok to retain it - newToCIDR = append(newToCIDR, c) - } - } - } - - egress.ToCIDR = newToCIDR - - return nil -} - -// deleteToPortsFromEndpoint takes an egress rule and removes -// ToPorts rules matching endpoint -func deleteToPortsFromEndpoint( - egress *EgressRule, endpoint types.K8sServiceEndpoint) error { - - newPortRules := make([]PortRule, 0, len(egress.ToPorts)) - - for _, port := range endpoint.Ports { - for _, portRule := range egress.ToPorts { - for _, portProtocol := range portRule.Ports { - numericPort, err := strconv.Atoi(portProtocol.Port) - if err != nil { - return err - } - - ruleProt := strings.ToLower(string(portProtocol.Protocol)) - endpointProt := strings.ToLower(string(port.Protocol)) - - if endpointProt != ruleProt || int(port.Port) != numericPort { - newPortRules = append(newPortRules, portRule) - } - } - } - } - - egress.ToPorts = newPortRules - - return nil -} - -// GenerateEgressRulesFromEndpoints matches all egress rules against provided -// endpoint data and generates ToCIDR rules. Services are provided to check -// for headless services -func (r Rules) GenerateEgressRulesFromEndpoints( - endpoints map[types.K8sServiceNamespace]*types.K8sServiceEndpoint, - services map[types.K8sServiceNamespace]*types.K8sServiceInfo) error { - - for _, rule := range r { - for index := range rule.Egress { - for ns, ep := range endpoints { - svc, ok := services[ns] - if ok && svc.IsHeadless { - err := rule.Egress[index].GenerateToServiceRulesFromEndpoint(ns, *ep) - if err != nil { - return err - } - } - } - } - } - return nil -} diff --git a/pkg/policy/api/utils_test.go b/pkg/policy/api/utils_test.go index 531bb270b17c..30a01267984b 100644 --- a/pkg/policy/api/utils_test.go +++ b/pkg/policy/api/utils_test.go @@ -18,8 +18,6 @@ import ( "testing" . "gopkg.in/check.v1" - - "github.com/cilium/cilium/common/types" ) // Hook up gocheck into the "go test" runner. @@ -91,75 +89,3 @@ func (s *PolicyAPITestSuite) TestParseL4Proto(c *C) { _, err = ParseL4Proto("foo2") c.Assert(err, Not(IsNil)) } - -func (s *PolicyAPITestSuite) TestGenerateToCIDRFromEndpoint(c *C) { - rule := &EgressRule{} - - epIP := "10.1.1.1" - - endpointInfo := types.K8sServiceEndpoint{ - BEIPs: map[string]bool{ - epIP: true, - }, - Ports: map[types.FEPortName]*types.L4Addr{ - "port": &types.L4Addr{ - Protocol: types.TCP, - Port: 80, - }, - }, - } - - err := generateToCidrFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - - c.Assert(len(rule.ToCIDR), Equals, 1) - c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") - - // second run, to make sure there are no duplicates added - err = generateToCidrFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - - c.Assert(len(rule.ToCIDR), Equals, 1) - c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") - - err = deleteToCidrFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - c.Assert(len(rule.ToCIDR), Equals, 0) -} - -func (s *PolicyAPITestSuite) TestGenerateToPortsFromEndpoint(c *C) { - rule := &EgressRule{} - - epIP := "10.1.1.1" - - endpointInfo := types.K8sServiceEndpoint{ - BEIPs: map[string]bool{ - epIP: true, - }, - Ports: map[types.FEPortName]*types.L4Addr{ - "port": &types.L4Addr{ - Protocol: types.TCP, - Port: 80, - }, - }, - } - - err := generateToPortsFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - - c.Assert(len(rule.ToPorts), Equals, 1) - c.Assert(rule.ToPorts[0].Ports[0].Port, Equals, "80") - c.Assert(string(rule.ToPorts[0].Ports[0].Protocol), Equals, "TCP") - - // second run, to make sure there are no duplicates added - err = generateToCidrFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - - c.Assert(len(rule.ToPorts), Equals, 1) - c.Assert(rule.ToPorts[0].Ports[0].Port, Equals, "80") - c.Assert(string(rule.ToPorts[0].Ports[0].Protocol), Equals, "TCP") - - err = deleteToPortsFromEndpoint(rule, endpointInfo) - c.Assert(err, IsNil) - c.Assert(len(rule.ToPorts), Equals, 0) -} diff --git a/pkg/policy/policy.go b/pkg/policy/policy.go index 46eaf7f1caa5..4528ccf6bdd2 100644 --- a/pkg/policy/policy.go +++ b/pkg/policy/policy.go @@ -21,6 +21,7 @@ import ( "github.com/cilium/cilium/api/v1/models" "github.com/cilium/cilium/pkg/labels" + "github.com/cilium/cilium/pkg/policy/api" "github.com/op/go-logging" log "github.com/sirupsen/logrus" @@ -99,3 +100,8 @@ func (s *SearchContext) String() string { func (s *SearchContext) CallDepth() string { return strconv.Itoa(s.Depth * 2) } + +// Translator is an interface for altering policy rules +type Translator interface { + Translate(*api.Rule) error +} diff --git a/pkg/policy/repository.go b/pkg/policy/repository.go index 148bab7ee7cd..dd9fe453e442 100644 --- a/pkg/policy/repository.go +++ b/pkg/policy/repository.go @@ -17,7 +17,6 @@ package policy import ( "encoding/json" - "github.com/cilium/cilium/common/types" "github.com/cilium/cilium/pkg/labels" "github.com/cilium/cilium/pkg/lock" "github.com/cilium/cilium/pkg/policy/api" @@ -393,64 +392,14 @@ func (p *Repository) GetRevision() uint64 { return p.revision } -// RegenerateToK8sServiceRules deletes to CIDR rules that were generated from -// provided service-endpoint pair and regenerates them -func (p *Repository) RegenerateToK8sServiceRules( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - +// TranslateRules traverses rules and applies provided translator to rules +func (p *Repository) TranslateRules(translator Translator) error { p.Mutex.Lock() defer p.Mutex.Unlock() - if err := p.DeleteEndpointGeneratedEgressRules(serviceInfo, endpoint); err != nil { - return err - } - - return p.ConvertToK8sServiceToToCIDR(serviceInfo, endpoint) -} - -// ConvertToK8sServiceToToCIDR traverses all egress rules and matches them against -// provided serviceInfo. If a matching egress rule is found it is populated -// with ToCIDR entries based on endpoint object. -func (p *Repository) ConvertToK8sServiceToToCIDR( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - for ruleIndex := range p.rules { - for index := range p.rules[ruleIndex].Egress { - err := p.rules[ruleIndex].Egress[index].GenerateToServiceRulesFromEndpoint(serviceInfo, endpoint) - if err != nil { - return err - } - } - } - return nil -} - -// DeleteEndpointGeneratedEgressRulesWithLock calls -// DeleteEndpointGeneratedEgressRules while locking policy mutex -func (p *Repository) DeleteEndpointGeneratedEgressRulesWithLock( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - - p.Mutex.Lock() - defer p.Mutex.Unlock() - return p.DeleteEndpointGeneratedEgressRules(serviceInfo, endpoint) -} - -// DeleteEndpointGeneratedEgressRules traverses all egress rules, -// matches them against provided service info and deletes ToCIDR -// entries that match provided endpoint -func (p *Repository) DeleteEndpointGeneratedEgressRules( - serviceInfo types.K8sServiceNamespace, - endpoint types.K8sServiceEndpoint) error { - - for policyRuleIndex := range p.rules { - for egressIndex := range p.rules[policyRuleIndex].Egress { - err := p.rules[policyRuleIndex].Egress[egressIndex].DeleteGeneratedToServiceRulesFromEndpoint(serviceInfo, endpoint) - if err != nil { - return err - } + if err := translator.Translate(&p.rules[ruleIndex].Rule); err != nil { + return err } } return nil diff --git a/pkg/policy/repository_test.go b/pkg/policy/repository_test.go index 849841983741..a5acf526dfa7 100644 --- a/pkg/policy/repository_test.go +++ b/pkg/policy/repository_test.go @@ -18,7 +18,6 @@ import ( "bytes" "github.com/cilium/cilium/api/v1/models" - "github.com/cilium/cilium/common/types" "github.com/cilium/cilium/pkg/comparator" "github.com/cilium/cilium/pkg/labels" "github.com/cilium/cilium/pkg/policy/api" @@ -588,64 +587,3 @@ Label verdict: undecided repo.Mutex.RUnlock() c.Assert(verdict, Equals, api.Allowed) } - -func (ds *PolicyTestSuite) TestConvertToK8sServiceToToCIDR(c *C) { - repo := NewPolicyRepository() - - tag1 := labels.LabelArray{labels.ParseLabel("tag1")} - serviceInfo := types.K8sServiceNamespace{ - ServiceName: "svc", - Namespace: "default", - } - - epIP := "10.1.1.1" - - endpointInfo := types.K8sServiceEndpoint{ - BEIPs: map[string]bool{ - epIP: true, - }, - Ports: map[types.FEPortName]*types.L4Addr{ - "port": &types.L4Addr{ - Protocol: types.TCP, - Port: 80, - }, - }, - } - - rule1 := api.Rule{ - EndpointSelector: api.NewESFromLabels(labels.ParseSelectLabel("bar")), - Egress: []api.EgressRule{{ - ToServices: []api.Service{ - api.Service{ - K8sService: api.K8sServiceNamespace(serviceInfo), - }, - }}, - }, - Labels: tag1, - } - - _, err := repo.Add(rule1) - c.Assert(err, IsNil) - - err = repo.ConvertToK8sServiceToToCIDR(serviceInfo, endpointInfo) - c.Assert(err, IsNil) - - rule := repo.rules[0].Egress[0] - - c.Assert(len(rule.ToCIDR), Equals, 1) - c.Assert(string(rule.ToCIDR[0]), Equals, epIP+"/32") - - // TODO: test ToPorts when ToCIDR and ToPorts are compatible - //c.Assert(len(rule.ToPorts), Equals, 1) - //c.Assert(rule.ToPorts[0].Ports[0].Port, Equals, "80") - //c.Assert(string(rule.ToPorts[0].Ports[0].Protocol), Equals, "TCP") - - err = repo.DeleteEndpointGeneratedEgressRules(serviceInfo, endpointInfo) - - rule = repo.rules[0].Egress[0] - - c.Assert(err, IsNil) - c.Assert(len(rule.ToCIDR), Equals, 0) - // TODO: test ToPorts when ToCIDR and ToPorts are compatible - //c.Assert(len(rule.ToPorts), Equals, 0) -}