From f4b735216f2b0491ea8d548f36335d27c095b396 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 2 Apr 2019 15:38:04 -0700 Subject: [PATCH 01/64] parse selectors to kv based labels --- npm/nwpolicy.go | 85 +++++++---- npm/parsePolicy.go | 29 ++++ npm/parseSelector.go | 56 +++++++ npm/parseSelector_test.go | 213 +++++++++++++++++++++++++++ npm/{parse.go => translatePolicy.go} | 0 5 files changed, 356 insertions(+), 27 deletions(-) create mode 100644 npm/parsePolicy.go create mode 100644 npm/parseSelector.go create mode 100644 npm/parseSelector_test.go rename npm/{parse.go => translatePolicy.go} (100%) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 77b009b75e..cd8564ed64 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -13,7 +13,10 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.Lock() defer npMgr.Unlock() - var err error + var ( + err error + ns *namespace + ) defer func() { if err = npMgr.UpdateAndSendReport(err, util.AddNetworkPolicyEvent); err != nil { @@ -24,6 +27,15 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name log.Printf("NETWORK POLICY CREATING: %s/%s\n", npNs, npName) + var exists bool + if ns, exists = npMgr.nsMap[npNs]; !exists { + ns, err = newNs(npNs) + if err != nil { + log.Printf("Error creating namespace %s\n", npNs) + } + npMgr.nsMap[npNs] = ns + } + allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] if !npMgr.isAzureNpmChainCreated { @@ -40,43 +52,62 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.isAzureNpmChainCreated = true } - podSets, nsLists, iptEntries := parsePolicy(npObj) - - ipsMgr := allNs.ipsMgr - for _, set := range podSets { - if err = ipsMgr.CreateSet(set); err != nil { - log.Printf("Error creating ipset %s-%s\n", npNs, set) - return err + labels, newPolicies := splitPolicy(npObj) + var ( + mergedPolicy *networkingv1.NetworkPolicy + oldPolicies []*networkingv1.NetworkPolicy + mergedPolicies []*networkingv1.NetworkPolicy + ) + for i := range newPolicies { + label, newPolicy := labels[i], newPolicies[i] + if oldPolicy, exists := ns.npMap[label]; exists { + mergedPolicy, err = mergePolicy(oldPolicy, newPolicy) + oldPolicies = append(oldPolicies, oldPolicy) + mergedPolicies = append(mergedPolicies, mergedPolicy) + continue } + mergedPolicies = append(mergedPolicies, newPolicy) } - for _, list := range nsLists { - if err = ipsMgr.CreateList(list); err != nil { - log.Printf("Error creating ipset list %s-%s\n", npNs, list) - return err - } + npMgr.Unlock() + for _, oldPolicy := range oldPolicies { + npMgr.DeleteNetworkPolicy(oldPolicy) } + npMgr.Lock() - if err = npMgr.InitAllNsList(); err != nil { - log.Printf("Error initializing all-namespace ipset list.\n") - return err - } + for _, mergedPolicy = range mergedPolicies { - iptMgr := allNs.iptMgr - for _, iptEntry := range iptEntries { - if err = iptMgr.Add(iptEntry); err != nil { - log.Printf("Error applying iptables rule\n. Rule: %+v", iptEntry) + podSets, nsLists, iptEntries := parsePolicy(npObj) + + ipsMgr := allNs.ipsMgr + for _, set := range podSets { + if err = ipsMgr.CreateSet(set); err != nil { + log.Printf("Error creating ipset %s-%s\n", npNs, set) + return err + } + } + + for _, list := range nsLists { + if err = ipsMgr.CreateList(list); err != nil { + log.Printf("Error creating ipset list %s-%s\n", npNs, list) + return err + } + } + + if err = npMgr.InitAllNsList(); err != nil { + log.Printf("Error initializing all-namespace ipset list.\n") return err } - } - allNs.npMap[npName] = npObj + iptMgr := allNs.iptMgr + for _, iptEntry := range iptEntries { + if err = iptMgr.Add(iptEntry); err != nil { + log.Printf("Error applying iptables rule\n. Rule: %+v", iptEntry) + return err + } + } - ns, err := newNs(npNs) - if err != nil { - log.Printf("Error creating namespace %s\n", npNs) } - npMgr.nsMap[npNs] = ns return nil } diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go new file mode 100644 index 0000000000..5a7b77cb6c --- /dev/null +++ b/npm/parsePolicy.go @@ -0,0 +1,29 @@ +// Copyright 2018 Microsoft. All rights reserved. +// MIT License +package npm + +import ( + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.NetworkPolicy) { + var policies []*networkingv1.NetworkPolicy + + labels, keys, vals := ParseSelector(&(npObj.Spec.PodSelector)) + for i := range keys { + policy := *npObj + policy.Spec.PodSelector.MatchExpressions = []metav1.LabelSelectorRequirement{} + policy.Spec.PodSelector.MatchLabels[keys[i]] = vals[i] + policies = append(policies, &policy) + } + + return labels, policies +} + +// mergePolicy merges policies based on labels. +func mergePolicy(old *networkingv1.NetworkPolicy, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { + // if namespace matches && podSelector matches, then merge + // else return as is. + return &networkingv1.NetworkPolicy{}, nil +} diff --git a/npm/parseSelector.go b/npm/parseSelector.go new file mode 100644 index 0000000000..c719b6050e --- /dev/null +++ b/npm/parseSelector.go @@ -0,0 +1,56 @@ +package npm + +import ( + "github.com/Azure/azure-container-networking/log" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// ParseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. +func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { + var ( + labels []string + keys []string + vals []string + ) + for k, v := range selector.MatchLabels { + labels = append(labels, k+":"+v) + keys = append(keys, k) + vals = append(vals, v) + } + + for _, req := range selector.MatchExpressions { + var k string + switch op := req.Operator; op { + case metav1.LabelSelectorOpIn: + for _, v := range req.Values { + k = req.Key + keys = append(keys, k) + vals = append(vals, v) + labels = append(labels, k+":"+v) + } + case metav1.LabelSelectorOpNotIn: + for _, v := range req.Values { + k = "!" + req.Key + keys = append(keys, k) + vals = append(vals, v) + labels = append(labels, k+":"+v) + } + // Exists matches pods with req.Key as key + case metav1.LabelSelectorOpExists: + k = req.Key + keys = append(keys, req.Key) + vals = append(vals, "") + labels = append(labels, k) + // DoesNotExist matches pods without req.Key as key + case metav1.LabelSelectorOpDoesNotExist: + k = "!" + req.Key + keys = append(keys, k) + vals = append(vals, "") + labels = append(labels, k) + default: + log.Errorf("Invalid operator [%s] for selector [%v] requirement", op, *selector) + } + } + + return labels, keys, vals +} diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go new file mode 100644 index 0000000000..4dcf3bd3d3 --- /dev/null +++ b/npm/parseSelector_test.go @@ -0,0 +1,213 @@ +package npm + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestParseSelector(t *testing.T) { + selector := &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + } + + labels, keys, vals := ParseSelector(selector) + expectedLabels := []string{ + "testIn:frontend", + "testIn:backend", + } + expectedKeys := []string{ + "testIn", + "testIn", + } + expectedVals := []string{ + "frontend", + "backend", + } + + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(vals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + for i := range labels { + if labels[i] != expectedLabels[i] { + t.Errorf("TestparseSelector failed @ label comparison") + } + + if keys[i] != expectedKeys[i] { + t.Errorf("TestparseSelector failed @ key comparison") + } + + if vals[i] != expectedVals[i] { + t.Errorf("TestparseSelector failed @ value comparison") + } + } + + notIn := metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + "backend", + }, + } + + me := &selector.MatchExpressions + *me = append(*me, notIn) + + labels, keys, vals = ParseSelector(selector) + addedLabels := []string{ + "!testNotIn:frontend", + "!testNotIn:backend", + } + addedKeys := []string{ + "!testNotIn", + "!testNotIn", + } + addedVals := []string{ + "frontend", + "backend", + } + expectedLabels = append(expectedLabels, addedLabels...) + expectedKeys = append(expectedKeys, addedKeys...) + expectedVals = append(expectedVals, addedVals...) + + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(vals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + for i := range labels { + if labels[i] != expectedLabels[i] { + t.Errorf("TestparseSelector failed @ label comparison") + } + + if keys[i] != expectedKeys[i] { + t.Errorf("TestparseSelector failed @ key comparison") + } + + if vals[i] != expectedVals[i] { + t.Errorf("TestparseSelector failed @ value comparison") + } + } + + exists := metav1.LabelSelectorRequirement{ + Key: "testExists", + Operator: metav1.LabelSelectorOpExists, + Values: []string{}, + } + + *me = append(*me, exists) + + labels, keys, vals = ParseSelector(selector) + addedLabels = []string{ + "testExists", + } + addedKeys = []string{ + "testExists", + } + addedVals = []string{ + "", + } + expectedLabels = append(expectedLabels, addedLabels...) + expectedKeys = append(expectedKeys, addedKeys...) + expectedVals = append(expectedVals, addedVals...) + + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(vals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + for i := range labels { + if labels[i] != expectedLabels[i] { + t.Errorf("TestparseSelector failed @ label comparison") + } + + if keys[i] != expectedKeys[i] { + t.Errorf("TestparseSelector failed @ key comparison") + } + + if vals[i] != expectedVals[i] { + t.Errorf("TestparseSelector failed @ value comparison") + } + } + + doesNotExist := metav1.LabelSelectorRequirement{ + Key: "testDoesNotExist", + Operator: metav1.LabelSelectorOpDoesNotExist, + Values: []string{}, + } + + *me = append(*me, doesNotExist) + + labels, keys, vals = ParseSelector(selector) + addedLabels = []string{ + "!testDoesNotExist", + } + addedKeys = []string{ + "!testDoesNotExist", + } + addedVals = []string{ + "", + } + expectedLabels = append(expectedLabels, addedLabels...) + expectedKeys = append(expectedKeys, addedKeys...) + expectedVals = append(expectedVals, addedVals...) + + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(vals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + for i := range labels { + if labels[i] != expectedLabels[i] { + t.Errorf("TestparseSelector failed @ label comparison") + } + + if keys[i] != expectedKeys[i] { + t.Errorf("TestparseSelector failed @ key comparison") + } + + if vals[i] != expectedVals[i] { + t.Errorf("TestparseSelector failed @ value comparison") + } + } +} diff --git a/npm/parse.go b/npm/translatePolicy.go similarity index 100% rename from npm/parse.go rename to npm/translatePolicy.go From 61acc0b693bbd8671ee48c8cbee5858eb68aa578 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 2 Apr 2019 17:01:05 -0700 Subject: [PATCH 02/64] TestsplitPolicy --- npm/parsePolicy.go | 2 +- npm/parsePolicy_test.go | 129 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 npm/parsePolicy_test.go diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 5a7b77cb6c..43baa5739d 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -14,7 +14,7 @@ func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.N for i := range keys { policy := *npObj policy.Spec.PodSelector.MatchExpressions = []metav1.LabelSelectorRequirement{} - policy.Spec.PodSelector.MatchLabels[keys[i]] = vals[i] + policy.Spec.PodSelector.MatchLabels = map[string]string{keys[i]: vals[i]} policies = append(policies, &policy) } diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go new file mode 100644 index 0000000000..8f0737e6db --- /dev/null +++ b/npm/parsePolicy_test.go @@ -0,0 +1,129 @@ +package npm + +import ( + "reflect" + "testing" + + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestSplitPolicy(t *testing.T) { + policy := &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + "protocol": "https", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "testDoesNotExist", + Operator: metav1.LabelSelectorOpDoesNotExist, + }, + }, + }, + }, + } + + labels, policies := splitPolicy(policy) + + expectedLabels := []string{ + "role:client", + "protocol:https", + "testIn:frontend", + "testIn:backend", + "!testDoesNotExist", + } + + expectedPolicies := []*networkingv1.NetworkPolicy{ + &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "protocol": "https", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testIn": "frontend", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "testIn": "backend", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + &networkingv1.NetworkPolicy{ + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "!testDoesNotExist": "", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, + } + + if len(labels) != len(expectedLabels) { + t.Errorf("TestsplitPolicy failed @ labels length comparison") + } + + if len(policies) != len(expectedPolicies) { + t.Errorf("TestsplitPolicy failed @ policies length comparison") + } + + for i := range labels { + if labels[i] != expectedLabels[i] { + t.Errorf("TestsplitPolicy failed @ label comparison") + } + + if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchLabels, expectedPolicies[i].Spec.PodSelector.MatchLabels) { + t.Errorf("TestsplitPolicy failed @ MatchLabels comparison") + } + + if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchExpressions, expectedPolicies[i].Spec.PodSelector.MatchExpressions) { + t.Errorf("TestsplitPolicy failed @ MatchExpressions comparison") + } + + if !reflect.DeepEqual(policies[i].Spec.PodSelector, expectedPolicies[i].Spec.PodSelector) { + t.Error("TestsplitPolicy failed @ PodSelector comparison") + } + + if !reflect.DeepEqual(*(policies[i]), *(expectedPolicies[i])) { + t.Error("TestsplitPolicy failed @ policy comparison") + } + } +} From 3dbbd368fd545c339f8caf712f7f48d5982616f3 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 3 Apr 2019 11:53:43 -0700 Subject: [PATCH 03/64] ParseLabel --- npm/parseSelector.go | 19 ++++++++++++++--- npm/parseSelector_test.go | 44 +++++++++++++++++++++++++++++++++++++++ npm/util/const.go | 1 + 3 files changed, 61 insertions(+), 3 deletions(-) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index c719b6050e..04db8aea2a 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -1,10 +1,23 @@ package npm import ( - "github.com/Azure/azure-container-networking/log" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/Azure/azure-container-networking/log" + "github.com/Azure/azure-container-networking/npm/util" ) +// ParseLabel takes a Azure-NPM processed label then returns if it's referring to complement set, +// and if so, returns the original set as well. +func ParseLabel(label string) (string, bool) { + //The input label is guaranteed to have a non-zero length validated by k8s. + //For label definition, see below ParseSelector() function. + if label[0:1] == util.IptablesNotFlag { + return label[1:], true + } + return label, false +} + // ParseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { var ( @@ -30,7 +43,7 @@ func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string } case metav1.LabelSelectorOpNotIn: for _, v := range req.Values { - k = "!" + req.Key + k = util.IptablesNotFlag + req.Key keys = append(keys, k) vals = append(vals, v) labels = append(labels, k+":"+v) @@ -43,7 +56,7 @@ func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string labels = append(labels, k) // DoesNotExist matches pods without req.Key as key case metav1.LabelSelectorOpDoesNotExist: - k = "!" + req.Key + k = util.IptablesNotFlag + req.Key keys = append(keys, k) vals = append(vals, "") labels = append(labels, k) diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index 4dcf3bd3d3..fddd3c05cd 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -6,6 +6,50 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func TestParseLabel(t *testing.T) { + label, isComplementSet := ParseLabel("test:frontend") + expectedLabel := "test:frontend" + if isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("!test:frontend") + expectedLabel = "test:frontend" + if !isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("test") + expectedLabel = "test" + if isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("!test") + expectedLabel = "test" + if !isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("!!test") + expectedLabel = "!test" + if !isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("test:!frontend") + expectedLabel = "test:!frontend" + if isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } + + label, isComplementSet = ParseLabel("!test:!frontend") + expectedLabel = "test:!frontend" + if !isComplementSet || label != expectedLabel { + t.Errorf("TestParseLabel failed @ label %s", label) + } +} + func TestParseSelector(t *testing.T) { selector := &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ diff --git a/npm/util/const.go b/npm/util/const.go index 880b893d2f..e723f77704 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -38,6 +38,7 @@ const ( IptablesDrop string = "DROP" IptablesSrcFlag string = "src" IptablesDstFlag string = "dst" + IptablesNotFlag string = "!" IptablesProtFlag string = "-p" IptablesSFlag string = "-s" IptablesDFlag string = "-d" From d4ec358d3ccafbb7d0808f77a9782a9e84bfa108 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 9 Apr 2019 11:38:22 -0700 Subject: [PATCH 04/64] addPolicy --- npm/nwpolicy.go | 14 +- npm/parsePolicy.go | 48 ++++++- npm/parsePolicy_test.go | 296 +++++++++++++++++++++++++++++++++++++- npm/parseSelector.go | 11 ++ npm/parseSelector_test.go | 127 +++++++++------- 5 files changed, 434 insertions(+), 62 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index cd8564ed64..ec11d46411 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -54,19 +54,19 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP labels, newPolicies := splitPolicy(npObj) var ( - mergedPolicy *networkingv1.NetworkPolicy - oldPolicies []*networkingv1.NetworkPolicy - mergedPolicies []*networkingv1.NetworkPolicy + addedPolicy *networkingv1.NetworkPolicy + oldPolicies []*networkingv1.NetworkPolicy + addedPolicies []*networkingv1.NetworkPolicy ) for i := range newPolicies { label, newPolicy := labels[i], newPolicies[i] if oldPolicy, exists := ns.npMap[label]; exists { - mergedPolicy, err = mergePolicy(oldPolicy, newPolicy) + addedPolicy, err = addPolicy(oldPolicy, newPolicy) oldPolicies = append(oldPolicies, oldPolicy) - mergedPolicies = append(mergedPolicies, mergedPolicy) + addedPolicies = append(addedPolicies, addedPolicy) continue } - mergedPolicies = append(mergedPolicies, newPolicy) + addedPolicies = append(addedPolicies, newPolicy) } npMgr.Unlock() @@ -75,7 +75,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP } npMgr.Lock() - for _, mergedPolicy = range mergedPolicies { + for _, addedPolicy = range addedPolicies { podSets, nsLists, iptEntries := parsePolicy(npObj) diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 43baa5739d..b958d018fa 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -3,6 +3,9 @@ package npm import ( + "fmt" + "reflect" + networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -13,6 +16,7 @@ func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.N labels, keys, vals := ParseSelector(&(npObj.Spec.PodSelector)) for i := range keys { policy := *npObj + policy.ObjectMeta.Name = labels[i] policy.Spec.PodSelector.MatchExpressions = []metav1.LabelSelectorRequirement{} policy.Spec.PodSelector.MatchLabels = map[string]string{keys[i]: vals[i]} policies = append(policies, &policy) @@ -21,9 +25,47 @@ func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.N return labels, policies } -// mergePolicy merges policies based on labels. -func mergePolicy(old *networkingv1.NetworkPolicy, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { +// addPolicy merges policies based on labels. +func addPolicy(old *networkingv1.NetworkPolicy, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { // if namespace matches && podSelector matches, then merge // else return as is. - return &networkingv1.NetworkPolicy{}, nil + if !reflect.DeepEqual(old.TypeMeta, new.TypeMeta) { + return nil, fmt.Errorf("Old and new networkpolicy don't have the same TypeMeta") + } + if old.ObjectMeta.Namespace != new.ObjectMeta.Namespace { + return nil, fmt.Errorf("Old and new networkpolicy don't have the same namespace") + } + + if len(old.Spec.PodSelector.MatchLabels) != 1 || !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { + return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") + } + + addedPolicy := &networkingv1.NetworkPolicy{ + TypeMeta: old.TypeMeta, + ObjectMeta: metav1.ObjectMeta{ + Name: old.ObjectMeta.Name, + Namespace: old.ObjectMeta.Namespace, + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: old.Spec.PodSelector, + }, + } + + spec := &(addedPolicy.Spec) + if len(old.Spec.PolicyTypes) == 1 && old.Spec.PolicyTypes[0] == networkingv1.PolicyTypeEgress && + len(new.Spec.PolicyTypes) == 1 && new.Spec.PolicyTypes[0] == networkingv1.PolicyTypeEgress { + spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress} + } else { + spec.PolicyTypes = []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + } + } + + ingress := append(old.Spec.Ingress, new.Spec.Ingress...) + egress := append(old.Spec.Egress, new.Spec.Egress...) + addedPolicy.Spec.Ingress = ingress + addedPolicy.Spec.Egress = egress + + return addedPolicy, nil } diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go index 8f0737e6db..b9d2311888 100644 --- a/npm/parsePolicy_test.go +++ b/npm/parsePolicy_test.go @@ -1,11 +1,14 @@ package npm import ( + "fmt" "reflect" "testing" + "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" ) func TestSplitPolicy(t *testing.T) { @@ -106,7 +109,7 @@ func TestSplitPolicy(t *testing.T) { } for i := range labels { - if labels[i] != expectedLabels[i] { + if !reflect.DeepEqual(labels, expectedLabels) { t.Errorf("TestsplitPolicy failed @ label comparison") } @@ -127,3 +130,294 @@ func TestSplitPolicy(t *testing.T) { } } } + +func TestAddPolicy(t *testing.T) { + tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP + port6783, port6784 := intstr.FromInt(6783), intstr.FromInt(6784) + oldIngressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "db", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + } + oldIngressNamespaceSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend-ns", + "backend-ns", + }, + }, + }, + } + oldEgressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "sql", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + } + oldPolicy := networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6783, + }, + }, + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldIngressPodSelector, + }, + networkingv1.NetworkPolicyPeer{ + PodSelector: oldIngressNamespaceSelector, + }, + }, + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{}, + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldEgressPodSelector, + }, + }, + }, + }, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + }, + } + + newPolicy := oldPolicy + npPort6784 := networkingv1.NetworkPolicyPort{ + Protocol: &udp, + Port: &port6784, + } + newPolicy.Spec.Ingress[0].Ports = append(newPolicy.Spec.Ingress[0].Ports, npPort6784) + newPolicy.Spec.Ingress[0].From[0].PodSelector.MatchLabels["status"] = "ok" + newIngressNamespaceSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "new", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend-ns", + "backend-ns", + }, + }, + }, + } + newPolicy.Spec.Ingress[0].From[1].PodSelector = newIngressNamespaceSelector + + expectedIngress := append(oldPolicy.Spec.Ingress, newPolicy.Spec.Ingress...) + expectedEgress := append(oldPolicy.Spec.Egress, newPolicy.Spec.Egress...) + expectedPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + }, + Ingress: expectedIngress, + Egress: expectedEgress, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + }, + } + + addedPolicy, err := addPolicy(&oldPolicy, &newPolicy) + if err != nil || !reflect.DeepEqual(addedPolicy, expectedPolicy) { + t.Errorf("TestMergePolicy failed") + fmt.Println(addedPolicy) + fmt.Println(expectedPolicy) + } +} + +func TestDeductPolicy(t *testing.T { + tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP + port6783, port6784 := intstr.FromInt(6783), intstr.FromInt(6784) + oldIngressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "db", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + } + oldIngressNamespaceSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend-ns", + "backend-ns", + }, + }, + }, + } + oldEgressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "sql", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + } + oldPolicy := networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6783, + }, + }, + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldIngressPodSelector, + }, + networkingv1.NetworkPolicyPeer{ + PodSelector: oldIngressNamespaceSelector, + }, + }, + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{}, + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldEgressPodSelector, + }, + }, + }, + }, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + }, + } + + newPolicy := oldPolicy + newPolicy.Spec.Ingress[0].From = newPolicy.Spec.Ingress[0].From[0:1] + newPolicy.Spec.Egress[0].To[0] = networkingv1.NetworkPolicyPeer{ + PodSelector: metav1.LabelSelector{}, + } + + expectedPolicy := networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6783, + }, + }, + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldIngressNamespaceSelector, + }, + }, + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{}, + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldEgressPodSelector, + }, + }, + }, + }, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + }, + } + + deductedPolicy, err := deductPolicy(&oldPolicy, &newPolicy) + if err != nil || !reflect.DeepEqual(deductedPolicy, expectedPolicy) { + t.Errorf("TestMergePolicy failed") + fmt.Println(deductedPolicy) + fmt.Println(expectedPolicy) + } +}) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 04db8aea2a..d83ca57280 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -25,6 +25,17 @@ func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string keys []string vals []string ) + + if selector == nil { + return labels, keys, vals + } + + if len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0 { + labels = append(labels, util.KubeAllNamespacesFlag) + keys = append(keys, util.KubeAllNamespacesFlag) + vals = append(vals, "") + } + for k, v := range selector.MatchLabels { labels = append(labels, k+":"+v) keys = append(keys, k) diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index fddd3c05cd..df98151438 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -1,8 +1,10 @@ package npm import ( + "reflect" "testing" + "github.com/Azure/azure-container-networking/npm/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -51,7 +53,44 @@ func TestParseLabel(t *testing.T) { } func TestParseSelector(t *testing.T) { - selector := &metav1.LabelSelector{ + var selector, expectedSelector *metav1.LabelSelector + selector, expectedSelector = nil, nil + labels, keys, vals := ParseSelector(selector) + expectedLabels, expectedKeys, expectedVals := []string{}, []string{}, []string{} + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(expectedVals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + if selector != expectedSelector { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + selector = &metav1.LabelSelector{} + labels, keys, vals = ParseSelector(selector) + expectedLabels = []string{util.KubeAllNamespacesFlag} + expectedKeys = []string{util.KubeAllNamespacesFlag} + expectedVals = []string{""} + if len(labels) != len(expectedLabels) { + t.Errorf("TestparseSelector failed @ labels length comparison") + } + + if len(keys) != len(expectedKeys) { + t.Errorf("TestparseSelector failed @ keys length comparison") + } + + if len(vals) != len(expectedVals) { + t.Errorf("TestparseSelector failed @ vals length comparison") + } + + selector = &metav1.LabelSelector{ MatchExpressions: []metav1.LabelSelectorRequirement{ metav1.LabelSelectorRequirement{ Key: "testIn", @@ -64,16 +103,16 @@ func TestParseSelector(t *testing.T) { }, } - labels, keys, vals := ParseSelector(selector) - expectedLabels := []string{ + labels, keys, vals = ParseSelector(selector) + expectedLabels = []string{ "testIn:frontend", "testIn:backend", } - expectedKeys := []string{ + expectedKeys = []string{ "testIn", "testIn", } - expectedVals := []string{ + expectedVals = []string{ "frontend", "backend", } @@ -90,18 +129,14 @@ func TestParseSelector(t *testing.T) { t.Errorf("TestparseSelector failed @ vals length comparison") } - for i := range labels { - if labels[i] != expectedLabels[i] { - t.Errorf("TestparseSelector failed @ label comparison") - } - - if keys[i] != expectedKeys[i] { - t.Errorf("TestparseSelector failed @ key comparison") - } - - if vals[i] != expectedVals[i] { - t.Errorf("TestparseSelector failed @ value comparison") - } + if !reflect.DeepEqual(labels, expectedLabels) { + t.Errorf("TestparseSelector failed @ label comparison") + } + if !reflect.DeepEqual(keys, expectedKeys) { + t.Errorf("TestparseSelector failed @ key comparison") + } + if !reflect.DeepEqual(vals, expectedVals) { + t.Errorf("TestparseSelector failed @ value comparison") } notIn := metav1.LabelSelectorRequirement{ @@ -145,18 +180,14 @@ func TestParseSelector(t *testing.T) { t.Errorf("TestparseSelector failed @ vals length comparison") } - for i := range labels { - if labels[i] != expectedLabels[i] { - t.Errorf("TestparseSelector failed @ label comparison") - } - - if keys[i] != expectedKeys[i] { - t.Errorf("TestparseSelector failed @ key comparison") - } - - if vals[i] != expectedVals[i] { - t.Errorf("TestparseSelector failed @ value comparison") - } + if !reflect.DeepEqual(labels, expectedLabels) { + t.Errorf("TestparseSelector failed @ label comparison") + } + if !reflect.DeepEqual(keys, expectedKeys) { + t.Errorf("TestparseSelector failed @ key comparison") + } + if !reflect.DeepEqual(vals, expectedVals) { + t.Errorf("TestparseSelector failed @ value comparison") } exists := metav1.LabelSelectorRequirement{ @@ -193,18 +224,14 @@ func TestParseSelector(t *testing.T) { t.Errorf("TestparseSelector failed @ vals length comparison") } - for i := range labels { - if labels[i] != expectedLabels[i] { - t.Errorf("TestparseSelector failed @ label comparison") - } - - if keys[i] != expectedKeys[i] { - t.Errorf("TestparseSelector failed @ key comparison") - } - - if vals[i] != expectedVals[i] { - t.Errorf("TestparseSelector failed @ value comparison") - } + if !reflect.DeepEqual(labels, expectedLabels) { + t.Errorf("TestparseSelector failed @ label comparison") + } + if !reflect.DeepEqual(keys, expectedKeys) { + t.Errorf("TestparseSelector failed @ key comparison") + } + if !reflect.DeepEqual(vals, expectedVals) { + t.Errorf("TestparseSelector failed @ value comparison") } doesNotExist := metav1.LabelSelectorRequirement{ @@ -241,17 +268,15 @@ func TestParseSelector(t *testing.T) { t.Errorf("TestparseSelector failed @ vals length comparison") } - for i := range labels { - if labels[i] != expectedLabels[i] { - t.Errorf("TestparseSelector failed @ label comparison") - } + if !reflect.DeepEqual(labels, expectedLabels) { + t.Errorf("TestparseSelector failed @ label comparison") + } - if keys[i] != expectedKeys[i] { - t.Errorf("TestparseSelector failed @ key comparison") - } + if !reflect.DeepEqual(keys, expectedKeys) { + t.Errorf("TestparseSelector failed @ key comparison") + } - if vals[i] != expectedVals[i] { - t.Errorf("TestparseSelector failed @ value comparison") - } + if !reflect.DeepEqual(vals, expectedVals) { + t.Errorf("TestparseSelector failed @ value comparison") } } From 557c25fb58811579befa5b2ebb71e927cd3f58f0 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 10 Apr 2019 11:20:58 -0700 Subject: [PATCH 05/64] start deductPolicy --- npm/parsePolicy.go | 21 ++++++++++++++++++++- npm/parsePolicy_test.go | 6 +++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index b958d018fa..403c16916f 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -26,12 +26,13 @@ func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.N } // addPolicy merges policies based on labels. -func addPolicy(old *networkingv1.NetworkPolicy, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { +func addPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { // if namespace matches && podSelector matches, then merge // else return as is. if !reflect.DeepEqual(old.TypeMeta, new.TypeMeta) { return nil, fmt.Errorf("Old and new networkpolicy don't have the same TypeMeta") } + if old.ObjectMeta.Namespace != new.ObjectMeta.Namespace { return nil, fmt.Errorf("Old and new networkpolicy don't have the same namespace") } @@ -69,3 +70,21 @@ func addPolicy(old *networkingv1.NetworkPolicy, new *networkingv1.NetworkPolicy) return addedPolicy, nil } + +// deductPolicy deduct one policy from the other. +func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { + // if namespace matches && podSelector matches, then merge + // else return as is. + if !reflect.DeepEqual(old.TypeMeta, new.TypeMeta) { + return nil, fmt.Errorf("Old and new networkpolicy don't have the same TypeMeta") + } + + if old.ObjectMeta.Namespace != new.ObjectMeta.Namespace { + return nil, fmt.Errorf("Old and new networkpolicy don't have the same namespace") + } + + if len(old.Spec.PodSelector.MatchLabels) != 1 || !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { + return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") + } + +} diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go index b9d2311888..46384c4de3 100644 --- a/npm/parsePolicy_test.go +++ b/npm/parsePolicy_test.go @@ -275,7 +275,7 @@ func TestAddPolicy(t *testing.T) { } } -func TestDeductPolicy(t *testing.T { +func TestDeductPolicy(t *testing.T) { tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP port6783, port6784 := intstr.FromInt(6783), intstr.FromInt(6784) oldIngressPodSelector := &metav1.LabelSelector{ @@ -370,7 +370,7 @@ func TestDeductPolicy(t *testing.T { newPolicy := oldPolicy newPolicy.Spec.Ingress[0].From = newPolicy.Spec.Ingress[0].From[0:1] newPolicy.Spec.Egress[0].To[0] = networkingv1.NetworkPolicyPeer{ - PodSelector: metav1.LabelSelector{}, + PodSelector: &metav1.LabelSelector{}, } expectedPolicy := networkingv1.NetworkPolicy{ @@ -420,4 +420,4 @@ func TestDeductPolicy(t *testing.T { fmt.Println(deductedPolicy) fmt.Println(expectedPolicy) } -}) +} From 341b0ad4c0c43df24da8b612e3469c9a0f4b8257 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 23 Apr 2019 17:08:35 -0700 Subject: [PATCH 06/64] deduct network policy --- npm/namespace.go | 36 ++++++++++++++------- npm/nwpolicy.go | 40 +++++++++++++++++++++--- npm/parsePolicy.go | 69 +++++++++++++++++++++++++++++++++++++++++ npm/parsePolicy_test.go | 52 +++++++++++++++++++++---------- 4 files changed, 165 insertions(+), 32 deletions(-) diff --git a/npm/namespace.go b/npm/namespace.go index 9ce7548811..d9bb0aab5d 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -14,23 +14,25 @@ import ( ) type namespace struct { - name string - setMap map[string]string - podMap map[types.UID]*corev1.Pod - npMap map[string]*networkingv1.NetworkPolicy - ipsMgr *ipsm.IpsetManager - iptMgr *iptm.IptablesManager + name string + setMap map[string]string + podMap map[types.UID]*corev1.Pod + rawNpMap map[string]*networkingv1.NetworkPolicy + processedNpMap map[string]*networkingv1.NetworkPolicy + ipsMgr *ipsm.IpsetManager + iptMgr *iptm.IptablesManager } // newNS constructs a new namespace object. func newNs(name string) (*namespace, error) { ns := &namespace{ - name: name, - setMap: make(map[string]string), - podMap: make(map[types.UID]*corev1.Pod), - npMap: make(map[string]*networkingv1.NetworkPolicy), - ipsMgr: ipsm.NewIpsetManager(), - iptMgr: iptm.NewIptablesManager(), + name: name, + setMap: make(map[string]string), + podMap: make(map[types.UID]*corev1.Pod), + rawNpMap: make(map[string]*networkingv1.NetworkPolicy), + processedNpMap: make(map[string]*networkingv1.NetworkPolicy), + ipsMgr: ipsm.NewIpsetManager(), + iptMgr: iptm.NewIptablesManager(), } return ns, nil @@ -40,6 +42,16 @@ func isSystemNs(nsObj *corev1.Namespace) bool { return nsObj.ObjectMeta.Name == util.KubeSystemFlag } +func (ns *namespace) policyExists(npObj *networkingv1.NetworkPolicy) bool { + if np, exists := ns.rawNpMap[npObj.ObjectMeta.Name]; exists { + if isSamePolicy(np, npObj) { + return true + } + } + + return false +} + // InitAllNsList syncs all-namespace ipset list. func (npMgr *NetworkPolicyManager) InitAllNsList() error { allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index ec11d46411..63fc4c6344 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -8,6 +8,16 @@ import ( networkingv1 "k8s.io/api/networking/v1" ) +func (npMgr *NetworkPolicyManager) canCleanUpNpmChains() bool { + for _, ns := range npMgr.nsMap { + if len(ns.rawNpMap) > 0 { + return false + } + } + + return true +} + // AddNetworkPolicy handles adding network policy to iptables. func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkPolicy) error { npMgr.Lock() @@ -36,6 +46,10 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.nsMap[npNs] = ns } + if ns.policyExists(npObj) { + return nil + } + allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] if !npMgr.isAzureNpmChainCreated { @@ -60,7 +74,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ) for i := range newPolicies { label, newPolicy := labels[i], newPolicies[i] - if oldPolicy, exists := ns.npMap[label]; exists { + if oldPolicy, exists := ns.processedNpMap[label]; exists { addedPolicy, err = addPolicy(oldPolicy, newPolicy) oldPolicies = append(oldPolicies, oldPolicy) addedPolicies = append(addedPolicies, addedPolicy) @@ -109,6 +123,8 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP } + ns.rawNpMap[npName] = npObj + return nil } @@ -145,7 +161,10 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo npMgr.Lock() defer npMgr.Unlock() - var err error + var ( + err error + ns *namespace + ) defer func() { if err = npMgr.UpdateAndSendReport(err, util.DeleteNetworkPolicyEvent); err != nil { @@ -156,6 +175,19 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name log.Printf("NETWORK POLICY DELETING: %s/%s\n", npNs, npName) + var exists bool + if ns, exists = npMgr.nsMap[npNs]; !exists { + ns, err = newNs(npNs) + if err != nil { + log.Printf("Error creating namespace %s\n", npNs) + } + npMgr.nsMap[npNs] = ns + } + + if !ns.policyExists(npObj) { + return nil + } + allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] _, _, iptEntries := parsePolicy(npObj) @@ -168,9 +200,9 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo } } - delete(allNs.npMap, npName) + delete(ns.rawNpMap, npName) - if len(allNs.npMap) == 0 { + if npMgr.canCleanUpNpmChains() { if err = iptMgr.UninitNpmChains(); err != nil { log.Printf("Error uninitialize azure-npm chains.\n") return err diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 403c16916f..9a3877acdd 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -10,6 +10,22 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +func isSamePolicy(old, new *networkingv1.NetworkPolicy) bool { + if !reflect.DeepEqual(old.TypeMeta, new.TypeMeta) { + return false + } + + if old.ObjectMeta.Namespace != new.ObjectMeta.Namespace { + return false + } + + if !reflect.DeepEqual(old.Spec, new.Spec) { + return false + } + + return true +} + func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.NetworkPolicy) { var policies []*networkingv1.NetworkPolicy @@ -87,4 +103,57 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") } + deductedPolicy := &networkingv1.NetworkPolicy{ + TypeMeta: old.TypeMeta, + ObjectMeta: metav1.ObjectMeta{ + Name: old.ObjectMeta.Name, + Namespace: old.ObjectMeta.Namespace, + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: old.Spec.PodSelector, + }, + } + + deductedIngress, newIngress := old.Spec.Ingress, new.Spec.Ingress + deductedEgress, newEgress := old.Spec.Egress, new.Spec.Egress + for _, ni := range newIngress { + for i, di := range deductedIngress { + if reflect.DeepEqual(di, ni) { + deductedIngress = append(deductedIngress[:i], deductedIngress[i+1:]...) + break + } + } + } + + for _, ne := range newEgress { + for i, de := range deductedEgress { + if reflect.DeepEqual(de, ne) { + deductedEgress = append(deductedEgress[:i], deductedEgress[i+1:]...) + break + } + } + } + + fmt.Println("deduIn\n:", deductedIngress) + fmt.Println("deduE\n:", deductedEgress) + + if len(deductedIngress) == 0 && len(deductedEgress) == 0 { + return nil, nil + } + + deductedPolicy.Spec.Ingress = deductedIngress + deductedPolicy.Spec.Egress = deductedEgress + + if len(old.Spec.PolicyTypes) == 1 && old.Spec.PolicyTypes[0] == networkingv1.PolicyTypeEgress && + len(new.Spec.PolicyTypes) == 1 && new.Spec.PolicyTypes[0] == networkingv1.PolicyTypeEgress && + len(deductedIngress) == 0 { + deductedPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{networkingv1.PolicyTypeEgress} + } else { + deductedPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + } + } + + return deductedPolicy, nil } diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go index 46384c4de3..af2bf426d9 100644 --- a/npm/parsePolicy_test.go +++ b/npm/parsePolicy_test.go @@ -49,6 +49,9 @@ func TestSplitPolicy(t *testing.T) { expectedPolicies := []*networkingv1.NetworkPolicy{ &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "role:client", + }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -59,6 +62,9 @@ func TestSplitPolicy(t *testing.T) { }, }, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "protocol:https", + }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -69,6 +75,9 @@ func TestSplitPolicy(t *testing.T) { }, }, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testIn:frontend", + }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -79,6 +88,9 @@ func TestSplitPolicy(t *testing.T) { }, }, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "testIn:backend", + }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -89,6 +101,9 @@ func TestSplitPolicy(t *testing.T) { }, }, &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "!testDoesNotExist", + }, Spec: networkingv1.NetworkPolicySpec{ PodSelector: metav1.LabelSelector{ MatchLabels: map[string]string{ @@ -111,6 +126,8 @@ func TestSplitPolicy(t *testing.T) { for i := range labels { if !reflect.DeepEqual(labels, expectedLabels) { t.Errorf("TestsplitPolicy failed @ label comparison") + fmt.Println(labels) + fmt.Println(expectedLabels) } if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchLabels, expectedPolicies[i].Spec.PodSelector.MatchLabels) { @@ -269,15 +286,15 @@ func TestAddPolicy(t *testing.T) { addedPolicy, err := addPolicy(&oldPolicy, &newPolicy) if err != nil || !reflect.DeepEqual(addedPolicy, expectedPolicy) { - t.Errorf("TestMergePolicy failed") + t.Errorf("TestAddPolicy failed") fmt.Println(addedPolicy) fmt.Println(expectedPolicy) } } func TestDeductPolicy(t *testing.T) { - tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP - port6783, port6784 := intstr.FromInt(6783), intstr.FromInt(6784) + tcp := v1.ProtocolTCP + port6783 := intstr.FromInt(6783) oldIngressPodSelector := &metav1.LabelSelector{ MatchLabels: map[string]string{ "app": "db", @@ -367,13 +384,7 @@ func TestDeductPolicy(t *testing.T) { }, } - newPolicy := oldPolicy - newPolicy.Spec.Ingress[0].From = newPolicy.Spec.Ingress[0].From[0:1] - newPolicy.Spec.Egress[0].To[0] = networkingv1.NetworkPolicyPeer{ - PodSelector: &metav1.LabelSelector{}, - } - - expectedPolicy := networkingv1.NetworkPolicy{ + newPolicy := networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Namespace: "testnamespace", }, @@ -393,7 +404,7 @@ func TestDeductPolicy(t *testing.T) { }, From: []networkingv1.NetworkPolicyPeer{ networkingv1.NetworkPolicyPeer{ - PodSelector: oldIngressNamespaceSelector, + PodSelector: oldIngressPodSelector, }, }, }, @@ -403,7 +414,7 @@ func TestDeductPolicy(t *testing.T) { Ports: []networkingv1.NetworkPolicyPort{}, To: []networkingv1.NetworkPolicyPeer{ networkingv1.NetworkPolicyPeer{ - PodSelector: oldEgressPodSelector, + PodSelector: &metav1.LabelSelector{}, }, }, }, @@ -414,10 +425,19 @@ func TestDeductPolicy(t *testing.T) { }, } + expectedPolicy := oldPolicy + expectedPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + } deductedPolicy, err := deductPolicy(&oldPolicy, &newPolicy) - if err != nil || !reflect.DeepEqual(deductedPolicy, expectedPolicy) { - t.Errorf("TestMergePolicy failed") - fmt.Println(deductedPolicy) - fmt.Println(expectedPolicy) + if err != nil || !reflect.DeepEqual(deductedPolicy, &expectedPolicy) { + t.Errorf("TestDeductPolicy failed") + } + + newPolicy = oldPolicy + deductedPolicy, err = deductPolicy(&oldPolicy, &newPolicy) + if err != nil || deductedPolicy != nil { + t.Errorf("TestDeductPolicy failed @ identical policies") } } From 4db9122faafdd68be00df5e411761ce237893f83 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 23 Apr 2019 17:10:48 -0700 Subject: [PATCH 07/64] remvoe redundant print --- npm/parsePolicy.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 9a3877acdd..1118b1d48a 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -134,9 +134,6 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo } } - fmt.Println("deduIn\n:", deductedIngress) - fmt.Println("deduE\n:", deductedEgress) - if len(deductedIngress) == 0 && len(deductedEgress) == 0 { return nil, nil } From 217d1a75b12fcd34de419ed8ed3a165dbeef9f2f Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Mon, 29 Apr 2019 13:24:40 -0700 Subject: [PATCH 08/64] TestDeductPolicy --- npm/parsePolicy_test.go | 64 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 57 insertions(+), 7 deletions(-) diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go index af2bf426d9..8658a73d37 100644 --- a/npm/parsePolicy_test.go +++ b/npm/parsePolicy_test.go @@ -1,7 +1,6 @@ package npm import ( - "fmt" "reflect" "testing" @@ -126,8 +125,6 @@ func TestSplitPolicy(t *testing.T) { for i := range labels { if !reflect.DeepEqual(labels, expectedLabels) { t.Errorf("TestsplitPolicy failed @ label comparison") - fmt.Println(labels) - fmt.Println(expectedLabels) } if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchLabels, expectedPolicies[i].Spec.PodSelector.MatchLabels) { @@ -287,8 +284,6 @@ func TestAddPolicy(t *testing.T) { addedPolicy, err := addPolicy(&oldPolicy, &newPolicy) if err != nil || !reflect.DeepEqual(addedPolicy, expectedPolicy) { t.Errorf("TestAddPolicy failed") - fmt.Println(addedPolicy) - fmt.Println(expectedPolicy) } } @@ -432,12 +427,67 @@ func TestDeductPolicy(t *testing.T) { } deductedPolicy, err := deductPolicy(&oldPolicy, &newPolicy) if err != nil || !reflect.DeepEqual(deductedPolicy, &expectedPolicy) { - t.Errorf("TestDeductPolicy failed") + t.Errorf( + "TestDeductPolicy failed.\n"+ + "Expected Policy: %v\n"+ + "DeductedPolicy: %v\n", + &expectedPolicy, + deductedPolicy, + ) } newPolicy = oldPolicy deductedPolicy, err = deductPolicy(&oldPolicy, &newPolicy) if err != nil || deductedPolicy != nil { - t.Errorf("TestDeductPolicy failed @ identical policies") + t.Errorf( + "TestDeductPolicy failed.\n"+ + "Expected Policy: %v\n"+ + "DeductedPolicy: %v\n", + &expectedPolicy, + deductedPolicy, + ) + } + + newPolicy = networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "client", + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{}, + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: oldEgressPodSelector, + }, + }, + }, + }, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + }, + } + + expectedPolicy = oldPolicy + expectedPolicy.Spec.Egress = []networkingv1.NetworkPolicyEgressRule{} + expectedPolicy.Spec.PolicyTypes = []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + } + deductedPolicy, err = deductPolicy(&oldPolicy, &newPolicy) + if err != nil || !reflect.DeepEqual(deductedPolicy, &expectedPolicy) { + t.Errorf( + "TestDeductPolicy failed.\n"+ + "Expected Policy: %v\n"+ + "DeductedPolicy: %v\n", + &expectedPolicy, + deductedPolicy, + ) } } From 14b833877731915fe1453e880a1245d77a8c1f09 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 1 May 2019 14:34:46 -0700 Subject: [PATCH 09/64] translatePolicy --- npm/translatePolicy.go | 935 ++------------------------------- npm/translatePolicyOld.goa | 1003 ++++++++++++++++++++++++++++++++++++ 2 files changed, 1038 insertions(+), 900 deletions(-) create mode 100644 npm/translatePolicyOld.goa diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 977256c6a8..3f07352e39 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -3,9 +3,6 @@ package npm import ( - "fmt" - - "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" networkingv1 "k8s.io/api/networking/v1" @@ -16,871 +13,12 @@ type portsInfo struct { port string } -func appendAndClearSets(podNsRuleSets *[]string, nsRuleLists *[]string, policyRuleSets *[]string, policyRuleLists *[]string) { - *policyRuleSets = append(*policyRuleSets, *podNsRuleSets...) - *policyRuleLists = append(*policyRuleLists, *nsRuleLists...) - podNsRuleSets, nsRuleLists = nil, nil -} - -func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { - var ( - portRuleExists = false - fromRuleExists = false - isAppliedToNs = false - protPortPairSlice []*portsInfo - podNsRuleSets []string // pod sets listed in one ingress rules. - nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets - entries []*iptm.IptEntry - ) - - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - isAppliedToNs = true - } - - if isAppliedToNs { - hashedTargetSetName := util.GetHashedName(ns) - - nsDrop := &iptm.IptEntry{ - Name: ns, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, nsDrop) - } - - // Use hashed string for ipset name to avoid string length limit of ipset. - for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) - - hashedTargetSetName := util.GetHashedName(targetSet) - - if len(rules) == 0 { - drop := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, drop) - continue - } - - // allow kube-system - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - allowKubeSystemIngress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemIngress) - - for _, rule := range rules { - for _, portRule := range rule.Ports { - protPortPairSlice = append(protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: fmt.Sprint(portRule.Port.IntVal), - }) - - portRuleExists = true - } - - if rule.From != nil { - for _, fromRule := range rule.From { - if fromRule.PodSelector != nil { - fromRuleExists = true - } - if fromRule.NamespaceSelector != nil { - fromRuleExists = true - } - if fromRule.IPBlock != nil { - fromRuleExists = true - } - } - } - } - - for _, rule := range rules { - if !portRuleExists && !fromRuleExists { - allow := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allow) - continue - } - - if !portRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - }, - } - entries = append(entries, entry) - } else { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - }, - } - entries = append(entries, entry) - } - } - - if !fromRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - continue - } - - for _, fromRule := range rule.From { - // Handle IPBlock field of NetworkPolicyPeer - if fromRule.IPBlock != nil { - if len(fromRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesSFlag, - fromRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, cidrEntry) - } - - if len(fromRule.IPBlock.Except) > 0 { - for _, except := range fromRule.IPBlock.Except { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesSFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - } - } - - if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { - continue - } - - // Allow traffic from namespaceSelector - if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { - // allow traffic from all namespaces - if len(fromRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector - if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { - // allow traffic from the same namespace - if len(fromRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - nsEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromPodChain, - }, - } - entries = append(entries, nsEntry) - - podEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, podEntry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector intersects namespaceSelector - // This is only supported in kubernetes version >= 1.11 - if util.IsNewNwPolicyVerFlag { - // allow traffic from all namespaces - if len(fromRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromPodChain, - }, - } - entries = append(entries, entry) - } - - // allow traffic from the same namespace - if len(fromRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - entry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - } - } - } - } - - log.Printf("finished parsing ingress rule") - return policyRuleSets, policyRuleLists, entries -} - -func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { - var ( - portRuleExists = false - toRuleExists = false - isAppliedToNs = false - protPortPairSlice []*portsInfo - podNsRuleSets []string // pod sets listed in one ingress rules. - nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets - entries []*iptm.IptEntry - ) - - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - isAppliedToNs = true - } - - if isAppliedToNs { - hashedTargetSetName := util.GetHashedName(ns) - - nsDrop := &iptm.IptEntry{ - Name: ns, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, nsDrop) - } - - // Use hashed string for ipset name to avoid string length limit of ipset. - for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) - - hashedTargetSetName := util.GetHashedName(targetSet) - - if len(rules) == 0 { - drop := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, drop) - continue - } - - // allow kube-system - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - allowKubeSystemEgress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemEgress) - - for _, rule := range rules { - for _, portRule := range rule.Ports { - protPortPairSlice = append(protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: fmt.Sprint(portRule.Port.IntVal), - }) - - portRuleExists = true - } - - if rule.To != nil { - for _, toRule := range rule.To { - if toRule.PodSelector != nil { - toRuleExists = true - } - if toRule.NamespaceSelector != nil { - toRuleExists = true - } - if toRule.IPBlock != nil { - toRuleExists = true - } - } - } - } - - for _, rule := range rules { - if !portRuleExists && !toRuleExists { - allow := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allow) - continue - } - - if !portRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToNsChain, - }, - } - entries = append(entries, entry) - } else { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToNsChain, - }, - } - entries = append(entries, entry) - } - } - - if !toRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - continue - } - - for _, toRule := range rule.To { - // Handle IPBlock field of NetworkPolicyPeer - if toRule.IPBlock != nil { - if len(toRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesDFlag, - toRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, cidrEntry) - } - - if len(toRule.IPBlock.Except) > 0 { - for _, except := range toRule.IPBlock.Except { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesDFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - } - } - - if toRule.PodSelector == nil && toRule.NamespaceSelector == nil { - continue - } - - // Allow traffic from namespaceSelector - if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { - // allow traffic from all namespaces - if len(toRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector - if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { - // allow traffic from the same namespace - if len(toRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - nsEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToPodChain, - }, - } - entries = append(entries, nsEntry) - - podEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, podEntry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector intersects namespaceSelector - // This is only supported in kubernetes version >= 1.11 - if util.IsNewNwPolicyVerFlag { - log.Printf("Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") - // allow traffic from all namespaces - if len(toRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToPodChain, - }, - } - entries = append(entries, entry) - } - - // allow traffic from the same namespace - if len(toRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - entry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - } - } - } - } - - log.Printf("finished parsing ingress rule") - return policyRuleSets, policyRuleLists, entries +func translateIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { + return nil, nil, nil } -// Drop all non-whitelisted packets. -func getDefaultDropEntries(targetSets []string) []*iptm.IptEntry { - var entries []*iptm.IptEntry - - for _, targetSet := range targetSets { - hashedTargetSetName := util.GetHashedName(targetSet) - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - - entry = &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - - return entries +func translateIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { + return nil, nil, nil } // Allow traffic from/to kube-system pods @@ -940,64 +78,61 @@ func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry return entries } -// ParsePolicy parses network policy. -func parsePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []*iptm.IptEntry) { +// translatePolicy translates network policy object into a set of iptables rules. +// input: +// kubernetes network policy project +// output: +// 1. ipset set names generated from all podSelectors +// 2. ipset list names generated from all namespaceSelectors +// 3. iptables entries generated from the input network policy object. +func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []*iptm.IptEntry) { var ( - resultPodSets []string - resultNsLists []string - affectedSets []string - entries []*iptm.IptEntry + resultSets []string + resultLists []string + entries []*iptm.IptEntry ) - // Get affected pods. - npNs, selector := npObj.ObjectMeta.Namespace, npObj.Spec.PodSelector.MatchLabels - for podLabelKey, podLabelVal := range selector { - affectedSet := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - affectedSets = append(affectedSets, affectedSet) - } + // Get targeting pods. + targetSets, _, _ := ParseSelector(npObj.Spec.PodSelector) if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { - entries = append(entries, getAllowKubeSystemEntries(npNs, affectedSets)...) + entries = append(entries, getAllowKubeSystemEntries(npNs, targetSets)...) } if len(npObj.Spec.PolicyTypes) == 0 { - ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) - resultPodSets = append(resultPodSets, ingressPodSets...) - resultNsLists = append(resultNsLists, ingressNsSets...) + ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, targetSets, npObj.Spec.Ingress) + resultSets = append(resultSets, ingressPodSets...) + resultLists = append(resultLists, ingressNsSets...) entries = append(entries, ingressEntries...) - egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) - resultPodSets = append(resultPodSets, egressPodSets...) - resultNsLists = append(resultNsLists, egressNsSets...) + egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, targetSets, npObj.Spec.Egress) + resultSets = append(resultSets, egressPodSets...) + resultLists = append(resultLists, egressNsSets...) entries = append(entries, egressEntries...) - entries = append(entries, getDefaultDropEntries(affectedSets)...) + resultSets = append(resultSets, targetSets...) - resultPodSets = append(resultPodSets, affectedSets...) - - return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries + return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } for _, ptype := range npObj.Spec.PolicyTypes { if ptype == networkingv1.PolicyTypeIngress { - ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) - resultPodSets = append(resultPodSets, ingressPodSets...) - resultNsLists = append(resultNsLists, ingressNsSets...) + ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, targetSets, npObj.Spec.Ingress) + resultSets = append(resultSets, ingressPodSets...) + resultLists = append(resultLists, ingressNsSets...) entries = append(entries, ingressEntries...) } if ptype == networkingv1.PolicyTypeEgress { - egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) - resultPodSets = append(resultPodSets, egressPodSets...) - resultNsLists = append(resultNsLists, egressNsSets...) + egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, targetSets, npObj.Spec.Egress) + resultSets = append(resultSets, egressPodSets...) + resultLists = append(resultLists, egressNsSets...) entries = append(entries, egressEntries...) } - - entries = append(entries, getDefaultDropEntries(affectedSets)...) } - resultPodSets = append(resultPodSets, affectedSets...) - resultPodSets = append(resultPodSets, npNs) + resultSets = append(resultSets, targetSets...) + resultSets = append(resultSets, npNs) - return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries + return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } diff --git a/npm/translatePolicyOld.goa b/npm/translatePolicyOld.goa new file mode 100644 index 0000000000..977256c6a8 --- /dev/null +++ b/npm/translatePolicyOld.goa @@ -0,0 +1,1003 @@ +// Copyright 2018 Microsoft. All rights reserved. +// MIT License +package npm + +import ( + "fmt" + + "github.com/Azure/azure-container-networking/log" + "github.com/Azure/azure-container-networking/npm/iptm" + "github.com/Azure/azure-container-networking/npm/util" + networkingv1 "k8s.io/api/networking/v1" +) + +type portsInfo struct { + protocol string + port string +} + +func appendAndClearSets(podNsRuleSets *[]string, nsRuleLists *[]string, policyRuleSets *[]string, policyRuleLists *[]string) { + *policyRuleSets = append(*policyRuleSets, *podNsRuleSets...) + *policyRuleLists = append(*policyRuleLists, *nsRuleLists...) + podNsRuleSets, nsRuleLists = nil, nil +} + +func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { + var ( + portRuleExists = false + fromRuleExists = false + isAppliedToNs = false + protPortPairSlice []*portsInfo + podNsRuleSets []string // pod sets listed in one ingress rules. + nsRuleLists []string // namespace sets listed in one ingress rule + policyRuleSets []string // policy-wise pod sets + policyRuleLists []string // policy-wise namespace sets + entries []*iptm.IptEntry + ) + + if len(targetSets) == 0 { + targetSets = append(targetSets, ns) + isAppliedToNs = true + } + + if isAppliedToNs { + hashedTargetSetName := util.GetHashedName(ns) + + nsDrop := &iptm.IptEntry{ + Name: ns, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, nsDrop) + } + + // Use hashed string for ipset name to avoid string length limit of ipset. + for _, targetSet := range targetSets { + log.Printf("Parsing iptables for label %s", targetSet) + + hashedTargetSetName := util.GetHashedName(targetSet) + + if len(rules) == 0 { + drop := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, drop) + continue + } + + // allow kube-system + hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + allowKubeSystemIngress := &iptm.IptEntry{ + Name: util.KubeSystemFlag, + HashedName: hashedKubeSystemSet, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allowKubeSystemIngress) + + for _, rule := range rules { + for _, portRule := range rule.Ports { + protPortPairSlice = append(protPortPairSlice, + &portsInfo{ + protocol: string(*portRule.Protocol), + port: fmt.Sprint(portRule.Port.IntVal), + }) + + portRuleExists = true + } + + if rule.From != nil { + for _, fromRule := range rule.From { + if fromRule.PodSelector != nil { + fromRuleExists = true + } + if fromRule.NamespaceSelector != nil { + fromRuleExists = true + } + if fromRule.IPBlock != nil { + fromRuleExists = true + } + } + } + } + + for _, rule := range rules { + if !portRuleExists && !fromRuleExists { + allow := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allow) + continue + } + + if !portRuleExists { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + }, + } + entries = append(entries, entry) + } else { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + }, + } + entries = append(entries, entry) + } + } + + if !fromRuleExists { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + continue + } + + for _, fromRule := range rule.From { + // Handle IPBlock field of NetworkPolicyPeer + if fromRule.IPBlock != nil { + if len(fromRule.IPBlock.CIDR) > 0 { + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, cidrEntry) + } + + if len(fromRule.IPBlock.Except) > 0 { + for _, except := range fromRule.IPBlock.Except { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesSFlag, + except, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, entry) + } + } + } + + if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { + continue + } + + // Allow traffic from namespaceSelector + if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { + // allow traffic from all namespaces + if len(fromRule.NamespaceSelector.MatchLabels) == 0 { + nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) + } + + for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { + nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) + } + + for _, nsRuleSet := range nsRuleLists { + hashedNsRuleSetName := util.GetHashedName(nsRuleSet) + entry := &iptm.IptEntry{ + Name: nsRuleSet, + HashedName: hashedNsRuleSetName, + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedNsRuleSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + continue + } + + // Allow traffic from podSelector + if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { + // allow traffic from the same namespace + if len(fromRule.PodSelector.MatchLabels) == 0 { + podNsRuleSets = append(podNsRuleSets, ns) + } + + for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { + podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) + } + + // Handle PodSelector field of NetworkPolicyPeer. + for _, podRuleSet := range podNsRuleSets { + hashedPodRuleSetName := util.GetHashedName(podRuleSet) + nsEntry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromPodChain, + }, + } + entries = append(entries, nsEntry) + + podEntry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureIngressFromPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedPodRuleSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, podEntry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + continue + } + + // Allow traffic from podSelector intersects namespaceSelector + // This is only supported in kubernetes version >= 1.11 + if util.IsNewNwPolicyVerFlag { + // allow traffic from all namespaces + if len(fromRule.NamespaceSelector.MatchLabels) == 0 { + nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) + } + + for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { + nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) + } + + for _, nsRuleSet := range nsRuleLists { + hashedNsRuleSetName := util.GetHashedName(nsRuleSet) + entry := &iptm.IptEntry{ + Name: nsRuleSet, + HashedName: hashedNsRuleSetName, + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedNsRuleSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromPodChain, + }, + } + entries = append(entries, entry) + } + + // allow traffic from the same namespace + if len(fromRule.PodSelector.MatchLabels) == 0 { + podNsRuleSets = append(podNsRuleSets, ns) + } + + for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { + podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) + } + + // Handle PodSelector field of NetworkPolicyPeer. + for _, podRuleSet := range podNsRuleSets { + hashedPodRuleSetName := util.GetHashedName(podRuleSet) + entry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureIngressFromPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedPodRuleSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + } + } + } + } + + log.Printf("finished parsing ingress rule") + return policyRuleSets, policyRuleLists, entries +} + +func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { + var ( + portRuleExists = false + toRuleExists = false + isAppliedToNs = false + protPortPairSlice []*portsInfo + podNsRuleSets []string // pod sets listed in one ingress rules. + nsRuleLists []string // namespace sets listed in one ingress rule + policyRuleSets []string // policy-wise pod sets + policyRuleLists []string // policy-wise namespace sets + entries []*iptm.IptEntry + ) + + if len(targetSets) == 0 { + targetSets = append(targetSets, ns) + isAppliedToNs = true + } + + if isAppliedToNs { + hashedTargetSetName := util.GetHashedName(ns) + + nsDrop := &iptm.IptEntry{ + Name: ns, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, nsDrop) + } + + // Use hashed string for ipset name to avoid string length limit of ipset. + for _, targetSet := range targetSets { + log.Printf("Parsing iptables for label %s", targetSet) + + hashedTargetSetName := util.GetHashedName(targetSet) + + if len(rules) == 0 { + drop := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, drop) + continue + } + + // allow kube-system + hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + allowKubeSystemEgress := &iptm.IptEntry{ + Name: util.KubeSystemFlag, + HashedName: hashedKubeSystemSet, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allowKubeSystemEgress) + + for _, rule := range rules { + for _, portRule := range rule.Ports { + protPortPairSlice = append(protPortPairSlice, + &portsInfo{ + protocol: string(*portRule.Protocol), + port: fmt.Sprint(portRule.Port.IntVal), + }) + + portRuleExists = true + } + + if rule.To != nil { + for _, toRule := range rule.To { + if toRule.PodSelector != nil { + toRuleExists = true + } + if toRule.NamespaceSelector != nil { + toRuleExists = true + } + if toRule.IPBlock != nil { + toRuleExists = true + } + } + } + } + + for _, rule := range rules { + if !portRuleExists && !toRuleExists { + allow := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allow) + continue + } + + if !portRuleExists { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToNsChain, + }, + } + entries = append(entries, entry) + } else { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToNsChain, + }, + } + entries = append(entries, entry) + } + } + + if !toRuleExists { + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + continue + } + + for _, toRule := range rule.To { + // Handle IPBlock field of NetworkPolicyPeer + if toRule.IPBlock != nil { + if len(toRule.IPBlock.CIDR) > 0 { + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesDFlag, + toRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, cidrEntry) + } + + if len(toRule.IPBlock.Except) > 0 { + for _, except := range toRule.IPBlock.Except { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesDFlag, + except, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, entry) + } + } + } + + if toRule.PodSelector == nil && toRule.NamespaceSelector == nil { + continue + } + + // Allow traffic from namespaceSelector + if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { + // allow traffic from all namespaces + if len(toRule.NamespaceSelector.MatchLabels) == 0 { + nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) + } + + for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { + nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) + } + + for _, nsRuleSet := range nsRuleLists { + hashedNsRuleSetName := util.GetHashedName(nsRuleSet) + entry := &iptm.IptEntry{ + Name: nsRuleSet, + HashedName: hashedNsRuleSetName, + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedNsRuleSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + continue + } + + // Allow traffic from podSelector + if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { + // allow traffic from the same namespace + if len(toRule.PodSelector.MatchLabels) == 0 { + podNsRuleSets = append(podNsRuleSets, ns) + } + + for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { + podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) + } + + // Handle PodSelector field of NetworkPolicyPeer. + for _, podRuleSet := range podNsRuleSets { + hashedPodRuleSetName := util.GetHashedName(podRuleSet) + nsEntry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToPodChain, + }, + } + entries = append(entries, nsEntry) + + podEntry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureEgressToPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedPodRuleSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, podEntry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + continue + } + + // Allow traffic from podSelector intersects namespaceSelector + // This is only supported in kubernetes version >= 1.11 + if util.IsNewNwPolicyVerFlag { + log.Printf("Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") + // allow traffic from all namespaces + if len(toRule.NamespaceSelector.MatchLabels) == 0 { + nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) + } + + for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { + nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) + } + + for _, nsRuleSet := range nsRuleLists { + hashedNsRuleSetName := util.GetHashedName(nsRuleSet) + entry := &iptm.IptEntry{ + Name: nsRuleSet, + HashedName: hashedNsRuleSetName, + Chain: util.IptablesAzureEgressToNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedNsRuleSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToPodChain, + }, + } + entries = append(entries, entry) + } + + // allow traffic from the same namespace + if len(toRule.PodSelector.MatchLabels) == 0 { + podNsRuleSets = append(podNsRuleSets, ns) + } + + for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { + podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) + } + + // Handle PodSelector field of NetworkPolicyPeer. + for _, podRuleSet := range podNsRuleSets { + hashedPodRuleSetName := util.GetHashedName(podRuleSet) + entry := &iptm.IptEntry{ + Name: podRuleSet, + HashedName: hashedPodRuleSetName, + Chain: util.IptablesAzureEgressToPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedPodRuleSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, entry) + } + appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) + } + } + } + } + + log.Printf("finished parsing ingress rule") + return policyRuleSets, policyRuleLists, entries +} + +// Drop all non-whitelisted packets. +func getDefaultDropEntries(targetSets []string) []*iptm.IptEntry { + var entries []*iptm.IptEntry + + for _, targetSet := range targetSets { + hashedTargetSetName := util.GetHashedName(targetSet) + entry := &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, entry) + + entry = &iptm.IptEntry{ + Name: targetSet, + HashedName: hashedTargetSetName, + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, entry) + } + + return entries +} + +// Allow traffic from/to kube-system pods +func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry { + var entries []*iptm.IptEntry + + if len(targetSets) == 0 { + targetSets = append(targetSets, ns) + } + + for _, targetSet := range targetSets { + hashedTargetSetName := util.GetHashedName(targetSet) + hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + allowKubeSystemIngress := &iptm.IptEntry{ + Name: util.KubeSystemFlag, + HashedName: hashedKubeSystemSet, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allowKubeSystemIngress) + + allowKubeSystemEgress := &iptm.IptEntry{ + Name: util.KubeSystemFlag, + HashedName: hashedKubeSystemSet, + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allowKubeSystemEgress) + } + + return entries +} + +// ParsePolicy parses network policy. +func parsePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []*iptm.IptEntry) { + var ( + resultPodSets []string + resultNsLists []string + affectedSets []string + entries []*iptm.IptEntry + ) + + // Get affected pods. + npNs, selector := npObj.ObjectMeta.Namespace, npObj.Spec.PodSelector.MatchLabels + for podLabelKey, podLabelVal := range selector { + affectedSet := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal + affectedSets = append(affectedSets, affectedSet) + } + + if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { + entries = append(entries, getAllowKubeSystemEntries(npNs, affectedSets)...) + } + + if len(npObj.Spec.PolicyTypes) == 0 { + ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) + resultPodSets = append(resultPodSets, ingressPodSets...) + resultNsLists = append(resultNsLists, ingressNsSets...) + entries = append(entries, ingressEntries...) + + egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) + resultPodSets = append(resultPodSets, egressPodSets...) + resultNsLists = append(resultNsLists, egressNsSets...) + entries = append(entries, egressEntries...) + + entries = append(entries, getDefaultDropEntries(affectedSets)...) + + resultPodSets = append(resultPodSets, affectedSets...) + + return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries + } + + for _, ptype := range npObj.Spec.PolicyTypes { + if ptype == networkingv1.PolicyTypeIngress { + ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) + resultPodSets = append(resultPodSets, ingressPodSets...) + resultNsLists = append(resultNsLists, ingressNsSets...) + entries = append(entries, ingressEntries...) + } + + if ptype == networkingv1.PolicyTypeEgress { + egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) + resultPodSets = append(resultPodSets, egressPodSets...) + resultNsLists = append(resultNsLists, egressNsSets...) + entries = append(entries, egressEntries...) + } + + entries = append(entries, getDefaultDropEntries(affectedSets)...) + } + + resultPodSets = append(resultPodSets, affectedSets...) + resultPodSets = append(resultPodSets, npNs) + + return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries +} From 36301c467247dbe1b1eda48fb5cc859d7996ceab Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 1 May 2019 15:10:45 -0700 Subject: [PATCH 10/64] try build --- npm/nwpolicy.go | 4 ++-- npm/translatePolicy.go | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 63fc4c6344..3a36513382 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -91,7 +91,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP for _, addedPolicy = range addedPolicies { - podSets, nsLists, iptEntries := parsePolicy(npObj) + podSets, nsLists, iptEntries := translatePolicy(npObj) ipsMgr := allNs.ipsMgr for _, set := range podSets { @@ -190,7 +190,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] - _, _, iptEntries := parsePolicy(npObj) + _, _, iptEntries := translatePolicy(npObj) iptMgr := allNs.iptMgr for _, iptEntry := range iptEntries { diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 3f07352e39..548626691c 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -17,7 +17,7 @@ func translateIngress(ns string, targetSets []string, rules []networkingv1.Netwo return nil, nil, nil } -func translateIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { +func translateEgress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { return nil, nil, nil } @@ -93,8 +93,9 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* ) // Get targeting pods. - targetSets, _, _ := ParseSelector(npObj.Spec.PodSelector) + targetSets, _, _ := ParseSelector(&(npObj.Spec.PodSelector)) + npNs := npObj.ObjectMeta.Namespace if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { entries = append(entries, getAllowKubeSystemEntries(npNs, targetSets)...) } From 6b81fd672afd13e0d58bd7014f6d9e2b8e833188 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 1 May 2019 16:01:02 -0700 Subject: [PATCH 11/64] print policy --- npm/translatePolicy.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 548626691c..1a188608a7 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -3,6 +3,7 @@ package npm import ( + "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" networkingv1 "k8s.io/api/networking/v1" @@ -92,6 +93,7 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* entries []*iptm.IptEntry ) + log.Printf("Translating network policy:\n %+v", npObj) // Get targeting pods. targetSets, _, _ := ParseSelector(&(npObj.Spec.PodSelector)) From 6f5f82738bceaccbf08b75ef441814face66f795 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 1 May 2019 16:38:09 -0700 Subject: [PATCH 12/64] record newPolicy --- npm/nwpolicy.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 3a36513382..750f46071f 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -78,9 +78,10 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP addedPolicy, err = addPolicy(oldPolicy, newPolicy) oldPolicies = append(oldPolicies, oldPolicy) addedPolicies = append(addedPolicies, addedPolicy) - continue + } else { + ns.processedNpMap[label] = newPolicy + addedPolicies = append(addedPolicies, newPolicy) } - addedPolicies = append(addedPolicies, newPolicy) } npMgr.Unlock() From 1b4d2a1c8a80d2f291f56b52991bf828ce1b21ec Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 1 May 2019 17:16:59 -0700 Subject: [PATCH 13/64] pass in addedPolicy --- npm/nwpolicy.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 750f46071f..0cc91931b7 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -91,8 +91,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.Lock() for _, addedPolicy = range addedPolicies { - - podSets, nsLists, iptEntries := translatePolicy(npObj) + podSets, nsLists, iptEntries := translatePolicy(addedPolicy) ipsMgr := allNs.ipsMgr for _, set := range podSets { From 1051448b222519e9445bdbfba9f6d9357454e5e7 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 2 May 2019 11:53:14 -0700 Subject: [PATCH 14/64] translateIngress --- npm/nwpolicy.go | 6 +-- npm/translatePolicy.go | 89 +++++++++++++++++++++++++++++++----------- 2 files changed, 70 insertions(+), 25 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 0cc91931b7..29eef014b6 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -91,17 +91,17 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.Lock() for _, addedPolicy = range addedPolicies { - podSets, nsLists, iptEntries := translatePolicy(addedPolicy) + sets, lists, iptEntries := translatePolicy(addedPolicy) ipsMgr := allNs.ipsMgr - for _, set := range podSets { + for _, set := range sets { if err = ipsMgr.CreateSet(set); err != nil { log.Printf("Error creating ipset %s-%s\n", npNs, set) return err } } - for _, list := range nsLists { + for _, list := range lists { if err = ipsMgr.CreateList(list); err != nil { log.Printf("Error creating ipset list %s-%s\n", npNs, list) return err diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 1a188608a7..e7565cc34e 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -7,6 +7,7 @@ import ( "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) type portsInfo struct { @@ -14,25 +15,71 @@ type portsInfo struct { port string } -func translateIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { - return nil, nil, nil +func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { + var ( + portRuleExists = false + fromRuleExists = false + isAppliedToNs = false + protPortPairSlice []*portsInfo + podNsRuleSets []string // pod sets listed in one ingress rules. + nsRuleLists []string // namespace sets listed in one ingress rule + policyRuleSets []string // policy-wise pod sets + policyRuleLists []string // policy-wise namespace sets + entries []*iptm.IptEntry + ) + + labels, keys, vals := ParseSelector(&targetSelector) + for i := range labels { + label, key, val := labels[i], keys[i], vals[i] + log.Printf("Parsing iptables for label %s", label) + + hashedLabelName := util.GetHashedName(label) + + for _, rule := range rules { + // parse Ports field + for _, portRule := range rule.Ports { + protPortPairSlice = append(protPortPairSlice, + &portsInfo{ + protocol: string(*portRule.ProtoMessage), + port: protRule.Port.String(), + } + ) + portRuleExists = true + } + + if rule.From != nil { + for _, fromRule := range rule.From { + if fromRule.PodSelector != nil || + fromRule.NamespaceSelector != nil || + fromRule.IPBlock != nil { + fromRuleExists = true + } + } + } + + // TODO + if !portRuleExists && !fromRuleExists { + break + } + } + } + + log.Printf("finished parsing ingress rule") + return policyRuleSets, policyRuleLists, entries } -func translateEgress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { +func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { return nil, nil, nil } // Allow traffic from/to kube-system pods -func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry { +func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { var entries []*iptm.IptEntry - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - } - - for _, targetSet := range targetSets { - hashedTargetSetName := util.GetHashedName(targetSet) - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + labels, _, _ := ParseSelector(&targetSelector) + hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + for _, label := range labels { + hashedLabelName := util.GetHashedName(label) allowKubeSystemIngress := &iptm.IptEntry{ Name: util.KubeSystemFlag, HashedName: hashedKubeSystemSet, @@ -46,7 +93,7 @@ func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry util.IptablesMatchFlag, util.IptablesSetFlag, util.IptablesMatchSetFlag, - hashedTargetSetName, + hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, @@ -62,7 +109,7 @@ func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry util.IptablesMatchFlag, util.IptablesSetFlag, util.IptablesMatchSetFlag, - hashedTargetSetName, + hashedLabelName, util.IptablesSrcFlag, util.IptablesMatchFlag, util.IptablesSetFlag, @@ -94,47 +141,45 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* ) log.Printf("Translating network policy:\n %+v", npObj) - // Get targeting pods. - targetSets, _, _ := ParseSelector(&(npObj.Spec.PodSelector)) npNs := npObj.ObjectMeta.Namespace if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { - entries = append(entries, getAllowKubeSystemEntries(npNs, targetSets)...) + entries = append(entries, getAllowKubeSystemEntries(npNs, npObj.Spec.PodSelector)...) } if len(npObj.Spec.PolicyTypes) == 0 { - ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, targetSets, npObj.Spec.Ingress) + ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) resultSets = append(resultSets, ingressPodSets...) resultLists = append(resultLists, ingressNsSets...) entries = append(entries, ingressEntries...) - egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, targetSets, npObj.Spec.Egress) + egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) resultSets = append(resultSets, egressPodSets...) resultLists = append(resultLists, egressNsSets...) entries = append(entries, egressEntries...) - resultSets = append(resultSets, targetSets...) + resultSets = append(resultSets, npObj.Spec.PodSelector...) return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } for _, ptype := range npObj.Spec.PolicyTypes { if ptype == networkingv1.PolicyTypeIngress { - ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, targetSets, npObj.Spec.Ingress) + ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) resultSets = append(resultSets, ingressPodSets...) resultLists = append(resultLists, ingressNsSets...) entries = append(entries, ingressEntries...) } if ptype == networkingv1.PolicyTypeEgress { - egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, targetSets, npObj.Spec.Egress) + egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) resultSets = append(resultSets, egressPodSets...) resultLists = append(resultLists, egressNsSets...) entries = append(entries, egressEntries...) } } - resultSets = append(resultSets, targetSets...) + resultSets = append(resultSets, npObj.Spec.PodSelector...) resultSets = append(resultSets, npNs) return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries From bd509be43bbef2f4c84b911084c7b85552c03cbc Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 2 May 2019 11:56:38 -0700 Subject: [PATCH 15/64] comma --- npm/translatePolicy.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index e7565cc34e..b6214b1299 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -42,7 +42,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne &portsInfo{ protocol: string(*portRule.ProtoMessage), port: protRule.Port.String(), - } + }, ) portRuleExists = true } From 3d6d7da9044f0d573d18476574c6cc8fb8a72170 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 2 May 2019 11:59:37 -0700 Subject: [PATCH 16/64] fix build err --- npm/translatePolicy.go | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index b6214b1299..221c1e3f1f 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -32,7 +32,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne for i := range labels { label, key, val := labels[i], keys[i], vals[i] log.Printf("Parsing iptables for label %s", label) - + hashedLabelName := util.GetHashedName(label) for _, rule := range rules { @@ -40,8 +40,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne for _, portRule := range rule.Ports { protPortPairSlice = append(protPortPairSlice, &portsInfo{ - protocol: string(*portRule.ProtoMessage), - port: protRule.Port.String(), + protocol: string(*portRule.Protocol), + port: portRule.Port.String(), }, ) portRuleExists = true @@ -50,8 +50,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if rule.From != nil { for _, fromRule := range rule.From { if fromRule.PodSelector != nil || - fromRule.NamespaceSelector != nil || - fromRule.IPBlock != nil { + fromRule.NamespaceSelector != nil || + fromRule.IPBlock != nil { fromRuleExists = true } } @@ -62,7 +62,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne break } } - } + } log.Printf("finished parsing ingress rule") return policyRuleSets, policyRuleLists, entries @@ -158,8 +158,6 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* resultLists = append(resultLists, egressNsSets...) entries = append(entries, egressEntries...) - resultSets = append(resultSets, npObj.Spec.PodSelector...) - return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } @@ -179,7 +177,6 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* } } - resultSets = append(resultSets, npObj.Spec.PodSelector...) resultSets = append(resultSets, npNs) return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries From 4fed13194693f8beeddd36aa02b1b1a3ff24d70a Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 2 May 2019 12:02:03 -0700 Subject: [PATCH 17/64] fix build err --- npm/translatePolicy.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 221c1e3f1f..06d398e3bd 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -17,23 +17,23 @@ type portsInfo struct { func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( - portRuleExists = false - fromRuleExists = false - isAppliedToNs = false + portRuleExists = false + fromRuleExists = false + //isAppliedToNs = false protPortPairSlice []*portsInfo - podNsRuleSets []string // pod sets listed in one ingress rules. - nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets - entries []*iptm.IptEntry + //podNsRuleSets []string // pod sets listed in one ingress rules. + //nsRuleLists []string // namespace sets listed in one ingress rule + policyRuleSets []string // policy-wise pod sets + policyRuleLists []string // policy-wise namespace sets + entries []*iptm.IptEntry ) - labels, keys, vals := ParseSelector(&targetSelector) + labels, _, _ := ParseSelector(&targetSelector) for i := range labels { - label, key, val := labels[i], keys[i], vals[i] + label := labels[i] log.Printf("Parsing iptables for label %s", label) - hashedLabelName := util.GetHashedName(label) + //hashedLabelName := util.GetHashedName(label) for _, rule := range rules { // parse Ports field From ae390d6dc9eef2cbfe38130589e5f29619fc4f4a Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 2 May 2019 13:54:47 -0700 Subject: [PATCH 18/64] remove --- npm/translatePolicy.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 06d398e3bd..544dce7371 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -17,9 +17,8 @@ type portsInfo struct { func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( - portRuleExists = false - fromRuleExists = false - //isAppliedToNs = false + portRuleExists = false + fromRuleExists = false protPortPairSlice []*portsInfo //podNsRuleSets []string // pod sets listed in one ingress rules. //nsRuleLists []string // namespace sets listed in one ingress rule From 44c4f4c2f83d55f822a472811c07b25c77f47405 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 12 Jun 2019 11:08:57 -0700 Subject: [PATCH 19/64] change telemetry to message queue and add npm --- Makefile | 39 +++- cni/telemetry/Dockerfile | 13 ++ cni/telemetry/service/telemetrymain.go | 14 +- log/logger.go | 45 +++- log/logger_test.go | 2 +- log/stdapi.go | 6 + npm/Dockerfile | 3 +- npm/azure-npm.yaml | 19 +- npm/ipsm/ipsm.go | 56 +++-- npm/iptm/iptm.go | 63 ++--- npm/namespace.go | 58 ++--- npm/namespace_test.go | 6 +- npm/npm.go | 146 ++++++------ npm/nwpolicy.go | 47 ++-- npm/nwpolicy_test.go | 6 +- npm/parse.go | 10 +- npm/plugin/main.go | 19 +- npm/pod.go | 51 ++--- npm/pod_test.go | 6 +- npm/util/const.go | 15 +- telemetry/cnstelemetry.go | 6 +- telemetry/telemetry.go | 7 +- telemetry/telemetry_test.go | 24 +- telemetry/telemetrybuffer.go | 306 ++++++++++++++++--------- 24 files changed, 534 insertions(+), 433 deletions(-) create mode 100644 cni/telemetry/Dockerfile diff --git a/Makefile b/Makefile index 42a8056279..297cee0fc9 100644 --- a/Makefile +++ b/Makefile @@ -62,6 +62,7 @@ CNM_DIR = cnm/plugin CNI_NET_DIR = cni/network/plugin CNI_IPAM_DIR = cni/ipam/plugin CNI_TELEMETRY_DIR = cni/telemetry/service +TELEMETRY_CONF_DIR = telemetry CNS_DIR = cns/service NPM_DIR = npm/plugin OUTPUT_DIR = output @@ -71,6 +72,7 @@ CNI_BUILD_DIR = $(BUILD_DIR)/cni CNI_MULTITENANCY_BUILD_DIR = $(BUILD_DIR)/cni-multitenancy CNS_BUILD_DIR = $(BUILD_DIR)/cns NPM_BUILD_DIR = $(BUILD_DIR)/npm +NPM_TELEMETRY_DIR = $(NPM_BUILD_DIR)/telemetry # Containerized build parameters. BUILD_CONTAINER_IMAGE = acn-build @@ -97,6 +99,7 @@ CNI_MULTITENANCY_ARCHIVE_NAME = azure-vnet-cni-multitenancy-$(GOOS)-$(GOARCH)-$( CNS_ARCHIVE_NAME = azure-cns-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT) NPM_ARCHIVE_NAME = azure-npm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT) NPM_IMAGE_ARCHIVE_NAME = azure-npm-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT) +TELEMETRY_IMAGE_ARCHIVE_NAME = azure-vnet-telemetry-$(GOOS)-$(GOARCH)-$(VERSION).$(ARCHIVE_EXT) # Docker libnetwork (CNM) plugin v2 image parameters. CNM_PLUGIN_IMAGE ?= microsoft/azure-vnet-plugin @@ -105,8 +108,10 @@ CNM_PLUGIN_ROOTFS = azure-vnet-plugin-rootfs # Azure network policy manager parameters. AZURE_NPM_IMAGE = containernetworking/azure-npm +# Azure vnet telemetry image parameters. +AZURE_VNET_TELEMETRY_IMAGE = containernetworking/azure-vnet-telemetry + VERSION ?= $(shell git describe --tags --always --dirty) -AZURE_NPM_VERSION = $(VERSION) ENSURE_OUTPUT_DIR_EXISTS := $(shell mkdir -p $(OUTPUT_DIR)) @@ -130,7 +135,7 @@ all-binaries: azure-cnm-plugin azure-cni-plugin azure-cns endif ifeq ($(GOOS),linux) -all-images: azure-npm-image +all-images: azure-npm-image azure-vnet-telemetry-image else all-images: @echo "Nothing to build. Skip." @@ -153,7 +158,7 @@ $(CNI_BUILD_DIR)/azure-vnet$(EXE_EXT): $(CNIFILES) $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT): $(CNIFILES) go build -v -o $(CNI_BUILD_DIR)/azure-vnet-ipam$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -s -w" $(CNI_IPAM_DIR)/*.go -# Build the Azure CNI IPAM plugin. +# Build the Azure CNI telemetry plugin. $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT): $(CNIFILES) go build -v -o $(CNI_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -s -w" $(CNI_TELEMETRY_DIR)/*.go @@ -163,6 +168,7 @@ $(CNS_BUILD_DIR)/azure-cns$(EXE_EXT): $(CNSFILES) # Build the Azure NPM plugin. $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT): $(NPMFILES) + go build -v -o $(NPM_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -s -w" $(CNI_TELEMETRY_DIR)/*.go go build -v -o $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT) -ldflags "-X main.version=$(VERSION) -s -w" $(NPM_DIR)/*.go # Build all binaries in a container. @@ -229,16 +235,32 @@ azure-npm-image: azure-npm ifeq ($(GOOS),linux) docker build \ -f npm/Dockerfile \ - -t $(AZURE_NPM_IMAGE):$(AZURE_NPM_VERSION) \ + -t $(AZURE_NPM_IMAGE):$(VERSION) \ --build-arg NPM_BUILD_DIR=$(NPM_BUILD_DIR) \ . - docker save $(AZURE_NPM_IMAGE):$(AZURE_NPM_VERSION) | gzip -c > $(NPM_BUILD_DIR)/$(NPM_ARCHIVE_NAME) + docker save $(AZURE_NPM_IMAGE):$(VERSION) | gzip -c > $(NPM_BUILD_DIR)/$(NPM_IMAGE_ARCHIVE_NAME) endif # Publish the Azure NPM image to a Docker registry .PHONY: publish-azure-npm-image publish-azure-npm-image: - docker push $(AZURE_NPM_IMAGE):$(AZURE_NPM_VERSION) + docker push $(AZURE_NPM_IMAGE):$(VERSION) + +# Build the Azure vnet telemetry image +.PHONY: azure-vnet-telemetry-image +azure-vnet-telemetry-image: azure-vnet-telemetry + docker build \ + -f cni/telemetry/Dockerfile \ + -t $(AZURE_VNET_TELEMETRY_IMAGE):$(VERSION) \ + --build-arg TELEMETRY_BUILD_DIR=$(NPM_BUILD_DIR) \ + --build-arg TELEMETRY_CONF_DIR=$(TELEMETRY_CONF_DIR) \ + . + docker save $(AZURE_VNET_TELEMETRY_IMAGE):$(VERSION) | gzip -c > $(NPM_BUILD_DIR)/$(TELEMETRY_IMAGE_ARCHIVE_NAME) + +# Publish the Azure vnet telemetry image to a Docker registry +.PHONY: publish-azure-vnet-telemetry-image +publish-azure-vnet-telemetry-image: + docker push $(AZURE_VNET_TELEMETRY_IMAGE):$(VERSION) # Create a CNI archive for the target platform. .PHONY: cni-archive @@ -274,7 +296,8 @@ cns-archive: .PHONY: npm-archive npm-archive: ifeq ($(GOOS),linux) - chmod 0755 $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT) - cd $(NPM_BUILD_DIR) && $(ARCHIVE_CMD) $(NPM_ARCHIVE_NAME) azure-npm$(EXE_EXT) + chmod 0755 $(NPM_BUILD_DIR)/azure-npm$(EXE_EXT) $(NPM_BUILD_DIR)/azure-vnet-telemetry$(EXE_EXT) + cp telemetry/azure-vnet-telemetry.config $(NPM_BUILD_DIR)/azure-vnet-telemetry.config + cd $(NPM_BUILD_DIR) && $(ARCHIVE_CMD) $(NPM_ARCHIVE_NAME) azure-npm$(EXE_EXT) azure-vnet-telemetry$(EXE_EXT) azure-vnet-telemetry.config chown $(BUILD_USER):$(BUILD_USER) $(NPM_BUILD_DIR)/$(NPM_ARCHIVE_NAME) endif \ No newline at end of file diff --git a/cni/telemetry/Dockerfile b/cni/telemetry/Dockerfile new file mode 100644 index 0000000000..8d16370e04 --- /dev/null +++ b/cni/telemetry/Dockerfile @@ -0,0 +1,13 @@ +# Use a minimal image as a parent image +FROM ubuntu:18.04 +ARG TELEMETRY_BUILD_DIR +ARG TELEMETRY_CONF_DIR + +# Install plugin +COPY $TELEMETRY_BUILD_DIR/azure-vnet-telemetry /usr/bin +COPY $TELEMETRY_CONF_DIR/azure-vnet-telemetry.config /usr/bin + +WORKDIR /usr/bin + +# Run below command by default when the container starts. +ENTRYPOINT ["/usr/bin/azure-vnet-telemetry", "-d", "/usr/bin"] \ No newline at end of file diff --git a/cni/telemetry/service/telemetrymain.go b/cni/telemetry/service/telemetrymain.go index 5a63b0202e..7d93bf12ad 100644 --- a/cni/telemetry/service/telemetrymain.go +++ b/cni/telemetry/service/telemetrymain.go @@ -106,7 +106,7 @@ func main() { return } - log.Printf("args %+v", os.Args) + log.Logf("args %+v", os.Args) if runtime.GOOS == "linux" { configPath = fmt.Sprintf("%s/%s%s", configDirectory, azureVnetTelemetry, configExtension) @@ -114,25 +114,25 @@ func main() { configPath = fmt.Sprintf("%s\\%s%s", configDirectory, azureVnetTelemetry, configExtension) } - log.Printf("[Telemetry] Config path: %s", configPath) + log.Logf("[Telemetry] Config path: %s", configPath) config, err = telemetry.ReadConfigFile(configPath) if err != nil { - log.Printf("[Telemetry] Error reading telemetry config: %v", err) + log.Logf("[Telemetry] Error reading telemetry config: %v", err) } - log.Printf("read config returned %+v", config) + log.Logf("read config returned %+v", config) for { tb = telemetry.NewTelemetryBuffer("") - log.Printf("[Telemetry] Starting telemetry server") + log.Logf("[Telemetry] Starting telemetry server") err = tb.StartServer() if err == nil || tb.FdExists { break } - log.Printf("[Telemetry] Telemetry service starting failed: %v", err) + log.Logf("[Telemetry] Telemetry service starting failed: %v", err) tb.Cleanup(telemetry.FdName) time.Sleep(time.Millisecond * 200) } @@ -141,7 +141,7 @@ func main() { config.ReportToHostIntervalInSeconds = reportToHostIntervalInSeconds } - log.Printf("[Telemetry] Report to host for an interval of %d seconds", config.ReportToHostIntervalInSeconds) + log.Logf("[Telemetry] Report to host for an interval of %d seconds", config.ReportToHostIntervalInSeconds) tb.BufferAndPushData(config.ReportToHostIntervalInSeconds * time.Second) log.Close() } diff --git a/log/logger.go b/log/logger.go index e4bcd954bc..4f35b52a6a 100644 --- a/log/logger.go +++ b/log/logger.go @@ -138,7 +138,7 @@ func (logger *Logger) rotate() { fileName := logger.getLogFileName() fileInfo, err := os.Stat(fileName) if err != nil { - logger.Printf("[log] Failed to query log file info %+v.", err) + logger.Logf("[log] Failed to query log file info %+v.", err) return } @@ -185,7 +185,7 @@ func (logger *Logger) Response(tag string, response interface{}, returnCode int, } } -// Logf logs a formatted string. +// logf logs a formatted string. func (logger *Logger) logf(format string, args ...interface{}) { if logger.callCount%rotationCheckFrq == 0 { logger.rotate() @@ -195,27 +195,48 @@ func (logger *Logger) logf(format string, args ...interface{}) { logger.l.Printf(format, args...) } +// Logf wraps logf. +func (logger *Logger) Logf(format string, args ...interface{}) { + logger.mutex.Lock() + logger.logf(format, args...) + logger.mutex.Unlock() +} + // Printf logs a formatted string at info level. func (logger *Logger) Printf(format string, args ...interface{}) { - if logger.level >= LevelInfo { - logger.mutex.Lock() - logger.logf(format, args...) - logger.mutex.Unlock() + if logger.level < LevelInfo { + return } + + logger.mutex.Lock() + logger.logf(format, args...) + logger.mutex.Unlock() + go func() { + if logger.reports != nil { + logger.reports <- fmt.Sprintf(format, args...) + } + }() } -// Debugf logs a formatted string at debug level. +// Debugf logs a formatted string at info level. func (logger *Logger) Debugf(format string, args ...interface{}) { - if logger.level >= LevelDebug { - logger.mutex.Lock() - logger.logf(format, args...) - logger.mutex.Unlock() + if logger.level < LevelDebug { + return } + + logger.mutex.Lock() + logger.logf(format, args...) + logger.mutex.Unlock() + go func() { + if logger.reports != nil { + logger.reports <- fmt.Sprintf(format, args...) + } + }() } // Errorf logs a formatted string at info level and sends the string to TelemetryBuffer. func (logger *Logger) Errorf(format string, args ...interface{}) { - logger.Printf(format, args...) + logger.Logf(format, args...) go func() { if logger.reports != nil { logger.reports <- fmt.Sprintf(format, args...) diff --git a/log/logger_test.go b/log/logger_test.go index 10128ca91a..03f8c33e6c 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -22,7 +22,7 @@ func TestLogFileRotatesWhenSizeLimitIsReached(t *testing.T) { l.SetLogFileLimits(512, 2) for i := 1; i <= 100; i++ { - l.Printf("LogText %v", i) + l.Logf("LogText %v", i) } l.Close() diff --git a/log/stdapi.go b/log/stdapi.go index 21a3a5fcf4..cac9922ba7 100644 --- a/log/stdapi.go +++ b/log/stdapi.go @@ -47,6 +47,12 @@ func Response(tag string, response interface{}, returnCode int, returnStr string stdLog.Response(tag, response, returnCode, returnStr, err) } +// Logf logs to the local log. +func Logf(format string, args ...interface{}) { + stdLog.Logf(format, args...) +} + +// Printf logs to the local log and send the log through the channel. func Printf(format string, args ...interface{}) { stdLog.Printf(format, args...) } diff --git a/npm/Dockerfile b/npm/Dockerfile index b04bb47da5..f241acd93e 100644 --- a/npm/Dockerfile +++ b/npm/Dockerfile @@ -1,5 +1,5 @@ # Use a minimal image as a parent image -FROM ubuntu:16.04 +FROM ubuntu:18.04 ARG NPM_BUILD_DIR # Install dependencies. @@ -9,6 +9,7 @@ RUN apt-get install -y ipset # Install plugin. COPY $NPM_BUILD_DIR/azure-npm /usr/bin + WORKDIR /usr/bin # Run the npm command by default when the container starts. diff --git a/npm/azure-npm.yaml b/npm/azure-npm.yaml index d0825ba165..725a070127 100644 --- a/npm/azure-npm.yaml +++ b/npm/azure-npm.yaml @@ -76,7 +76,7 @@ spec: beta.kubernetes.io/os: linux containers: - name: azure-npm - image: containernetworking/azure-npm:v1.0.18 + image: containernetworking/azure-npm:v1.0.23 securityContext: privileged: true env: @@ -90,6 +90,17 @@ spec: mountPath: /run/xtables.lock - name: log mountPath: /var/log + - name: socket-dir + mountPath: /var/run + - name: tmp + mountPath: /tmp + - name: azure-vnet-telemetry + image: containernetworking/azure-vnet-telemetry:v1.0.23 + volumeMounts: + - name: socket-dir + mountPath: /var/run + - name: tmp + mountPath: /tmp hostNetwork: true volumes: - name: log @@ -100,4 +111,10 @@ spec: hostPath: path: /run/xtables.lock type: File + - name: tmp + hostPath: + path: /tmp + type: Directory + - name: socket-dir + emptyDir: {} serviceAccountName: azure-npm \ No newline at end of file diff --git a/npm/ipsm/ipsm.go b/npm/ipsm/ipsm.go index d33079c708..2637b06bea 100644 --- a/npm/ipsm/ipsm.go +++ b/npm/ipsm/ipsm.go @@ -83,9 +83,9 @@ func (ipsMgr *IpsetManager) CreateList(listName string) error { set: util.GetHashedName(listName), spec: util.IpsetSetListFlag, } - log.Printf("Creating List: %+v\n", entry) + log.Printf("[Azure-NPM] Creating List: %+v", entry) if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error creating ipset list %s.\n", listName) + log.Errorf("[Azure-NPM] Error: failed to create ipset list %s.", listName) return err } @@ -104,12 +104,11 @@ func (ipsMgr *IpsetManager) DeleteList(listName string) error { errCode, err := ipsMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("Cannot delete list %s as it's being referred or doesn't exist.\n", listName) + log.Printf("[Azure-NPM] Error: Cannot delete list %s as it's being referred or doesn't exist.", listName) return nil } - log.Printf("Error deleting ipset %s", listName) - log.Printf("%+v\n", entry) + log.Errorf("[Azure-NPM] Error: failed to delete ipset %s %+v", listName, entry) return err } @@ -135,7 +134,7 @@ func (ipsMgr *IpsetManager) AddToList(listName string, setName string) error { } if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error creating ipset rules. rule: %+v", entry) + log.Errorf("[Azure-NPM] Error: failed to create ipset rules. rule: %+v", entry) return err } @@ -147,7 +146,7 @@ func (ipsMgr *IpsetManager) AddToList(listName string, setName string) error { // DeleteFromList removes an ipset to an ipset list. func (ipsMgr *IpsetManager) DeleteFromList(listName string, setName string) error { if _, exists := ipsMgr.listMap[listName]; !exists { - log.Printf("ipset list with name %s not found", listName) + log.Printf("[Azure-NPM] ipset list with name %s not found", listName) return nil } @@ -165,14 +164,13 @@ func (ipsMgr *IpsetManager) DeleteFromList(listName string, setName string) erro } errCode, err := ipsMgr.Run(entry) if errCode > 1 && err != nil { - log.Printf("Error deleting ipset entry.\n") - log.Printf("%+v\n", entry) + log.Errorf("[Azure-NPM] Error: failed to delete ipset entry. %+v", entry) return err } if len(ipsMgr.listMap[listName].elements) == 0 { if err := ipsMgr.DeleteList(listName); err != nil { - log.Printf("Error deleting ipset list %s.\n", listName) + log.Errorf("[Azure-NPM] Error: failed to delete ipset list %s.", listName) return err } } @@ -193,9 +191,9 @@ func (ipsMgr *IpsetManager) CreateSet(setName string) error { set: util.GetHashedName(setName), spec: util.IpsetNetHashFlag, } - log.Printf("Creating Set: %+v\n", entry) + log.Printf("[Azure-NPM] Creating Set: %+v", entry) if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error creating ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to create ipset.") return err } @@ -207,7 +205,7 @@ func (ipsMgr *IpsetManager) CreateSet(setName string) error { // DeleteSet removes a set from ipset. func (ipsMgr *IpsetManager) DeleteSet(setName string) error { if _, exists := ipsMgr.setMap[setName]; !exists { - log.Printf("ipset with name %s not found", setName) + log.Printf("[Azure-NPM] ipset with name %s not found", setName) return nil } @@ -222,11 +220,11 @@ func (ipsMgr *IpsetManager) DeleteSet(setName string) error { errCode, err := ipsMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("Cannot delete set %s as it's being referred.\n", setName) + log.Printf("[Azure-NPM] Cannot delete set %s as it's being referred.", setName) return nil } - log.Printf("Error deleting ipset %s\n. Entry: %+v", setName, entry) + log.Errorf("[Azure-NPM] Error: failed to delete ipset %s. Entry: %+v", setName, entry) return err } @@ -252,8 +250,7 @@ func (ipsMgr *IpsetManager) AddToSet(setName string, ip string) error { } if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error creating ipset rules.\n") - log.Printf("rule: %+v\n", entry) + log.Printf("[Azure-NPM] Error: failed to create ipset rules. %+v", entry) return err } @@ -265,7 +262,7 @@ func (ipsMgr *IpsetManager) AddToSet(setName string, ip string) error { // DeleteFromSet removes an ip from an entry in setMap, and delete/update the corresponding ipset. func (ipsMgr *IpsetManager) DeleteFromSet(setName string, ip string) error { if _, exists := ipsMgr.setMap[setName]; !exists { - log.Printf("ipset with name %s not found", setName) + log.Printf("[Azure-NPM] ipset with name %s not found", setName) return nil } @@ -281,7 +278,7 @@ func (ipsMgr *IpsetManager) DeleteFromSet(setName string, ip string) error { spec: ip, } if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error deleting ipset entry.\n Entry: %+v", entry) + log.Errorf("[Azure-NPM] Error: failed to delete ipset entry. Entry: %+v", entry) return err } @@ -296,7 +293,7 @@ func (ipsMgr *IpsetManager) Clean() error { } if err := ipsMgr.DeleteSet(setName); err != nil { - log.Printf("Error cleaning ipset\n") + log.Errorf("[Azure-NPM] Error: failed to clean ipset") return err } } @@ -307,7 +304,7 @@ func (ipsMgr *IpsetManager) Clean() error { } if err := ipsMgr.DeleteList(listName); err != nil { - log.Printf("Error cleaning ipset list\n") + log.Errorf("[Azure-NPM] Error: failed to clean ipset list") return err } } @@ -321,13 +318,13 @@ func (ipsMgr *IpsetManager) Destroy() error { operationFlag: util.IpsetFlushFlag, } if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error flushing ipset\n") + log.Errorf("[Azure-NPM] Error: failed to flush ipset") return err } entry.operationFlag = util.IpsetDestroyFlag if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("Error destroying ipset\n") + log.Errorf("[Azure-NPM] Error: failed to destroy ipset") return err } @@ -345,13 +342,12 @@ func (ipsMgr *IpsetManager) Run(entry *ipsEntry) (int, error) { cmdArgs = append(cmdArgs, entry.spec) } - cmdOut, err := exec.Command(cmdName, cmdArgs...).Output() - log.Printf("%s\n", string(cmdOut)) - + log.Printf("[Azure-NPM] Executing ipset command %s %v", cmdName, cmdArgs) + _, err := exec.Command(cmdName, cmdArgs...).Output() if msg, failed := err.(*exec.ExitError); failed { errCode := msg.Sys().(syscall.WaitStatus).ExitStatus() if errCode > 1 { - log.Printf("There was an error running command: %s\nArguments:%+v", err, cmdArgs) + log.Errorf("[Azure-NPM] Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) } return errCode, err @@ -368,7 +364,7 @@ func (ipsMgr *IpsetManager) Save(configFile string) error { cmd := exec.Command(util.Ipset, util.IpsetSaveFlag, util.IpsetFileFlag, configFile) if err := cmd.Start(); err != nil { - log.Printf("Error saving ipset to file.\n") + log.Errorf("[Azure-NPM] Error: failed to save ipset to file.") return err } cmd.Wait() @@ -384,7 +380,7 @@ func (ipsMgr *IpsetManager) Restore(configFile string) error { f, err := os.Stat(configFile) if err != nil { - log.Printf("Error getting file %s stat from ipsm.Restore", configFile) + log.Errorf("[Azure-NPM] Error: failed to get file %s stat from ipsm.Restore", configFile) return err } @@ -396,7 +392,7 @@ func (ipsMgr *IpsetManager) Restore(configFile string) error { cmd := exec.Command(util.Ipset, util.IpsetRestoreFlag, util.IpsetFileFlag, configFile) if err := cmd.Start(); err != nil { - log.Printf("Error restoring ipset from file.\n") + log.Errorf("[Azure-NPM] Error: failed to restore ipset from file.") return err } cmd.Wait() diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 3acfe5dbb2..5b254fba51 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -50,7 +50,7 @@ func NewIptablesManager() *IptablesManager { // InitNpmChains initializes Azure NPM chains in iptables. func (iptMgr *IptablesManager) InitNpmChains() error { - log.Printf("Initializing AZURE-NPM chains") + log.Printf("[Azure-NPM] Initializing AZURE-NPM chains.") if err := iptMgr.AddChain(util.IptablesAzureChain); err != nil { return err @@ -72,7 +72,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err = iptMgr.Run(entry); err != nil { - log.Printf("Error adding AZURE-NPM chain to FORWARD chain\n") + log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM chain to FORWARD chain.") return err } } @@ -95,7 +95,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err = iptMgr.Run(entry); err != nil { - log.Printf("Error adding default allow CONNECTED/RELATED rule to AZURE-NPM chain\n") + log.Printf("[Azure-NPM] Error: failed to add default allow CONNECTED/RELATED rule to AZURE-NPM chain.") return err } } @@ -116,7 +116,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error adding AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain\n") + log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain.") return err } } @@ -147,7 +147,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error adding AZURE-NPM-EGRESS-PORT chain to AZURE-NPM chain\n") + log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-EGRESS-PORT chain to AZURE-NPM chain.") return err } } @@ -178,7 +178,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error adding AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain\n") + log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain.") return err } } @@ -210,7 +210,7 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { iptMgr.OperationFlag = util.IptablesDeletionFlag errCode, err := iptMgr.Run(entry) if errCode != 1 && err != nil { - log.Printf("Error removing default rule from FORWARD chain\n") + log.Errorf("[Azure-NPM] Error: failed to remove default rule from FORWARD chain.") return err } @@ -220,7 +220,7 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { Chain: chain, } if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error flushing iptables chain %s\n", chain) + log.Errorf("[Azure-NPM] Error: failed to flush iptables chain %s.", chain) } } @@ -238,12 +238,12 @@ func (iptMgr *IptablesManager) Exists(entry *IptEntry) (bool, error) { iptMgr.OperationFlag = util.IptablesCheckFlag returnCode, err := iptMgr.Run(entry) if err == nil { - log.Printf("Rule exists. %+v\n", entry) + log.Printf("[Azure-NPM] Rule exists. %+v.", entry) return true, nil } if returnCode == 1 { - log.Printf("Rule doesn't exist. %+v\n", entry) + log.Printf("[Azure-NPM] Rule doesn't exist. %+v.", entry) return false, nil } @@ -259,11 +259,11 @@ func (iptMgr *IptablesManager) AddChain(chain string) error { errCode, err := iptMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("Chain already exists %s\n", entry.Chain) + log.Printf("[Azure-NPM] Chain already exists %s.", entry.Chain) return nil } - log.Printf("Error creating iptables chain %s\n", entry.Chain) + log.Errorf("[Azure-NPM] Error: failed to create iptables chain %s.", entry.Chain) return err } @@ -279,10 +279,10 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { errCode, err := iptMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("Chain doesn't exist %s\n", entry.Chain) + log.Printf("[Azure-NPM] Chain doesn't exist %s.", entry.Chain) return nil } - log.Printf("Error deleting iptables chain %s\n", entry.Chain) + log.Errorf("[Azure-NPM] Error: failed to delete iptables chain %s.", entry.Chain) return err } @@ -291,7 +291,7 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { // Add adds a rule in iptables. func (iptMgr *IptablesManager) Add(entry *IptEntry) error { - log.Printf("Add iptables entry: %+v\n", entry) + log.Printf("[Azure-NPM] Add iptables entry: %+v.", entry) exists, err := iptMgr.Exists(entry) if err != nil { @@ -304,7 +304,7 @@ func (iptMgr *IptablesManager) Add(entry *IptEntry) error { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error creating iptables rules.\n") + log.Errorf("[Azure-NPM] Error: failed to create iptables rules.") return err } @@ -313,7 +313,7 @@ func (iptMgr *IptablesManager) Add(entry *IptEntry) error { // Delete removes a rule in iptables. func (iptMgr *IptablesManager) Delete(entry *IptEntry) error { - log.Printf("Deleting iptables entry: %+v\n", entry) + log.Printf("[Azure-NPM] Deleting iptables entry: %+v", entry) exists, err := iptMgr.Exists(entry) if err != nil { @@ -326,7 +326,7 @@ func (iptMgr *IptablesManager) Delete(entry *IptEntry) error { iptMgr.OperationFlag = util.IptablesDeletionFlag if _, err := iptMgr.Run(entry); err != nil { - log.Printf("Error deleting iptables rules.\n") + log.Errorf("[Azure-NPM] Error: failed to delete iptables rules.") return err } @@ -335,8 +335,9 @@ func (iptMgr *IptablesManager) Delete(entry *IptEntry) error { // Run execute an iptables command to update iptables. func (iptMgr *IptablesManager) Run(entry *IptEntry) (int, error) { - if entry.Command == "" { - entry.Command = util.Iptables + cmdName := entry.Command + if cmdName == "" { + cmdName = util.Iptables } if entry.LockWaitTimeInSeconds == "" { @@ -344,13 +345,13 @@ func (iptMgr *IptablesManager) Run(entry *IptEntry) (int, error) { } cmdArgs := append([]string{util.IptablesWaitFlag, entry.LockWaitTimeInSeconds, iptMgr.OperationFlag, entry.Chain}, entry.Specs...) - cmdOut, err := exec.Command(entry.Command, cmdArgs...).Output() - log.Printf("%s\n", string(cmdOut)) + log.Printf("[Azure-NPM] Executing iptables command %s %v", cmdName, cmdArgs) + _, err := exec.Command(cmdName, cmdArgs...).Output() if msg, failed := err.(*exec.ExitError); failed { errCode := msg.Sys().(syscall.WaitStatus).ExitStatus() if errCode > 1 { - log.Printf("There was an error running command: %s\nArguments:%+v", err, cmdArgs) + log.Errorf("[Azure-NPM] Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) } return errCode, err @@ -372,14 +373,14 @@ func (iptMgr *IptablesManager) Save(configFile string) error { defer func(l *os.File) { if err = l.Close(); err != nil { - log.Printf("Failed to close iptables locks") + log.Printf("[Azure-NPM] Failed to close iptables locks") } }(l) // create the config file for writing f, err := os.Create(configFile) if err != nil { - log.Printf("Error opening file: %s.", configFile) + log.Errorf("[Azure-NPM] Error: failed to open file: %s.", configFile) return err } defer f.Close() @@ -387,7 +388,7 @@ func (iptMgr *IptablesManager) Save(configFile string) error { cmd := exec.Command(util.IptablesSave) cmd.Stdout = f if err := cmd.Start(); err != nil { - log.Printf("Error running iptables-save.") + log.Errorf("[Azure-NPM] Error: failed to run iptables-save.") return err } cmd.Wait() @@ -408,14 +409,14 @@ func (iptMgr *IptablesManager) Restore(configFile string) error { defer func(l *os.File) { if err = l.Close(); err != nil { - log.Printf("Failed to close iptables locks") + log.Printf("[Azure-NPM] Failed to close iptables locks") } }(l) // open the config file for reading f, err := os.Open(configFile) if err != nil { - log.Printf("Error opening file: %s.", configFile) + log.Errorf("[Azure-NPM] Error: failed to open file: %s.", configFile) return err } defer f.Close() @@ -423,7 +424,7 @@ func (iptMgr *IptablesManager) Restore(configFile string) error { cmd := exec.Command(util.IptablesRestore) cmd.Stdin = f if err := cmd.Start(); err != nil { - log.Printf("Error running iptables-restore.\n") + log.Errorf("[Azure-NPM] Error: failed to run iptables-restore.") return err } cmd.Wait() @@ -446,7 +447,7 @@ func grabIptablesLocks() (*os.File, error) { // Grab 1.6.x style lock. l, err := os.OpenFile(util.IptablesLockFile, os.O_CREATE, 0600) if err != nil { - log.Printf("failed to open iptables lock") + log.Printf("[Azure-NPM] Error: failed to open iptables lock file %s.", util.IptablesLockFile) return nil, err } @@ -457,7 +458,7 @@ func grabIptablesLocks() (*os.File, error) { return true, nil }); err != nil { - log.Printf("failed to acquire new iptables lock: %v", err) + log.Printf("[Azure-NPM] Error: failed to acquire new iptables lock: %v.", err) return nil, err } diff --git a/npm/namespace.go b/npm/namespace.go index 9ce7548811..d44b1c949e 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -49,7 +49,7 @@ func (npMgr *NetworkPolicyManager) InitAllNsList() error { } if err := allNs.ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Printf("Error adding namespace set %s to list %s\n", nsName, util.KubeAllNamespacesFlag) + log.Errorf("[Azure-NPM] Error: failed to add namespace set %s to list %s", nsName, util.KubeAllNamespacesFlag) return err } } @@ -66,7 +66,7 @@ func (npMgr *NetworkPolicyManager) UninitAllNsList() error { } if err := allNs.ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Printf("Error deleting namespace set %s from list %s\n", nsName, util.KubeAllNamespacesFlag) + log.Errorf("[Azure-NPM] Error: failed to delete namespace set %s from list %s", nsName, util.KubeAllNamespacesFlag) return err } } @@ -81,24 +81,18 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.AddNamespaceEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - - nsName, nsNs := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace - log.Printf("NAMESPACE CREATING: %s/%s\n", nsName, nsNs) + nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + log.Printf("[Azure-NPM] NAMESPACE CREATING: [%s/%s/%+v]", nsName, nsNs, nsLabel) ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Create ipset for the namespace. if err = ipsMgr.CreateSet(nsName); err != nil { - log.Printf("Error creating ipset for namespace %s.\n", nsName) + log.Errorf("[Azure-NPM] Error: failed to create ipset for namespace %s.", nsName) return err } if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Printf("Error adding %s to all-namespace ipset list.\n", nsName) + log.Errorf("[Azure-NPM] Error: failed to add %s to all-namespace ipset list.", nsName) return err } @@ -107,9 +101,9 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) - log.Printf("Adding namespace %s to ipset list %s\n", nsName, labelKey) + log.Printf("[Azure-NPM] Adding namespace %s to ipset list %s", nsName, labelKey) if err = ipsMgr.AddToList(labelKey, nsName); err != nil { - log.Printf("Error Adding namespace %s to ipset list %s\n", nsName, labelKey) + log.Errorf("[Azure-NPM] Error: failed to add namespace %s to ipset list %s", nsName, labelKey) return err } labelKeys = append(labelKeys, labelKey) @@ -117,7 +111,7 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { ns, err := newNs(nsName) if err != nil { - log.Printf("Error creating namespace %s\n", nsName) + log.Errorf("[Azure-NPM] Error: failed to create namespace %s", nsName) } npMgr.nsMap[nsName] = ns @@ -128,16 +122,12 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { func (npMgr *NetworkPolicyManager) UpdateNamespace(oldNsObj *corev1.Namespace, newNsObj *corev1.Namespace) error { var err error - defer func() { - npMgr.Lock() - if err = npMgr.UpdateAndSendReport(err, util.AddNamespaceEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - npMgr.Unlock() - }() - - oldNsName, newNsName := oldNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Name - log.Printf("NAMESPACE UPDATING. %s/%s", oldNsName, newNsName) + oldNsName, oldNsNs, oldNsLabel := oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels + newNsName, newNsNs, newNsLabel := newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels + log.Printf( + "[Azure-NPM] NAMESPACE UPDATING:\n old namespace: [%s/%s/%+v]\n new namespace: [%s/%s/%+v]", + oldNsName, oldNsNs, oldNsLabel, newNsName, newNsNs, newNsLabel, + ) if err = npMgr.DeleteNamespace(oldNsObj); err != nil { return err @@ -159,14 +149,8 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.DeleteNamespaceEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - - nsName, nsNs := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace - log.Printf("NAMESPACE DELETING: %s/%s\n", nsName, nsNs) + nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + log.Printf("[Azure-NPM] NAMESPACE DELETING: [%s/%s/%+v]", nsName, nsNs, nsLabel) _, exists := npMgr.nsMap[nsName] if !exists { @@ -179,9 +163,9 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) - log.Printf("Deleting namespace %s from ipset list %s\n", nsName, labelKey) + log.Printf("[Azure-NPM] Deleting namespace %s from ipset list %s", nsName, labelKey) if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { - log.Printf("Error deleting namespace %s from ipset list %s\n", nsName, labelKey) + log.Errorf("[Azure-NPM] Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) return err } labelKeys = append(labelKeys, labelKey) @@ -189,13 +173,13 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro // Delete the namespace from all-namespace ipset list. if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Printf("Error deleting namespace %s from ipset list %s\n", nsName, util.KubeAllNamespacesFlag) + log.Errorf("[Azure-NPM] Error: failed to delete namespace %s from ipset list %s", nsName, util.KubeAllNamespacesFlag) return err } // Delete ipset for the namespace. if err = ipsMgr.DeleteSet(nsName); err != nil { - log.Printf("Error deleting ipset for namespace %s.\n", nsName) + log.Errorf("[Azure-NPM] Error: failed to delete ipset for namespace %s.", nsName) return err } diff --git a/npm/namespace_test.go b/npm/namespace_test.go index 9cc69176dd..d4906dd68c 100644 --- a/npm/namespace_test.go +++ b/npm/namespace_test.go @@ -49,7 +49,7 @@ func TestAddNamespace(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -91,7 +91,7 @@ func TestUpdateNamespace(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -146,7 +146,7 @@ func TestDeleteNamespace(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } diff --git a/npm/npm.go b/npm/npm.go index 806433d32b..10b57c6d5a 100644 --- a/npm/npm.go +++ b/npm/npm.go @@ -25,14 +25,17 @@ import ( ) const ( - hostNetAgentURLForNpm = "http://168.63.129.16/machine/plugins?comp=netagent&type=npmreport" - contentType = "application/json" - telemetryRetryWaitTimeInSeconds = 60 - restoreRetryWaitTimeInSeconds = 5 - restoreMaxRetries = 10 - backupWaitTimeInSeconds = 60 + hostNetAgentURLForNpm = "http://168.63.129.16/machine/plugins?comp=netagent&type=npmreport" + restoreRetryWaitTimeInSeconds = 5 + restoreMaxRetries = 10 + backupWaitTimeInSeconds = 60 + telemetryRetryTimeInSeconds = 60 + heartbeatIntervalInMinutes = 30 ) +// reports channel +var reports = make(chan interface{}, 1000) + // NetworkPolicyManager contains informers for pod, namespace and networkpolicy. type NetworkPolicyManager struct { sync.Mutex @@ -58,17 +61,17 @@ type NetworkPolicyManager struct { func (npMgr *NetworkPolicyManager) GetClusterState() telemetry.ClusterState { pods, err := npMgr.clientset.CoreV1().Pods("").List(metav1.ListOptions{}) if err != nil { - log.Printf("Error Listing pods in GetClusterState") + log.Logf("[Azure-NPM] Error: Failed to list pods in GetClusterState") } namespaces, err := npMgr.clientset.CoreV1().Namespaces().List(metav1.ListOptions{}) if err != nil { - log.Printf("Error Listing namespaces in GetClusterState") + log.Logf("[Azure-NPM] Error: Failed to list namespaces in GetClusterState") } networkpolicies, err := npMgr.clientset.NetworkingV1().NetworkPolicies("").List(metav1.ListOptions{}) if err != nil { - log.Printf("Error Listing networkpolicies in GetClusterState") + log.Logf("[Azure-NPM] Error: Failed to list networkpolicies in GetClusterState") } npMgr.clusterState.PodCount = len(pods.Items) @@ -78,31 +81,58 @@ func (npMgr *NetworkPolicyManager) GetClusterState() telemetry.ClusterState { return npMgr.clusterState } -// UpdateAndSendReport updates the npm report then send it. -// This function should only be called when npMgr is locked. -func (npMgr *NetworkPolicyManager) UpdateAndSendReport(err error, eventMsg string) error { +// SendNpmTelemetry updates the npm report then send it. +func (npMgr *NetworkPolicyManager) SendNpmTelemetry() { if !npMgr.TelemetryEnabled { - return nil + return } - clusterState := npMgr.GetClusterState() - v := reflect.ValueOf(npMgr.reportManager.Report).Elem().FieldByName("ClusterState") - if v.CanSet() { - v.FieldByName("PodCount").SetInt(int64(clusterState.PodCount)) - v.FieldByName("NsCount").SetInt(int64(clusterState.NsCount)) - v.FieldByName("NwPolicyCount").SetInt(int64(clusterState.NwPolicyCount)) +CONNECT: + tb := telemetry.NewTelemetryBuffer("") + for { + tb.TryToConnectToTelemetryService() + if tb.Connected { + break + } + + time.Sleep(time.Second * telemetryRetryTimeInSeconds) } - reflect.ValueOf(npMgr.reportManager.Report).Elem().FieldByName("EventMessage").SetString(eventMsg) + heartbeat := time.NewTicker(time.Minute * heartbeatIntervalInMinutes).C + report := npMgr.reportManager.Report + for { + select { + case <-heartbeat: + clusterState := npMgr.GetClusterState() + v := reflect.ValueOf(report).Elem().FieldByName("ClusterState") + if v.CanSet() { + v.FieldByName("PodCount").SetInt(int64(clusterState.PodCount)) + v.FieldByName("NsCount").SetInt(int64(clusterState.NsCount)) + v.FieldByName("NwPolicyCount").SetInt(int64(clusterState.NwPolicyCount)) + } + reflect.ValueOf(report).Elem().FieldByName("ErrorMessage").SetString("heartbeat") + case msg := <-reports: + reflect.ValueOf(report).Elem().FieldByName("ErrorMessage").SetString(msg.(string)) + fmt.Println(msg.(string)) + } - if err != nil { - reflect.ValueOf(npMgr.reportManager.Report).Elem().FieldByName("EventMessage").SetString(err.Error()) - } + reflect.ValueOf(report).Elem().FieldByName("Timestamp").SetString(time.Now().UTC().String()) + // TODO: Remove below line after the host change is rolled out + reflect.ValueOf(report).Elem().FieldByName("EventMessage").SetString(time.Now().UTC().String()) - var telemetryBuffer *telemetry.TelemetryBuffer - connectToTelemetryServer(telemetryBuffer) + report, err := npMgr.reportManager.ReportToBytes() + if err != nil { + log.Logf("[Azure-NPM] ReportToBytes failed: %v", err) + continue + } - return npMgr.reportManager.SendReport(telemetryBuffer) + // If write fails, try to re-establish connections as server/client + if _, err = tb.Write(report); err != nil { + log.Logf("[Azure-NPM] Telemetry write failed: %v", err) + tb.Close() + goto CONNECT + } + } } // restore restores iptables from backup file @@ -117,7 +147,7 @@ func (npMgr *NetworkPolicyManager) restore() { time.Sleep(restoreRetryWaitTimeInSeconds * time.Second) } - log.Printf("Timeout restoring Azure-NPM states") + log.Logf("[Azure-NPM] Error: timeout restoring Azure-NPM states") panic(err.Error) } @@ -129,7 +159,7 @@ func (npMgr *NetworkPolicyManager) backup() { time.Sleep(backupWaitTimeInSeconds * time.Second) if err = iptMgr.Save(util.IptablesConfigFile); err != nil { - log.Printf("Error backing up Azure-NPM states") + log.Logf("[Azure-NPM] Error: failed to back up Azure-NPM states") } } } @@ -162,51 +192,6 @@ func (npMgr *NetworkPolicyManager) Start(stopCh <-chan struct{}) error { return nil } -func connectToTelemetryServer(telemetryBuffer *telemetry.TelemetryBuffer) { - for { - telemetryBuffer = telemetry.NewTelemetryBuffer("") - err := telemetryBuffer.StartServer() - if err == nil || telemetryBuffer.FdExists { - connErr := telemetryBuffer.Connect() - if connErr == nil { - break - } - - log.Printf("[NPM-Telemetry] Failed to establish telemetry manager connection.") - time.Sleep(time.Second * telemetryRetryWaitTimeInSeconds) - } - } -} - -// RunReportManager starts NPMReportManager and send telemetry periodically. -func (npMgr *NetworkPolicyManager) RunReportManager() { - if !npMgr.TelemetryEnabled { - return - } - - var telemetryBuffer *telemetry.TelemetryBuffer - connectToTelemetryServer(telemetryBuffer) - - go telemetryBuffer.BufferAndPushData(time.Duration(0)) - - for { - clusterState := npMgr.GetClusterState() - v := reflect.ValueOf(npMgr.reportManager.Report).Elem().FieldByName("ClusterState") - if v.CanSet() { - v.FieldByName("PodCount").SetInt(int64(clusterState.PodCount)) - v.FieldByName("NsCount").SetInt(int64(clusterState.NsCount)) - v.FieldByName("NwPolicyCount").SetInt(int64(clusterState.NwPolicyCount)) - } - - if err := npMgr.reportManager.SendReport(telemetryBuffer); err != nil { - log.Printf("[NPM-Telemetry] Error sending NPM telemetry report") - connectToTelemetryServer(telemetryBuffer) - } - - time.Sleep(5 * time.Minute) - } -} - // NewNetworkPolicyManager creates a NetworkPolicyManager func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory informers.SharedInformerFactory, npmVersion string) *NetworkPolicyManager { @@ -216,13 +201,13 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in serverVersion, err := clientset.ServerVersion() if err != nil { - log.Printf("Error retrieving server version") + log.Logf("[Azure-NPM] Error: failed to retrieving kubernetes version") panic(err.Error) } - log.Printf("API server version: %+v", serverVersion) + log.Logf("[Azure-NPM] API server version: %+v", serverVersion) if err = util.SetIsNewNwPolicyVerFlag(serverVersion); err != nil { - log.Printf("Error setting IsNewNwPolicyVerFlag") + log.Logf("[Azure-NPM] Error: failed to set IsNewNwPolicyVerFlag") panic(err.Error) } @@ -242,20 +227,25 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in }, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, serverVersion: serverVersion, TelemetryEnabled: true, } + // Set-up channel for Azure-NPM telemetry if it's enabled (enabled by default) + if logger := log.GetStd(); logger != nil && npMgr.TelemetryEnabled { + logger.SetChannel(reports) + } + clusterID := util.GetClusterID(npMgr.nodeName) clusterState := npMgr.GetClusterState() npMgr.reportManager.Report.(*telemetry.NPMReport).GetReport(clusterID, npMgr.nodeName, npmVersion, serverVersion.GitVersion, clusterState) allNs, err := newNs(util.KubeAllNamespacesFlag) if err != nil { - log.Printf("Error creating all-namespace") + log.Logf("[Azure-NPM] Error: failed to create all-namespace.") panic(err.Error) } npMgr.nsMap[util.KubeAllNamespacesFlag] = allNs diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 77b009b75e..64313ad387 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -15,25 +15,19 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.AddNetworkPolicyEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name - log.Printf("NETWORK POLICY CREATING: %s/%s\n", npNs, npName) + log.Printf("[Azure-NPM] NETWORK POLICY CREATING: %v", npObj) allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] if !npMgr.isAzureNpmChainCreated { if err = allNs.ipsMgr.CreateSet(util.KubeSystemFlag); err != nil { - log.Printf("Error initialize kube-system ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to initialize kube-system ipset.") return err } if err = allNs.iptMgr.InitNpmChains(); err != nil { - log.Printf("Error initialize azure-npm chains.\n") + log.Errorf("[Azure-NPM] Error: failed to initialize azure-npm chains.") return err } @@ -45,27 +39,27 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ipsMgr := allNs.ipsMgr for _, set := range podSets { if err = ipsMgr.CreateSet(set); err != nil { - log.Printf("Error creating ipset %s-%s\n", npNs, set) + log.Errorf("[Azure-NPM] Error: failed to create ipset %s-%s", npNs, set) return err } } for _, list := range nsLists { if err = ipsMgr.CreateList(list); err != nil { - log.Printf("Error creating ipset list %s-%s\n", npNs, list) + log.Errorf("[Azure-NPM] Error: failed to create ipset list %s-%s", npNs, list) return err } } if err = npMgr.InitAllNsList(); err != nil { - log.Printf("Error initializing all-namespace ipset list.\n") + log.Errorf("[Azure-NPM] Error: failed to initialize all-namespace ipset list.") return err } iptMgr := allNs.iptMgr for _, iptEntry := range iptEntries { if err = iptMgr.Add(iptEntry); err != nil { - log.Printf("Error applying iptables rule\n. Rule: %+v", iptEntry) + log.Errorf("[Azure-NPM] Error: failed to apply iptables rule. Rule: %+v", iptEntry) return err } } @@ -74,7 +68,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ns, err := newNs(npNs) if err != nil { - log.Printf("Error creating namespace %s\n", npNs) + log.Errorf("[Azure-NPM] Error: failed to create namespace %s", npNs) } npMgr.nsMap[npNs] = ns @@ -85,16 +79,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP func (npMgr *NetworkPolicyManager) UpdateNetworkPolicy(oldNpObj *networkingv1.NetworkPolicy, newNpObj *networkingv1.NetworkPolicy) error { var err error - defer func() { - npMgr.Lock() - if err = npMgr.UpdateAndSendReport(err, util.UpdateNetworkPolicyEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - npMgr.Unlock() - }() - - oldNpNs, oldNpName := oldNpObj.ObjectMeta.Namespace, oldNpObj.ObjectMeta.Name - log.Printf("NETWORK POLICY UPDATING: %s/%s\n", oldNpNs, oldNpName) + log.Printf("[Azure-NPM] NETWORK POLICY UPDATING:\n old policy:[%v]\n new policy:[%v]", oldNpObj, newNpObj) if err = npMgr.DeleteNetworkPolicy(oldNpObj); err != nil { return err @@ -116,14 +101,8 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.DeleteNetworkPolicyEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - - npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name - log.Printf("NETWORK POLICY DELETING: %s/%s\n", npNs, npName) + npName := npObj.ObjectMeta.Name + log.Printf("[Azure-NPM] NETWORK POLICY DELETING: %v", npObj) allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] @@ -132,7 +111,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo iptMgr := allNs.iptMgr for _, iptEntry := range iptEntries { if err = iptMgr.Delete(iptEntry); err != nil { - log.Printf("Error applying iptables rule.\n Rule: %+v", iptEntry) + log.Errorf("[Azure-NPM] Error: failed to apply iptables rule. Rule: %+v", iptEntry) return err } } @@ -141,7 +120,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo if len(allNs.npMap) == 0 { if err = iptMgr.UninitNpmChains(); err != nil { - log.Printf("Error uninitialize azure-npm chains.\n") + log.Errorf("[Azure-NPM] Error: failed to uninitialize azure-npm chains.") return err } npMgr.isAzureNpmChainCreated = false diff --git a/npm/nwpolicy_test.go b/npm/nwpolicy_test.go index 1c01d8cc5b..2e564649de 100644 --- a/npm/nwpolicy_test.go +++ b/npm/nwpolicy_test.go @@ -22,7 +22,7 @@ func TestAddNetworkPolicy(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -102,7 +102,7 @@ func TestUpdateNetworkPolicy(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -210,7 +210,7 @@ func TestDeleteNetworkPolicy(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } diff --git a/npm/parse.go b/npm/parse.go index 977256c6a8..35178887b4 100644 --- a/npm/parse.go +++ b/npm/parse.go @@ -62,7 +62,7 @@ func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPo // Use hashed string for ipset name to avoid string length limit of ipset. for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) + log.Printf("[Azure-NPM] Parsing iptables for label %s", targetSet) hashedTargetSetName := util.GetHashedName(targetSet) @@ -427,7 +427,7 @@ func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPo } } - log.Printf("finished parsing ingress rule") + log.Printf("[Azure-NPM] finished parsing ingress rule") return policyRuleSets, policyRuleLists, entries } @@ -471,7 +471,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol // Use hashed string for ipset name to avoid string length limit of ipset. for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) + log.Printf("[Azure-NPM] Parsing iptables for label %s", targetSet) hashedTargetSetName := util.GetHashedName(targetSet) @@ -764,7 +764,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol // Allow traffic from podSelector intersects namespaceSelector // This is only supported in kubernetes version >= 1.11 if util.IsNewNwPolicyVerFlag { - log.Printf("Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") + log.Printf("[Azure-NPM] Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") // allow traffic from all namespaces if len(toRule.NamespaceSelector.MatchLabels) == 0 { nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) @@ -837,7 +837,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol } } - log.Printf("finished parsing ingress rule") + log.Printf("[Azure-NPM] finished parsing ingress rule") return policyRuleSets, policyRuleLists, entries } diff --git a/npm/plugin/main.go b/npm/plugin/main.go index 25909bd9b1..be52aea16c 100644 --- a/npm/plugin/main.go +++ b/npm/plugin/main.go @@ -14,6 +14,8 @@ import ( "k8s.io/client-go/rest" ) +const waitForTelemetryInSeconds = 60 + // Version is populated by make during build. var version string @@ -21,7 +23,7 @@ func initLogging() error { log.SetName("azure-npm") log.SetLevel(log.LevelInfo) if err := log.SetTarget(log.TargetLogfile); err != nil { - log.Printf("[cni-npm] Failed to configure logging, err:%v.\n", err) + log.Logf("[Azure-NPM] Failed to configure logging, err:%v.", err) return err } @@ -33,7 +35,7 @@ func main() { defer func() { if r := recover(); r != nil { - log.Printf("[cni-npm] recovered from error: %v", err) + log.Logf("[Azure-NPM] recovered from error: %v", err) } }() @@ -50,22 +52,23 @@ func main() { // Creates the clientset clientset, err := kubernetes.NewForConfig(config) if err != nil { - log.Printf("[Azure-NPM] clientset creation failed with error %v.\n", err) + log.Logf("[Azure-NPM] clientset creation failed with error %v.", err) panic(err.Error()) } factory := informers.NewSharedInformerFactory(clientset, time.Hour*24) npMgr := npm.NewNetworkPolicyManager(clientset, factory, version) + + go npMgr.SendNpmTelemetry() + + time.Sleep(time.Second * waitForTelemetryInSeconds) + err = npMgr.Start(wait.NeverStop) if err != nil { - log.Printf("[Azure-NPM] npm failed with error %v.", err) + log.Logf("[Azure-NPM] npm failed with error %v.", err) panic(err.Error) } - // Disable Azure-NPM telemetry for now since it might throttle wireserver. - npMgr.TelemetryEnabled = false - go npMgr.RunReportManager() - select {} } diff --git a/npm/pod.go b/npm/pod.go index 5cb4f67f85..afbbc31a2d 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -12,9 +12,9 @@ import ( ) func isValidPod(podObj *corev1.Pod) bool { - return podObj.Status.Phase != "Failed" && - podObj.Status.Phase != "Succeeded" && - podObj.Status.Phase != "Unknown" && + return podObj.Status.Phase != corev1.PodPhase(util.KubePodStatusFailedFlag) && + podObj.Status.Phase != corev1.PodPhase(util.KubePodStatusSucceededFlag) && + podObj.Status.Phase != corev1.PodPhase(util.KubePodStatusUnknownFlag) && len(podObj.Status.PodIP) > 0 } @@ -33,25 +33,19 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.AddPodEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - podNs := podObj.ObjectMeta.Namespace podName := podObj.ObjectMeta.Name podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels podIP := podObj.Status.PodIP - log.Printf("POD CREATING: %s/%s/%s%+v%s\n", podNs, podName, podNodeName, podLabels, podIP) + log.Printf("[Azure-NPM] POD CREATING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) // Add the pod to ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Add the pod to its namespace's ipset. - log.Printf("Adding pod %s to ipset %s\n", podIP, podNs) + log.Printf("[Azure-NPM] Adding pod %s to ipset %s", podIP, podNs) if err = ipsMgr.AddToSet(podNs, podIP); err != nil { - log.Printf("Error adding pod to namespace ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to add pod to namespace ipset.") return err } @@ -64,9 +58,9 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { } labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - log.Printf("Adding pod %s to ipset %s\n", podIP, labelKey) + log.Printf("[Azure-NPM] Adding pod %s to ipset %s", podIP, labelKey) if err = ipsMgr.AddToSet(labelKey, podIP); err != nil { - log.Printf("Error adding pod to label ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to add pod to label ipset.") return err } labelKeys = append(labelKeys, labelKey) @@ -74,7 +68,7 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { ns, err := newNs(podNs) if err != nil { - log.Printf("Error creating namespace %s\n", podNs) + log.Errorf("[Azure-NPM] Error: failed to create namespace %s", podNs) return err } npMgr.nsMap[podNs] = ns @@ -90,26 +84,21 @@ func (npMgr *NetworkPolicyManager) UpdatePod(oldPodObj, newPodObj *corev1.Pod) e var err error - defer func() { - npMgr.Lock() - if err = npMgr.UpdateAndSendReport(err, util.UpdateNamespaceEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - npMgr.Unlock() - }() - oldPodObjNs := oldPodObj.ObjectMeta.Namespace oldPodObjName := oldPodObj.ObjectMeta.Name + oldPodObjLabel := oldPodObj.ObjectMeta.Labels oldPodObjPhase := oldPodObj.Status.Phase oldPodObjIP := oldPodObj.Status.PodIP newPodObjNs := newPodObj.ObjectMeta.Namespace newPodObjName := newPodObj.ObjectMeta.Name + newPodObjLabel := newPodObj.ObjectMeta.Labels newPodObjPhase := newPodObj.Status.Phase newPodObjIP := newPodObj.Status.PodIP log.Printf( - "POD UPDATING. %s %s %s %s %s %s %s %s\n", - oldPodObjNs, oldPodObjName, oldPodObjPhase, oldPodObjIP, newPodObjNs, newPodObjName, newPodObjPhase, newPodObjIP, + "[Azure-NPM] POD UPDATING:\n old pod: [%s/%s/%+v/%s/%s]\n new pod: [%s/%s/%+v/%s/%s]", + oldPodObjNs, oldPodObjName, oldPodObjLabel, oldPodObjPhase, oldPodObjIP, + newPodObjNs, newPodObjName, newPodObjLabel, newPodObjPhase, newPodObjIP, ) if err = npMgr.DeletePod(oldPodObj); err != nil { @@ -136,24 +125,18 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { var err error - defer func() { - if err = npMgr.UpdateAndSendReport(err, util.DeletePodEvent); err != nil { - log.Printf("Error sending NPM telemetry report") - } - }() - podNs := podObj.ObjectMeta.Namespace podName := podObj.ObjectMeta.Name podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels podIP := podObj.Status.PodIP - log.Printf("POD DELETING: %s/%s/%s\n", podNs, podName, podNodeName) + log.Printf("[Azure-NPM] POD DELETING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) // Delete pod from ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Delete the pod from its namespace's ipset. if err = ipsMgr.DeleteFromSet(podNs, podIP); err != nil { - log.Printf("Error deleting pod from namespace ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to delete pod from namespace ipset.") return err } // Delete the pod from its label's ipset. @@ -165,7 +148,7 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal if err = ipsMgr.DeleteFromSet(labelKey, podIP); err != nil { - log.Printf("Error deleting pod from label ipset.\n") + log.Errorf("[Azure-NPM] Error: failed to delete pod from label ipset.") return err } } diff --git a/npm/pod_test.go b/npm/pod_test.go index 6330c1e4ce..716621997c 100644 --- a/npm/pod_test.go +++ b/npm/pod_test.go @@ -41,7 +41,7 @@ func TestAddPod(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -86,7 +86,7 @@ func TestUpdatePod(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } @@ -149,7 +149,7 @@ func TestDeletePod(t *testing.T) { TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: contentType, + ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, } diff --git a/npm/util/const.go b/npm/util/const.go index 42b1509813..040ab48fba 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -4,12 +4,15 @@ package util //kubernetes related constants. const ( - KubeSystemFlag string = "kube-system" - KubePodTemplateHashFlag string = "pod-template-hash" - KubeAllPodsFlag string = "all-pod" - KubeAllNamespacesFlag string = "all-namespace" - KubeAppFlag string = "k8s-app" - KubeProxyFlag string = "kube-proxy" + KubeSystemFlag string = "kube-system" + KubePodTemplateHashFlag string = "pod-template-hash" + KubeAllPodsFlag string = "all-pod" + KubeAllNamespacesFlag string = "all-namespace" + KubeAppFlag string = "k8s-app" + KubeProxyFlag string = "kube-proxy" + KubePodStatusFailedFlag string = "Failed" + KubePodStatusSucceededFlag string = "Succeeded" + KubePodStatusUnknownFlag string = "Unknown" // The version of k8s that accept "AND" between namespaceSelector and podSelector is "1.11" k8sMajorVerForNewPolicyDef string = "1" diff --git a/telemetry/cnstelemetry.go b/telemetry/cnstelemetry.go index 271e0c51de..7bcea55844 100644 --- a/telemetry/cnstelemetry.go +++ b/telemetry/cnstelemetry.go @@ -24,6 +24,8 @@ const ( telemetryWaitTimeInMilliseconds = 200 ) +var codeRegex = regexp.MustCompile(`Code:(\w*)`) + // SendCnsTelemetry - handles cns telemetry reports func SendCnsTelemetry(reports chan interface{}, service *restserver.HTTPRestService, telemetryStopProcessing chan bool) { @@ -50,7 +52,7 @@ CONNECT: case <-heartbeat: reflect.ValueOf(reportMgr.Report).Elem().FieldByName("EventMessage").SetString("Heartbeat") case msg := <-reports: - codeStr := regexp.MustCompile(`Code:(\w*)`).FindString(msg.(string)) + codeStr := codeRegex.FindString(msg.(string)) if len(codeStr) > errorcodePrefix { reflect.ValueOf(reportMgr.Report).Elem().FieldByName("Errorcode").SetString(codeStr[errorcodePrefix:]) } @@ -74,7 +76,7 @@ CONNECT: if err == nil { // If write fails, try to re-establish connections as server/client if _, err = tb.Write(report); err != nil { - log.Printf("[CNS-Telemetry] Telemetry write failed: %v", err) + log.Logf("[CNS-Telemetry] Telemetry write failed: %v", err) tb.Close() goto CONNECT } diff --git a/telemetry/telemetry.go b/telemetry/telemetry.go index 98693cb224..62ab3c26e5 100644 --- a/telemetry/telemetry.go +++ b/telemetry/telemetry.go @@ -156,6 +156,7 @@ type NPMReport struct { ErrorMessage string EventMessage string UpTime string + Timestamp string ClusterState ClusterState Metadata Metadata `json:"compute"` } @@ -238,7 +239,7 @@ func (reportMgr *ReportManager) SetReportState(telemetryFile string) error { _, err = f.Write(reportBytes) if err != nil { - log.Printf("[Telemetry] Error while writing to file %v", err) + fmt.Printf("[Telemetry] Error while writing to file %v", err) return fmt.Errorf("[Telemetry] Error while writing to file %v", err) } @@ -251,7 +252,7 @@ func (reportMgr *ReportManager) SetReportState(telemetryFile string) error { func (reportMgr *ReportManager) GetReportState(telemetryFile string) bool { // try to set IsNewInstance in report if _, err := os.Stat(telemetryFile); os.IsNotExist(err) { - log.Printf("[Telemetry] File not exist %v", telemetryFile) + fmt.Printf("[Telemetry] File not exist %v", telemetryFile) reflect.ValueOf(reportMgr.Report).Elem().FieldByName("IsNewInstance").SetBool(true) return false } @@ -291,7 +292,7 @@ func (report *CNIReport) GetInterfaceDetails(queryUrl string) { if resp.StatusCode != http.StatusOK { errMsg := fmt.Sprintf("Error while getting interface details. http code :%d", resp.StatusCode) report.InterfaceDetails.ErrorMessage = errMsg - log.Printf(errMsg) + log.Logf(errMsg) return } diff --git a/telemetry/telemetry_test.go b/telemetry/telemetry_test.go index 795608e174..bdc3ce79e9 100644 --- a/telemetry/telemetry_test.go +++ b/telemetry/telemetry_test.go @@ -4,7 +4,6 @@ package telemetry import ( - "bytes" "encoding/json" "fmt" "log" @@ -135,7 +134,7 @@ func handleIpamQuery(w http.ResponseWriter, r *http.Request) { func handlePayload(rw http.ResponseWriter, req *http.Request) { decoder := json.NewDecoder(req.Body) - var t Payload + var t Buffer err := decoder.Decode(&t) if err != nil { panic(err) @@ -143,7 +142,7 @@ func handlePayload(rw http.ResponseWriter, req *http.Request) { defer req.Body.Close() log.Println(t) - log.Printf("Payload: %+v", t) + fmt.Printf("Buffer: %+v", t) } func TestGetOSDetails(t *testing.T) { @@ -189,8 +188,8 @@ func TestSendTelemetry(t *testing.T) { func TestReceiveTelemetryData(t *testing.T) { time.Sleep(300 * time.Millisecond) - if len(tb.payload.CNIReports) != 1 { - t.Errorf("payload doesn't contain CNI report") + if len(tb.buffer.CNIReports) != 1 { + t.Errorf("buffer doesn't contain CNI report") } } @@ -306,18 +305,3 @@ func TestSetReportState(t *testing.T) { t.Errorf("Error removing telemetry file due to %v", err) } } - -func TestPayloadCap(t *testing.T) { - // sampleCniReport is ~66 bytes and we're adding 2000 reports here to test that the payload will be capped to 65535 - for i := 0; i < 4; i++ { - for j := 0; j < 500; j++ { - tb.payload.push(sampleCniReport) - } - - var body bytes.Buffer - json.NewEncoder(&body).Encode(tb.payload) - if uint16(body.Len()) > MaxPayloadSize { - t.Fatalf("Payload size exceeded max size of %d", MaxPayloadSize) - } - } -} diff --git a/telemetry/telemetrybuffer.go b/telemetry/telemetrybuffer.go index 8240623628..2417c5ebba 100644 --- a/telemetry/telemetrybuffer.go +++ b/telemetry/telemetrybuffer.go @@ -29,21 +29,22 @@ type TelemetryConfig struct { // FdName - file descriptor name // Delimiter - delimiter for socket reads/writes -// azureHostReportURL - host net agent url of type payload -// DefaultInterval - default interval for sending payload to host +// azureHostReportURL - host net agent url of type buffer +// DefaultInterval - default interval for sending buffer to host // logName - telemetry log name -// MaxPayloadSize - max payload size in bytes +// MaxPayloadSize - max buffer size in bytes const ( - FdName = "azure-vnet-telemetry" - Delimiter = '\n' - azureHostReportURL = "http://168.63.129.16/machine/plugins?comp=netagent&type=payload" - minInterval = 10 * time.Second - logName = "azure-vnet-telemetry" - MaxPayloadSize uint16 = 4096 - dnc = "DNC" - cns = "CNS" - npm = "NPM" - cni = "CNI" + FdName = "azure-vnet-telemetry" + Delimiter = '\n' + azureHostReportURL = "http://168.63.129.16/machine/plugins?comp=netagent&type=payload" + minInterval = 10 * time.Second + logName = "azure-vnet-telemetry" + MaxPayloadSize = 4096 + MaxBufferSize = 1048576 + dnc = "DNC" + cns = "CNS" + npm = "NPM" + cni = "CNI" ) var payloadSize uint16 = 0 @@ -54,7 +55,7 @@ type TelemetryBuffer struct { listener net.Listener connections []net.Conn azureHostReportURL string - payload Payload + buffer Buffer FdExists bool Connected bool data chan interface{} @@ -62,8 +63,8 @@ type TelemetryBuffer struct { mutex sync.Mutex } -// Payload object holds the different types of reports -type Payload struct { +// Buffer object holds the different types of reports +type Buffer struct { DNCReports []DNCReport CNIReports []CNIReport NPMReports []NPMReport @@ -78,13 +79,13 @@ func NewTelemetryBuffer(hostReportURL string) *TelemetryBuffer { tb.azureHostReportURL = azureHostReportURL } - tb.data = make(chan interface{}) + tb.data = make(chan interface{}, 1000) tb.cancel = make(chan bool, 1) tb.connections = make([]net.Conn, 0) - tb.payload.DNCReports = make([]DNCReport, 0) - tb.payload.CNIReports = make([]CNIReport, 0) - tb.payload.NPMReports = make([]NPMReport, 0) - tb.payload.CNSReports = make([]CNSReport, 0) + tb.buffer.DNCReports = make([]DNCReport, 0) + tb.buffer.CNIReports = make([]CNIReport, 0) + tb.buffer.NPMReports = make([]NPMReport, 0) + tb.buffer.CNSReports = make([]CNSReport, 0) return &tb } @@ -95,7 +96,7 @@ func remove(s []net.Conn, i int) []net.Conn { return s[:len(s)-1] } - log.Printf("tb connections remove failed index %v len %v", i, len(s)) + log.Logf("tb connections remove failed index %v len %v", i, len(s)) return s } @@ -104,11 +105,11 @@ func (tb *TelemetryBuffer) StartServer() error { err := tb.Listen(FdName) if err != nil { tb.FdExists = strings.Contains(err.Error(), "in use") || strings.Contains(err.Error(), "Access is denied") - log.Printf("Listen returns: %v", err.Error()) + log.Logf("Listen returns: %v", err.Error()) return err } - log.Printf("Telemetry service started") + log.Logf("Telemetry service started") // Spawn server goroutine to handle incoming connections go func() { for { @@ -166,7 +167,7 @@ func (tb *TelemetryBuffer) StartServer() error { } }() } else { - log.Printf("Telemetry Server accept error %v", err) + log.Logf("Telemetry Server accept error %v", err) return } } @@ -190,7 +191,7 @@ func (tb *TelemetryBuffer) Connect() error { func (tb *TelemetryBuffer) BufferAndPushData(intervalms time.Duration) { defer tb.Close() if !tb.FdExists { - log.Printf("[Telemetry] Buffer telemetry data and send it to host") + log.Logf("[Telemetry] Buffer telemetry data and send it to host") if intervalms < minInterval { intervalms = minInterval } @@ -199,23 +200,23 @@ func (tb *TelemetryBuffer) BufferAndPushData(intervalms time.Duration) { for { select { case <-interval: - // Send payload to host and clear cache when sent successfully - // To-do : if we hit max slice size in payload, write to disk and process the logs on disk on future sends - if err := tb.sendToHost(); err == nil { - tb.payload.reset() - } else { - log.Printf("[Telemetry] sending to host failed with error %+v", err) - } + // Send buffer to host and clear cache when sent successfully + // To-do : if we hit max slice size in buffer, write to disk and process the logs on disk on future sends + tb.mutex.Lock() + tb.sendToHost() + tb.mutex.Unlock() case report := <-tb.data: - tb.payload.push(report) + tb.mutex.Lock() + tb.buffer.push(report) + tb.mutex.Unlock() case <-tb.cancel: - log.Printf("server cancel event") + log.Logf("[Telemetry] server cancel event") goto EXIT } } } else { <-tb.cancel - log.Printf("Received cancel event") + log.Logf("[Telemetry] Received cancel event") } EXIT: @@ -256,7 +257,7 @@ func (tb *TelemetryBuffer) Close() { } if tb.listener != nil { - log.Printf("server close") + log.Logf("server close") tb.listener.Close() } @@ -273,13 +274,124 @@ func (tb *TelemetryBuffer) Close() { tb.connections = make([]net.Conn, 0) } -// sendToHost - send payload to host +// sendToHost - send buffer to host func (tb *TelemetryBuffer) sendToHost() error { + buf := Buffer{ + DNCReports: make([]DNCReport, 0), + CNIReports: make([]CNIReport, 0), + NPMReports: make([]NPMReport, 0), + CNSReports: make([]CNSReport, 0), + } + i, payloadSize, maxPayloadSizeReached := 0, 0, false + isDNCReportsEmpty, isCNIReportsEmpty, isCNSReportsEmpty, isNPMReportsEmpty := false, false, false, false + for { + // craft payload in a round-robin manner. + switch i % 4 { + case 0: + reportLen := len(tb.buffer.DNCReports) + if reportLen == 0 || isDNCReportsEmpty { + isDNCReportsEmpty = true + break + } + + if reportLen == 1 { + isDNCReportsEmpty = true + } + + report := tb.buffer.DNCReports[0] + if bytes, err := json.Marshal(report); err == nil { + payloadSize += len(bytes) + if payloadSize > MaxPayloadSize { + maxPayloadSizeReached = true + break + } + } + buf.DNCReports = append(buf.DNCReports, report) + tb.buffer.DNCReports = tb.buffer.DNCReports[1:] + case 1: + reportLen := len(tb.buffer.CNIReports) + if reportLen == 0 || isCNIReportsEmpty { + isCNIReportsEmpty = true + break + } + + if reportLen == 1 { + isCNIReportsEmpty = true + } + + report := tb.buffer.CNIReports[0] + if bytes, err := json.Marshal(report); err == nil { + payloadSize += len(bytes) + if payloadSize > MaxPayloadSize { + maxPayloadSizeReached = true + break + } + } + buf.CNIReports = append(buf.CNIReports, report) + tb.buffer.CNIReports = tb.buffer.CNIReports[1:] + case 2: + reportLen := len(tb.buffer.CNSReports) + if reportLen == 0 || isCNSReportsEmpty { + isCNSReportsEmpty = true + break + } + + if reportLen == 1 { + isCNSReportsEmpty = true + } + + report := tb.buffer.CNSReports[0] + if bytes, err := json.Marshal(report); err == nil { + payloadSize += len(bytes) + if payloadSize > MaxPayloadSize { + maxPayloadSizeReached = true + break + } + } + buf.CNSReports = append(buf.CNSReports, report) + tb.buffer.CNSReports = tb.buffer.CNSReports[1:] + case 3: + reportLen := len(tb.buffer.NPMReports) + if reportLen == 0 || isNPMReportsEmpty { + isNPMReportsEmpty = true + break + } + + if reportLen == 1 { + isNPMReportsEmpty = true + } + + report := tb.buffer.NPMReports[0] + if bytes, err := json.Marshal(report); err == nil { + payloadSize += len(bytes) + if payloadSize > MaxPayloadSize { + maxPayloadSizeReached = true + break + } + } + buf.NPMReports = append(buf.NPMReports, report) + tb.buffer.NPMReports = tb.buffer.NPMReports[1:] + } + + if isDNCReportsEmpty && isCNIReportsEmpty && isCNSReportsEmpty && isNPMReportsEmpty { + break + } + + if maxPayloadSizeReached { + break + } + + i++ + } + httpc := &http.Client{} var body bytes.Buffer - log.Printf("Sending payload %+v", tb.payload) - json.NewEncoder(&body).Encode(tb.payload) + log.Logf("Sending buffer %+v", buf) + if err := json.NewEncoder(&body).Encode(buf); err != nil { + log.Logf("[Telemetry] Encode buffer error %v", err) + } resp, err := httpc.Post(tb.azureHostReportURL, ContentType, &body) + log.Logf("[Telemetry] Got response %v", resp) if err != nil { return fmt.Errorf("[Telemetry] HTTP Post returned error %v", err) } @@ -294,77 +406,48 @@ func (tb *TelemetryBuffer) sendToHost() error { } // push - push the report (x) to corresponding slice -func (pl *Payload) push(x interface{}) { +func (buf *Buffer) push(x interface{}) { metadata, err := getHostMetadata() if err != nil { - log.Printf("Error getting metadata %v", err) + log.Logf("Error getting metadata %v", err) } else { err = saveHostMetadata(metadata) if err != nil { - log.Printf("saving host metadata failed with :%v", err) + log.Logf("saving host metadata failed with :%v", err) } } - if notExceeded, reportType := pl.payloadCapNotExceeded(x); notExceeded { - switch reportType { - case dnc: - dncReport := x.(DNCReport) - dncReport.Metadata = metadata - pl.DNCReports = append(pl.DNCReports, dncReport) - case cni: - cniReport := x.(CNIReport) - cniReport.Metadata = metadata - pl.CNIReports = append(pl.CNIReports, cniReport) - case npm: - npmReport := x.(NPMReport) - npmReport.Metadata = metadata - pl.NPMReports = append(pl.NPMReports, npmReport) - case cns: - cnsReport := x.(CNSReport) - cnsReport.Metadata = metadata - pl.CNSReports = append(pl.CNSReports, cnsReport) - } - } -} - -// reset - reset payload slices and sets payloadSize to 0 -func (pl *Payload) reset() { - pl.DNCReports = nil - pl.DNCReports = make([]DNCReport, 0) - pl.CNIReports = nil - pl.CNIReports = make([]CNIReport, 0) - pl.NPMReports = nil - pl.NPMReports = make([]NPMReport, 0) - pl.CNSReports = nil - pl.CNSReports = make([]CNSReport, 0) - payloadSize = 0 -} - -// payloadCapNotExceeded - Returns whether payload cap will be exceeded as a result of adding the new report; and the report type -// If the cap is not exceeded, we update the payload size here. -func (pl *Payload) payloadCapNotExceeded(x interface{}) (notExceeded bool, reportType string) { - var body bytes.Buffer switch x.(type) { case DNCReport: - reportType = dnc - json.NewEncoder(&body).Encode(x.(DNCReport)) + dncReport := x.(DNCReport) + dncReport.Metadata = metadata + buf.DNCReports = append(buf.DNCReports, dncReport) case CNIReport: - reportType = cni - json.NewEncoder(&body).Encode(x.(CNIReport)) + cniReport := x.(CNIReport) + cniReport.Metadata = metadata + buf.CNIReports = append(buf.CNIReports, cniReport) case NPMReport: - reportType = npm - json.NewEncoder(&body).Encode(x.(NPMReport)) + npmReport := x.(NPMReport) + npmReport.Metadata = metadata + buf.NPMReports = append(buf.NPMReports, npmReport) case CNSReport: - reportType = cns - json.NewEncoder(&body).Encode(x.(CNSReport)) - } - - updatedPayloadSize := uint16(body.Len()) + payloadSize - if notExceeded = updatedPayloadSize < MaxPayloadSize && payloadSize < updatedPayloadSize; notExceeded { - payloadSize = updatedPayloadSize + cnsReport := x.(CNSReport) + cnsReport.Metadata = metadata + buf.CNSReports = append(buf.CNSReports, cnsReport) } +} - return +// reset - reset buffer slices and sets payloadSize to 0 +func (buf *Buffer) reset() { + buf.DNCReports = nil + buf.DNCReports = make([]DNCReport, 0) + buf.CNIReports = nil + buf.CNIReports = make([]CNIReport, 0) + buf.NPMReports = nil + buf.NPMReports = make([]NPMReport, 0) + buf.CNSReports = nil + buf.CNSReports = make([]CNSReport, 0) + payloadSize = 0 } // saveHostMetadata - save metadata got from wireserver to json file @@ -375,7 +458,7 @@ func saveHostMetadata(metadata Metadata) error { } if err = ioutil.WriteFile(metadataFile, dataBytes, 0644); err != nil { - log.Printf("[Telemetry] Writing metadata to file failed: %v", err) + log.Logf("[Telemetry] Writing metadata to file failed: %v", err) } return err @@ -391,7 +474,7 @@ func getHostMetadata() (Metadata, error) { } } - log.Printf("[Telemetry] Request metadata from wireserver") + log.Logf("[Telemetry] Request metadata from wireserver") req, err := http.NewRequest("GET", metadataURL, nil) if err != nil { @@ -438,14 +521,14 @@ func WaitForTelemetrySocket(maxAttempt int, waitTimeInMillisecs time.Duration) { func StartTelemetryService(path string, args []string) error { platform.KillProcessByName(TelemetryServiceProcessName) - log.Printf("[Telemetry] Starting telemetry service process :%v args:%v", path, args) + log.Logf("[Telemetry] Starting telemetry service process :%v args:%v", path, args) if err := common.StartProcess(path, args); err != nil { - log.Printf("[Telemetry] Failed to start telemetry service process :%v", err) + log.Logf("[Telemetry] Failed to start telemetry service process :%v", err) return err } - log.Printf("[Telemetry] Telemetry service started") + log.Logf("[Telemetry] Telemetry service started") return nil } @@ -456,12 +539,12 @@ func ReadConfigFile(filePath string) (TelemetryConfig, error) { b, err := ioutil.ReadFile(filePath) if err != nil { - log.Printf("[Telemetry] Failed to read telemetry config: %v", err) + log.Logf("[Telemetry] Failed to read telemetry config: %v", err) return config, err } if err = json.Unmarshal(b, &config); err != nil { - log.Printf("[Telemetry] unmarshal failed with %v", err) + log.Logf("[Telemetry] unmarshal failed with %v", err) } return config, err @@ -473,18 +556,29 @@ func (tb *TelemetryBuffer) ConnectToTelemetryService(telemetryNumRetries, teleme args := []string{"-d", dir} for attempt := 0; attempt < 2; attempt++ { if err := tb.Connect(); err != nil { - log.Printf("Connection to telemetry socket failed: %v", err) + log.Logf("Connection to telemetry socket failed: %v", err) tb.Cleanup(FdName) StartTelemetryService(path, args) WaitForTelemetrySocket(telemetryNumRetries, time.Duration(telemetryWaitTimeInMilliseconds)) } else { tb.Connected = true - log.Printf("Connected to telemetry service") + log.Logf("Connected to telemetry service") return } } } +// TryToConnectToTelemetryService - Attempt to connect telemetry process without spawning it if it's not already running. +func (tb *TelemetryBuffer) TryToConnectToTelemetryService() { + if err := tb.Connect(); err != nil { + log.Logf("Connection to telemetry socket failed: %v", err) + return + } + + tb.Connected = true + log.Logf("Connected to telemetry service") +} + func getTelemetryServiceDirectory() (path string, dir string) { path = fmt.Sprintf("%v/%v", CniInstallDir, TelemetryServiceProcessName) if exists, _ := common.CheckIfFileExists(path); !exists { @@ -492,7 +586,7 @@ func getTelemetryServiceDirectory() (path string, dir string) { exDir := filepath.Dir(ex) path = fmt.Sprintf("%v/%v", exDir, TelemetryServiceProcessName) if exists, _ = common.CheckIfFileExists(path); !exists { - log.Printf("Skip starting telemetry service as file didn't exist") + log.Logf("Skip starting telemetry service as file didn't exist") return } dir = exDir From ef51b86395896378df69585a6cf5c69aa35fc9b0 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 12 Jun 2019 11:31:36 -0700 Subject: [PATCH 20/64] remove [Azure-NPM] prefix --- npm/ipsm/ipsm.go | 50 ++++++++++++++++++++--------------------- npm/iptm/iptm.go | 56 +++++++++++++++++++++++----------------------- npm/namespace.go | 28 +++++++++++------------ npm/npm.go | 22 +++++++++--------- npm/nwpolicy.go | 24 ++++++++++---------- npm/parse.go | 10 ++++----- npm/plugin/main.go | 8 +++---- npm/pod.go | 20 ++++++++--------- 8 files changed, 109 insertions(+), 109 deletions(-) diff --git a/npm/ipsm/ipsm.go b/npm/ipsm/ipsm.go index 2637b06bea..7b52c2d233 100644 --- a/npm/ipsm/ipsm.go +++ b/npm/ipsm/ipsm.go @@ -83,9 +83,9 @@ func (ipsMgr *IpsetManager) CreateList(listName string) error { set: util.GetHashedName(listName), spec: util.IpsetSetListFlag, } - log.Printf("[Azure-NPM] Creating List: %+v", entry) + log.Printf("Creating List: %+v", entry) if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset list %s.", listName) + log.Errorf("Error: failed to create ipset list %s.", listName) return err } @@ -104,11 +104,11 @@ func (ipsMgr *IpsetManager) DeleteList(listName string) error { errCode, err := ipsMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("[Azure-NPM] Error: Cannot delete list %s as it's being referred or doesn't exist.", listName) + log.Printf("Error: Cannot delete list %s as it's being referred or doesn't exist.", listName) return nil } - log.Errorf("[Azure-NPM] Error: failed to delete ipset %s %+v", listName, entry) + log.Errorf("Error: failed to delete ipset %s %+v", listName, entry) return err } @@ -134,7 +134,7 @@ func (ipsMgr *IpsetManager) AddToList(listName string, setName string) error { } if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset rules. rule: %+v", entry) + log.Errorf("Error: failed to create ipset rules. rule: %+v", entry) return err } @@ -146,7 +146,7 @@ func (ipsMgr *IpsetManager) AddToList(listName string, setName string) error { // DeleteFromList removes an ipset to an ipset list. func (ipsMgr *IpsetManager) DeleteFromList(listName string, setName string) error { if _, exists := ipsMgr.listMap[listName]; !exists { - log.Printf("[Azure-NPM] ipset list with name %s not found", listName) + log.Printf("ipset list with name %s not found", listName) return nil } @@ -164,13 +164,13 @@ func (ipsMgr *IpsetManager) DeleteFromList(listName string, setName string) erro } errCode, err := ipsMgr.Run(entry) if errCode > 1 && err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete ipset entry. %+v", entry) + log.Errorf("Error: failed to delete ipset entry. %+v", entry) return err } if len(ipsMgr.listMap[listName].elements) == 0 { if err := ipsMgr.DeleteList(listName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete ipset list %s.", listName) + log.Errorf("Error: failed to delete ipset list %s.", listName) return err } } @@ -191,9 +191,9 @@ func (ipsMgr *IpsetManager) CreateSet(setName string) error { set: util.GetHashedName(setName), spec: util.IpsetNetHashFlag, } - log.Printf("[Azure-NPM] Creating Set: %+v", entry) + log.Printf("Creating Set: %+v", entry) if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset.") + log.Errorf("Error: failed to create ipset.") return err } @@ -205,7 +205,7 @@ func (ipsMgr *IpsetManager) CreateSet(setName string) error { // DeleteSet removes a set from ipset. func (ipsMgr *IpsetManager) DeleteSet(setName string) error { if _, exists := ipsMgr.setMap[setName]; !exists { - log.Printf("[Azure-NPM] ipset with name %s not found", setName) + log.Printf("ipset with name %s not found", setName) return nil } @@ -220,11 +220,11 @@ func (ipsMgr *IpsetManager) DeleteSet(setName string) error { errCode, err := ipsMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("[Azure-NPM] Cannot delete set %s as it's being referred.", setName) + log.Printf("Cannot delete set %s as it's being referred.", setName) return nil } - log.Errorf("[Azure-NPM] Error: failed to delete ipset %s. Entry: %+v", setName, entry) + log.Errorf("Error: failed to delete ipset %s. Entry: %+v", setName, entry) return err } @@ -250,7 +250,7 @@ func (ipsMgr *IpsetManager) AddToSet(setName string, ip string) error { } if _, err := ipsMgr.Run(entry); err != nil { - log.Printf("[Azure-NPM] Error: failed to create ipset rules. %+v", entry) + log.Printf("Error: failed to create ipset rules. %+v", entry) return err } @@ -262,7 +262,7 @@ func (ipsMgr *IpsetManager) AddToSet(setName string, ip string) error { // DeleteFromSet removes an ip from an entry in setMap, and delete/update the corresponding ipset. func (ipsMgr *IpsetManager) DeleteFromSet(setName string, ip string) error { if _, exists := ipsMgr.setMap[setName]; !exists { - log.Printf("[Azure-NPM] ipset with name %s not found", setName) + log.Printf("ipset with name %s not found", setName) return nil } @@ -278,7 +278,7 @@ func (ipsMgr *IpsetManager) DeleteFromSet(setName string, ip string) error { spec: ip, } if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete ipset entry. Entry: %+v", entry) + log.Errorf("Error: failed to delete ipset entry. Entry: %+v", entry) return err } @@ -293,7 +293,7 @@ func (ipsMgr *IpsetManager) Clean() error { } if err := ipsMgr.DeleteSet(setName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to clean ipset") + log.Errorf("Error: failed to clean ipset") return err } } @@ -304,7 +304,7 @@ func (ipsMgr *IpsetManager) Clean() error { } if err := ipsMgr.DeleteList(listName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to clean ipset list") + log.Errorf("Error: failed to clean ipset list") return err } } @@ -318,13 +318,13 @@ func (ipsMgr *IpsetManager) Destroy() error { operationFlag: util.IpsetFlushFlag, } if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to flush ipset") + log.Errorf("Error: failed to flush ipset") return err } entry.operationFlag = util.IpsetDestroyFlag if _, err := ipsMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to destroy ipset") + log.Errorf("Error: failed to destroy ipset") return err } @@ -342,12 +342,12 @@ func (ipsMgr *IpsetManager) Run(entry *ipsEntry) (int, error) { cmdArgs = append(cmdArgs, entry.spec) } - log.Printf("[Azure-NPM] Executing ipset command %s %v", cmdName, cmdArgs) + log.Printf("Executing ipset command %s %v", cmdName, cmdArgs) _, err := exec.Command(cmdName, cmdArgs...).Output() if msg, failed := err.(*exec.ExitError); failed { errCode := msg.Sys().(syscall.WaitStatus).ExitStatus() if errCode > 1 { - log.Errorf("[Azure-NPM] Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) + log.Errorf("Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) } return errCode, err @@ -364,7 +364,7 @@ func (ipsMgr *IpsetManager) Save(configFile string) error { cmd := exec.Command(util.Ipset, util.IpsetSaveFlag, util.IpsetFileFlag, configFile) if err := cmd.Start(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to save ipset to file.") + log.Errorf("Error: failed to save ipset to file.") return err } cmd.Wait() @@ -380,7 +380,7 @@ func (ipsMgr *IpsetManager) Restore(configFile string) error { f, err := os.Stat(configFile) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to get file %s stat from ipsm.Restore", configFile) + log.Errorf("Error: failed to get file %s stat from ipsm.Restore", configFile) return err } @@ -392,7 +392,7 @@ func (ipsMgr *IpsetManager) Restore(configFile string) error { cmd := exec.Command(util.Ipset, util.IpsetRestoreFlag, util.IpsetFileFlag, configFile) if err := cmd.Start(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to restore ipset from file.") + log.Errorf("Error: failed to restore ipset from file.") return err } cmd.Wait() diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 5b254fba51..ff12e413e2 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -50,7 +50,7 @@ func NewIptablesManager() *IptablesManager { // InitNpmChains initializes Azure NPM chains in iptables. func (iptMgr *IptablesManager) InitNpmChains() error { - log.Printf("[Azure-NPM] Initializing AZURE-NPM chains.") + log.Printf("Initializing AZURE-NPM chains.") if err := iptMgr.AddChain(util.IptablesAzureChain); err != nil { return err @@ -72,7 +72,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err = iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM chain to FORWARD chain.") + log.Errorf("Error: failed to add AZURE-NPM chain to FORWARD chain.") return err } } @@ -95,7 +95,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err = iptMgr.Run(entry); err != nil { - log.Printf("[Azure-NPM] Error: failed to add default allow CONNECTED/RELATED rule to AZURE-NPM chain.") + log.Printf("Error: failed to add default allow CONNECTED/RELATED rule to AZURE-NPM chain.") return err } } @@ -116,7 +116,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain.") + log.Errorf("Error: failed to add AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain.") return err } } @@ -147,7 +147,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-EGRESS-PORT chain to AZURE-NPM chain.") + log.Errorf("Error: failed to add AZURE-NPM-EGRESS-PORT chain to AZURE-NPM chain.") return err } } @@ -178,7 +178,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain.") + log.Errorf("Error: failed to add AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain.") return err } } @@ -210,7 +210,7 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { iptMgr.OperationFlag = util.IptablesDeletionFlag errCode, err := iptMgr.Run(entry) if errCode != 1 && err != nil { - log.Errorf("[Azure-NPM] Error: failed to remove default rule from FORWARD chain.") + log.Errorf("Error: failed to remove default rule from FORWARD chain.") return err } @@ -220,7 +220,7 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { Chain: chain, } if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to flush iptables chain %s.", chain) + log.Errorf("Error: failed to flush iptables chain %s.", chain) } } @@ -238,12 +238,12 @@ func (iptMgr *IptablesManager) Exists(entry *IptEntry) (bool, error) { iptMgr.OperationFlag = util.IptablesCheckFlag returnCode, err := iptMgr.Run(entry) if err == nil { - log.Printf("[Azure-NPM] Rule exists. %+v.", entry) + log.Printf("Rule exists. %+v.", entry) return true, nil } if returnCode == 1 { - log.Printf("[Azure-NPM] Rule doesn't exist. %+v.", entry) + log.Printf("Rule doesn't exist. %+v.", entry) return false, nil } @@ -259,11 +259,11 @@ func (iptMgr *IptablesManager) AddChain(chain string) error { errCode, err := iptMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("[Azure-NPM] Chain already exists %s.", entry.Chain) + log.Printf("Chain already exists %s.", entry.Chain) return nil } - log.Errorf("[Azure-NPM] Error: failed to create iptables chain %s.", entry.Chain) + log.Errorf("Error: failed to create iptables chain %s.", entry.Chain) return err } @@ -279,10 +279,10 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { errCode, err := iptMgr.Run(entry) if err != nil { if errCode == 1 { - log.Printf("[Azure-NPM] Chain doesn't exist %s.", entry.Chain) + log.Printf("Chain doesn't exist %s.", entry.Chain) return nil } - log.Errorf("[Azure-NPM] Error: failed to delete iptables chain %s.", entry.Chain) + log.Errorf("Error: failed to delete iptables chain %s.", entry.Chain) return err } @@ -291,7 +291,7 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { // Add adds a rule in iptables. func (iptMgr *IptablesManager) Add(entry *IptEntry) error { - log.Printf("[Azure-NPM] Add iptables entry: %+v.", entry) + log.Printf("Add iptables entry: %+v.", entry) exists, err := iptMgr.Exists(entry) if err != nil { @@ -304,7 +304,7 @@ func (iptMgr *IptablesManager) Add(entry *IptEntry) error { iptMgr.OperationFlag = util.IptablesInsertionFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create iptables rules.") + log.Errorf("Error: failed to create iptables rules.") return err } @@ -313,7 +313,7 @@ func (iptMgr *IptablesManager) Add(entry *IptEntry) error { // Delete removes a rule in iptables. func (iptMgr *IptablesManager) Delete(entry *IptEntry) error { - log.Printf("[Azure-NPM] Deleting iptables entry: %+v", entry) + log.Printf("Deleting iptables entry: %+v", entry) exists, err := iptMgr.Exists(entry) if err != nil { @@ -326,7 +326,7 @@ func (iptMgr *IptablesManager) Delete(entry *IptEntry) error { iptMgr.OperationFlag = util.IptablesDeletionFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete iptables rules.") + log.Errorf("Error: failed to delete iptables rules.") return err } @@ -345,13 +345,13 @@ func (iptMgr *IptablesManager) Run(entry *IptEntry) (int, error) { } cmdArgs := append([]string{util.IptablesWaitFlag, entry.LockWaitTimeInSeconds, iptMgr.OperationFlag, entry.Chain}, entry.Specs...) - log.Printf("[Azure-NPM] Executing iptables command %s %v", cmdName, cmdArgs) + log.Printf("Executing iptables command %s %v", cmdName, cmdArgs) _, err := exec.Command(cmdName, cmdArgs...).Output() if msg, failed := err.(*exec.ExitError); failed { errCode := msg.Sys().(syscall.WaitStatus).ExitStatus() if errCode > 1 { - log.Errorf("[Azure-NPM] Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) + log.Errorf("Error: There was an error running command: %s %s Arguments:%v", err, cmdName, cmdArgs) } return errCode, err @@ -373,14 +373,14 @@ func (iptMgr *IptablesManager) Save(configFile string) error { defer func(l *os.File) { if err = l.Close(); err != nil { - log.Printf("[Azure-NPM] Failed to close iptables locks") + log.Printf("Failed to close iptables locks") } }(l) // create the config file for writing f, err := os.Create(configFile) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to open file: %s.", configFile) + log.Errorf("Error: failed to open file: %s.", configFile) return err } defer f.Close() @@ -388,7 +388,7 @@ func (iptMgr *IptablesManager) Save(configFile string) error { cmd := exec.Command(util.IptablesSave) cmd.Stdout = f if err := cmd.Start(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to run iptables-save.") + log.Errorf("Error: failed to run iptables-save.") return err } cmd.Wait() @@ -409,14 +409,14 @@ func (iptMgr *IptablesManager) Restore(configFile string) error { defer func(l *os.File) { if err = l.Close(); err != nil { - log.Printf("[Azure-NPM] Failed to close iptables locks") + log.Printf("Failed to close iptables locks") } }(l) // open the config file for reading f, err := os.Open(configFile) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to open file: %s.", configFile) + log.Errorf("Error: failed to open file: %s.", configFile) return err } defer f.Close() @@ -424,7 +424,7 @@ func (iptMgr *IptablesManager) Restore(configFile string) error { cmd := exec.Command(util.IptablesRestore) cmd.Stdin = f if err := cmd.Start(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to run iptables-restore.") + log.Errorf("Error: failed to run iptables-restore.") return err } cmd.Wait() @@ -447,7 +447,7 @@ func grabIptablesLocks() (*os.File, error) { // Grab 1.6.x style lock. l, err := os.OpenFile(util.IptablesLockFile, os.O_CREATE, 0600) if err != nil { - log.Printf("[Azure-NPM] Error: failed to open iptables lock file %s.", util.IptablesLockFile) + log.Printf("Error: failed to open iptables lock file %s.", util.IptablesLockFile) return nil, err } @@ -458,7 +458,7 @@ func grabIptablesLocks() (*os.File, error) { return true, nil }); err != nil { - log.Printf("[Azure-NPM] Error: failed to acquire new iptables lock: %v.", err) + log.Printf("Error: failed to acquire new iptables lock: %v.", err) return nil, err } diff --git a/npm/namespace.go b/npm/namespace.go index d44b1c949e..d0af0d6528 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -49,7 +49,7 @@ func (npMgr *NetworkPolicyManager) InitAllNsList() error { } if err := allNs.ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add namespace set %s to list %s", nsName, util.KubeAllNamespacesFlag) + log.Errorf("Error: failed to add namespace set %s to list %s", nsName, util.KubeAllNamespacesFlag) return err } } @@ -66,7 +66,7 @@ func (npMgr *NetworkPolicyManager) UninitAllNsList() error { } if err := allNs.ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete namespace set %s from list %s", nsName, util.KubeAllNamespacesFlag) + log.Errorf("Error: failed to delete namespace set %s from list %s", nsName, util.KubeAllNamespacesFlag) return err } } @@ -82,17 +82,17 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var err error nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("[Azure-NPM] NAMESPACE CREATING: [%s/%s/%+v]", nsName, nsNs, nsLabel) + log.Printf("NAMESPACE CREATING: [%s/%s/%+v]", nsName, nsNs, nsLabel) ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Create ipset for the namespace. if err = ipsMgr.CreateSet(nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset for namespace %s.", nsName) + log.Errorf("Error: failed to create ipset for namespace %s.", nsName) return err } if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add %s to all-namespace ipset list.", nsName) + log.Errorf("Error: failed to add %s to all-namespace ipset list.", nsName) return err } @@ -101,9 +101,9 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) - log.Printf("[Azure-NPM] Adding namespace %s to ipset list %s", nsName, labelKey) + log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) if err = ipsMgr.AddToList(labelKey, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add namespace %s to ipset list %s", nsName, labelKey) + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) return err } labelKeys = append(labelKeys, labelKey) @@ -111,7 +111,7 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { ns, err := newNs(nsName) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to create namespace %s", nsName) + log.Errorf("Error: failed to create namespace %s", nsName) } npMgr.nsMap[nsName] = ns @@ -125,7 +125,7 @@ func (npMgr *NetworkPolicyManager) UpdateNamespace(oldNsObj *corev1.Namespace, n oldNsName, oldNsNs, oldNsLabel := oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels newNsName, newNsNs, newNsLabel := newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels log.Printf( - "[Azure-NPM] NAMESPACE UPDATING:\n old namespace: [%s/%s/%+v]\n new namespace: [%s/%s/%+v]", + "NAMESPACE UPDATING:\n old namespace: [%s/%s/%+v]\n new namespace: [%s/%s/%+v]", oldNsName, oldNsNs, oldNsLabel, newNsName, newNsNs, newNsLabel, ) @@ -150,7 +150,7 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var err error nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("[Azure-NPM] NAMESPACE DELETING: [%s/%s/%+v]", nsName, nsNs, nsLabel) + log.Printf("NAMESPACE DELETING: [%s/%s/%+v]", nsName, nsNs, nsLabel) _, exists := npMgr.nsMap[nsName] if !exists { @@ -163,9 +163,9 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) - log.Printf("[Azure-NPM] Deleting namespace %s from ipset list %s", nsName, labelKey) + log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) return err } labelKeys = append(labelKeys, labelKey) @@ -173,13 +173,13 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro // Delete the namespace from all-namespace ipset list. if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete namespace %s from ipset list %s", nsName, util.KubeAllNamespacesFlag) + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, util.KubeAllNamespacesFlag) return err } // Delete ipset for the namespace. if err = ipsMgr.DeleteSet(nsName); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete ipset for namespace %s.", nsName) + log.Errorf("Error: failed to delete ipset for namespace %s.", nsName) return err } diff --git a/npm/npm.go b/npm/npm.go index 10b57c6d5a..404e9c59eb 100644 --- a/npm/npm.go +++ b/npm/npm.go @@ -61,17 +61,17 @@ type NetworkPolicyManager struct { func (npMgr *NetworkPolicyManager) GetClusterState() telemetry.ClusterState { pods, err := npMgr.clientset.CoreV1().Pods("").List(metav1.ListOptions{}) if err != nil { - log.Logf("[Azure-NPM] Error: Failed to list pods in GetClusterState") + log.Logf("Error: Failed to list pods in GetClusterState") } namespaces, err := npMgr.clientset.CoreV1().Namespaces().List(metav1.ListOptions{}) if err != nil { - log.Logf("[Azure-NPM] Error: Failed to list namespaces in GetClusterState") + log.Logf("Error: Failed to list namespaces in GetClusterState") } networkpolicies, err := npMgr.clientset.NetworkingV1().NetworkPolicies("").List(metav1.ListOptions{}) if err != nil { - log.Logf("[Azure-NPM] Error: Failed to list networkpolicies in GetClusterState") + log.Logf("Error: Failed to list networkpolicies in GetClusterState") } npMgr.clusterState.PodCount = len(pods.Items) @@ -122,13 +122,13 @@ CONNECT: report, err := npMgr.reportManager.ReportToBytes() if err != nil { - log.Logf("[Azure-NPM] ReportToBytes failed: %v", err) + log.Logf("ReportToBytes failed: %v", err) continue } // If write fails, try to re-establish connections as server/client if _, err = tb.Write(report); err != nil { - log.Logf("[Azure-NPM] Telemetry write failed: %v", err) + log.Logf("Telemetry write failed: %v", err) tb.Close() goto CONNECT } @@ -147,7 +147,7 @@ func (npMgr *NetworkPolicyManager) restore() { time.Sleep(restoreRetryWaitTimeInSeconds * time.Second) } - log.Logf("[Azure-NPM] Error: timeout restoring Azure-NPM states") + log.Logf("Error: timeout restoring Azure-NPM states") panic(err.Error) } @@ -159,7 +159,7 @@ func (npMgr *NetworkPolicyManager) backup() { time.Sleep(backupWaitTimeInSeconds * time.Second) if err = iptMgr.Save(util.IptablesConfigFile); err != nil { - log.Logf("[Azure-NPM] Error: failed to back up Azure-NPM states") + log.Logf("Error: failed to back up Azure-NPM states") } } } @@ -201,13 +201,13 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in serverVersion, err := clientset.ServerVersion() if err != nil { - log.Logf("[Azure-NPM] Error: failed to retrieving kubernetes version") + log.Logf("Error: failed to retrieving kubernetes version") panic(err.Error) } - log.Logf("[Azure-NPM] API server version: %+v", serverVersion) + log.Logf("API server version: %+v", serverVersion) if err = util.SetIsNewNwPolicyVerFlag(serverVersion); err != nil { - log.Logf("[Azure-NPM] Error: failed to set IsNewNwPolicyVerFlag") + log.Logf("Error: failed to set IsNewNwPolicyVerFlag") panic(err.Error) } @@ -245,7 +245,7 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in allNs, err := newNs(util.KubeAllNamespacesFlag) if err != nil { - log.Logf("[Azure-NPM] Error: failed to create all-namespace.") + log.Logf("Error: failed to create all-namespace.") panic(err.Error) } npMgr.nsMap[util.KubeAllNamespacesFlag] = allNs diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 64313ad387..cd5a27bd94 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -16,18 +16,18 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP var err error npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name - log.Printf("[Azure-NPM] NETWORK POLICY CREATING: %v", npObj) + log.Printf("NETWORK POLICY CREATING: %v", npObj) allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] if !npMgr.isAzureNpmChainCreated { if err = allNs.ipsMgr.CreateSet(util.KubeSystemFlag); err != nil { - log.Errorf("[Azure-NPM] Error: failed to initialize kube-system ipset.") + log.Errorf("Error: failed to initialize kube-system ipset.") return err } if err = allNs.iptMgr.InitNpmChains(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to initialize azure-npm chains.") + log.Errorf("Error: failed to initialize azure-npm chains.") return err } @@ -39,27 +39,27 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ipsMgr := allNs.ipsMgr for _, set := range podSets { if err = ipsMgr.CreateSet(set); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset %s-%s", npNs, set) + log.Errorf("Error: failed to create ipset %s-%s", npNs, set) return err } } for _, list := range nsLists { if err = ipsMgr.CreateList(list); err != nil { - log.Errorf("[Azure-NPM] Error: failed to create ipset list %s-%s", npNs, list) + log.Errorf("Error: failed to create ipset list %s-%s", npNs, list) return err } } if err = npMgr.InitAllNsList(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to initialize all-namespace ipset list.") + log.Errorf("Error: failed to initialize all-namespace ipset list.") return err } iptMgr := allNs.iptMgr for _, iptEntry := range iptEntries { if err = iptMgr.Add(iptEntry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to apply iptables rule. Rule: %+v", iptEntry) + log.Errorf("Error: failed to apply iptables rule. Rule: %+v", iptEntry) return err } } @@ -68,7 +68,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ns, err := newNs(npNs) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to create namespace %s", npNs) + log.Errorf("Error: failed to create namespace %s", npNs) } npMgr.nsMap[npNs] = ns @@ -79,7 +79,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP func (npMgr *NetworkPolicyManager) UpdateNetworkPolicy(oldNpObj *networkingv1.NetworkPolicy, newNpObj *networkingv1.NetworkPolicy) error { var err error - log.Printf("[Azure-NPM] NETWORK POLICY UPDATING:\n old policy:[%v]\n new policy:[%v]", oldNpObj, newNpObj) + log.Printf("NETWORK POLICY UPDATING:\n old policy:[%v]\n new policy:[%v]", oldNpObj, newNpObj) if err = npMgr.DeleteNetworkPolicy(oldNpObj); err != nil { return err @@ -102,7 +102,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo var err error npName := npObj.ObjectMeta.Name - log.Printf("[Azure-NPM] NETWORK POLICY DELETING: %v", npObj) + log.Printf("NETWORK POLICY DELETING: %v", npObj) allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] @@ -111,7 +111,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo iptMgr := allNs.iptMgr for _, iptEntry := range iptEntries { if err = iptMgr.Delete(iptEntry); err != nil { - log.Errorf("[Azure-NPM] Error: failed to apply iptables rule. Rule: %+v", iptEntry) + log.Errorf("Error: failed to apply iptables rule. Rule: %+v", iptEntry) return err } } @@ -120,7 +120,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo if len(allNs.npMap) == 0 { if err = iptMgr.UninitNpmChains(); err != nil { - log.Errorf("[Azure-NPM] Error: failed to uninitialize azure-npm chains.") + log.Errorf("Error: failed to uninitialize azure-npm chains.") return err } npMgr.isAzureNpmChainCreated = false diff --git a/npm/parse.go b/npm/parse.go index 35178887b4..977256c6a8 100644 --- a/npm/parse.go +++ b/npm/parse.go @@ -62,7 +62,7 @@ func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPo // Use hashed string for ipset name to avoid string length limit of ipset. for _, targetSet := range targetSets { - log.Printf("[Azure-NPM] Parsing iptables for label %s", targetSet) + log.Printf("Parsing iptables for label %s", targetSet) hashedTargetSetName := util.GetHashedName(targetSet) @@ -427,7 +427,7 @@ func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPo } } - log.Printf("[Azure-NPM] finished parsing ingress rule") + log.Printf("finished parsing ingress rule") return policyRuleSets, policyRuleLists, entries } @@ -471,7 +471,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol // Use hashed string for ipset name to avoid string length limit of ipset. for _, targetSet := range targetSets { - log.Printf("[Azure-NPM] Parsing iptables for label %s", targetSet) + log.Printf("Parsing iptables for label %s", targetSet) hashedTargetSetName := util.GetHashedName(targetSet) @@ -764,7 +764,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol // Allow traffic from podSelector intersects namespaceSelector // This is only supported in kubernetes version >= 1.11 if util.IsNewNwPolicyVerFlag { - log.Printf("[Azure-NPM] Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") + log.Printf("Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") // allow traffic from all namespaces if len(toRule.NamespaceSelector.MatchLabels) == 0 { nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) @@ -837,7 +837,7 @@ func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPol } } - log.Printf("[Azure-NPM] finished parsing ingress rule") + log.Printf("finished parsing ingress rule") return policyRuleSets, policyRuleLists, entries } diff --git a/npm/plugin/main.go b/npm/plugin/main.go index be52aea16c..1f24059bc7 100644 --- a/npm/plugin/main.go +++ b/npm/plugin/main.go @@ -23,7 +23,7 @@ func initLogging() error { log.SetName("azure-npm") log.SetLevel(log.LevelInfo) if err := log.SetTarget(log.TargetLogfile); err != nil { - log.Logf("[Azure-NPM] Failed to configure logging, err:%v.", err) + log.Logf("Failed to configure logging, err:%v.", err) return err } @@ -35,7 +35,7 @@ func main() { defer func() { if r := recover(); r != nil { - log.Logf("[Azure-NPM] recovered from error: %v", err) + log.Logf("recovered from error: %v", err) } }() @@ -52,7 +52,7 @@ func main() { // Creates the clientset clientset, err := kubernetes.NewForConfig(config) if err != nil { - log.Logf("[Azure-NPM] clientset creation failed with error %v.", err) + log.Logf("clientset creation failed with error %v.", err) panic(err.Error()) } @@ -66,7 +66,7 @@ func main() { err = npMgr.Start(wait.NeverStop) if err != nil { - log.Logf("[Azure-NPM] npm failed with error %v.", err) + log.Logf("npm failed with error %v.", err) panic(err.Error) } diff --git a/npm/pod.go b/npm/pod.go index afbbc31a2d..af35897a9a 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -38,14 +38,14 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels podIP := podObj.Status.PodIP - log.Printf("[Azure-NPM] POD CREATING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) + log.Printf("POD CREATING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) // Add the pod to ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Add the pod to its namespace's ipset. - log.Printf("[Azure-NPM] Adding pod %s to ipset %s", podIP, podNs) + log.Printf("Adding pod %s to ipset %s", podIP, podNs) if err = ipsMgr.AddToSet(podNs, podIP); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add pod to namespace ipset.") + log.Errorf("Error: failed to add pod to namespace ipset.") return err } @@ -58,9 +58,9 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { } labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - log.Printf("[Azure-NPM] Adding pod %s to ipset %s", podIP, labelKey) + log.Printf("Adding pod %s to ipset %s", podIP, labelKey) if err = ipsMgr.AddToSet(labelKey, podIP); err != nil { - log.Errorf("[Azure-NPM] Error: failed to add pod to label ipset.") + log.Errorf("Error: failed to add pod to label ipset.") return err } labelKeys = append(labelKeys, labelKey) @@ -68,7 +68,7 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { ns, err := newNs(podNs) if err != nil { - log.Errorf("[Azure-NPM] Error: failed to create namespace %s", podNs) + log.Errorf("Error: failed to create namespace %s", podNs) return err } npMgr.nsMap[podNs] = ns @@ -96,7 +96,7 @@ func (npMgr *NetworkPolicyManager) UpdatePod(oldPodObj, newPodObj *corev1.Pod) e newPodObjIP := newPodObj.Status.PodIP log.Printf( - "[Azure-NPM] POD UPDATING:\n old pod: [%s/%s/%+v/%s/%s]\n new pod: [%s/%s/%+v/%s/%s]", + "POD UPDATING:\n old pod: [%s/%s/%+v/%s/%s]\n new pod: [%s/%s/%+v/%s/%s]", oldPodObjNs, oldPodObjName, oldPodObjLabel, oldPodObjPhase, oldPodObjIP, newPodObjNs, newPodObjName, newPodObjLabel, newPodObjPhase, newPodObjIP, ) @@ -130,13 +130,13 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels podIP := podObj.Status.PodIP - log.Printf("[Azure-NPM] POD DELETING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) + log.Printf("POD DELETING: [%s/%s/%s%+v%s]", podNs, podName, podNodeName, podLabels, podIP) // Delete pod from ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Delete the pod from its namespace's ipset. if err = ipsMgr.DeleteFromSet(podNs, podIP); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete pod from namespace ipset.") + log.Errorf("Error: failed to delete pod from namespace ipset.") return err } // Delete the pod from its label's ipset. @@ -148,7 +148,7 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal if err = ipsMgr.DeleteFromSet(labelKey, podIP); err != nil { - log.Errorf("[Azure-NPM] Error: failed to delete pod from label ipset.") + log.Errorf("Error: failed to delete pod from label ipset.") return err } } From 44e5f0728806f34563b626b6ca8fd78112f4d3d5 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Wed, 12 Jun 2019 12:20:28 -0700 Subject: [PATCH 21/64] remove npmreport url --- npm/namespace_test.go | 15 ++++++--------- npm/npm.go | 6 ++---- npm/nwpolicy_test.go | 3 --- npm/pod_test.go | 15 ++++++--------- 4 files changed, 14 insertions(+), 25 deletions(-) diff --git a/npm/namespace_test.go b/npm/namespace_test.go index d4906dd68c..a446ad70d8 100644 --- a/npm/namespace_test.go +++ b/npm/namespace_test.go @@ -48,9 +48,8 @@ func TestAddNamespace(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } @@ -90,9 +89,8 @@ func TestUpdateNamespace(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } @@ -145,9 +143,8 @@ func TestDeleteNamespace(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } diff --git a/npm/npm.go b/npm/npm.go index 404e9c59eb..fdab95e5c0 100644 --- a/npm/npm.go +++ b/npm/npm.go @@ -25,7 +25,6 @@ import ( ) const ( - hostNetAgentURLForNpm = "http://168.63.129.16/machine/plugins?comp=netagent&type=npmreport" restoreRetryWaitTimeInSeconds = 5 restoreMaxRetries = 10 backupWaitTimeInSeconds = 60 @@ -226,9 +225,8 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in NwPolicyCount: 0, }, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, serverVersion: serverVersion, TelemetryEnabled: true, diff --git a/npm/nwpolicy_test.go b/npm/nwpolicy_test.go index 2e564649de..1a2445929b 100644 --- a/npm/nwpolicy_test.go +++ b/npm/nwpolicy_test.go @@ -21,7 +21,6 @@ func TestAddNetworkPolicy(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, @@ -101,7 +100,6 @@ func TestUpdateNetworkPolicy(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, @@ -209,7 +207,6 @@ func TestDeleteNetworkPolicy(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, ContentType: telemetry.ContentType, Report: &telemetry.NPMReport{}, }, diff --git a/npm/pod_test.go b/npm/pod_test.go index 716621997c..0d9441d972 100644 --- a/npm/pod_test.go +++ b/npm/pod_test.go @@ -40,9 +40,8 @@ func TestAddPod(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } @@ -85,9 +84,8 @@ func TestUpdatePod(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } @@ -148,9 +146,8 @@ func TestDeletePod(t *testing.T) { nsMap: make(map[string]*namespace), TelemetryEnabled: false, reportManager: &telemetry.ReportManager{ - HostNetAgentURL: hostNetAgentURLForNpm, - ContentType: telemetry.ContentType, - Report: &telemetry.NPMReport{}, + ContentType: telemetry.ContentType, + Report: &telemetry.NPMReport{}, }, } From 7c821ed998c0b7ccc18f6613ef3285f219d8ccbe Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Mon, 17 Jun 2019 15:48:54 -0700 Subject: [PATCH 22/64] fair scheduling --- telemetry/telemetrybuffer.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/telemetry/telemetrybuffer.go b/telemetry/telemetrybuffer.go index 2417c5ebba..52878470ef 100644 --- a/telemetry/telemetrybuffer.go +++ b/telemetry/telemetrybuffer.go @@ -9,10 +9,12 @@ import ( "encoding/json" "fmt" "io/ioutil" + "math/rand" "net" "net/http" "os" "path/filepath" + "reflect" "strings" "sync" "time" @@ -282,7 +284,9 @@ func (tb *TelemetryBuffer) sendToHost() error { NPMReports: make([]NPMReport, 0), CNSReports: make([]CNSReport, 0), } - i, payloadSize, maxPayloadSizeReached := 0, 0, false + + seed := rand.NewSource(time.Now().UnixNano()) + i, payloadSize, maxPayloadSizeReached := rand.New(seed).Intn(reflect.ValueOf(&buf).Elem().NumField()), 0, false isDNCReportsEmpty, isCNIReportsEmpty, isCNSReportsEmpty, isNPMReportsEmpty := false, false, false, false for { // craft payload in a round-robin manner. From 90452882db182fd746b03263bca8f318fcb8fe55 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 18 Jun 2019 11:46:11 -0700 Subject: [PATCH 23/64] holds up to 1k reports for each type --- telemetry/telemetrybuffer.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/telemetry/telemetrybuffer.go b/telemetry/telemetrybuffer.go index 52878470ef..55bae233a3 100644 --- a/telemetry/telemetrybuffer.go +++ b/telemetry/telemetrybuffer.go @@ -84,10 +84,10 @@ func NewTelemetryBuffer(hostReportURL string) *TelemetryBuffer { tb.data = make(chan interface{}, 1000) tb.cancel = make(chan bool, 1) tb.connections = make([]net.Conn, 0) - tb.buffer.DNCReports = make([]DNCReport, 0) - tb.buffer.CNIReports = make([]CNIReport, 0) - tb.buffer.NPMReports = make([]NPMReport, 0) - tb.buffer.CNSReports = make([]CNSReport, 0) + tb.buffer.DNCReports = make([]DNCReport, 1000) + tb.buffer.CNIReports = make([]CNIReport, 1000) + tb.buffer.NPMReports = make([]NPMReport, 1000) + tb.buffer.CNSReports = make([]CNSReport, 1000) return &tb } From 5aa60e96a0ba8adaa1bae756860bfc3f3587634f Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 18 Jun 2019 14:38:19 -0700 Subject: [PATCH 24/64] fix cap on reports --- telemetry/telemetrybuffer.go | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/telemetry/telemetrybuffer.go b/telemetry/telemetrybuffer.go index 55bae233a3..adfca234b7 100644 --- a/telemetry/telemetrybuffer.go +++ b/telemetry/telemetrybuffer.go @@ -42,7 +42,7 @@ const ( minInterval = 10 * time.Second logName = "azure-vnet-telemetry" MaxPayloadSize = 4096 - MaxBufferSize = 1048576 + MaxNumReports = 1000 dnc = "DNC" cns = "CNS" npm = "NPM" @@ -81,13 +81,13 @@ func NewTelemetryBuffer(hostReportURL string) *TelemetryBuffer { tb.azureHostReportURL = azureHostReportURL } - tb.data = make(chan interface{}, 1000) + tb.data = make(chan interface{}, MaxNumReports) tb.cancel = make(chan bool, 1) tb.connections = make([]net.Conn, 0) - tb.buffer.DNCReports = make([]DNCReport, 1000) - tb.buffer.CNIReports = make([]CNIReport, 1000) - tb.buffer.NPMReports = make([]NPMReport, 1000) - tb.buffer.CNSReports = make([]CNSReport, 1000) + tb.buffer.DNCReports = make([]DNCReport, 0, MaxNumReports) + tb.buffer.CNIReports = make([]CNIReport, 0, MaxNumReports) + tb.buffer.NPMReports = make([]NPMReport, 0, MaxNumReports) + tb.buffer.CNSReports = make([]CNSReport, 0, MaxNumReports) return &tb } @@ -423,18 +423,30 @@ func (buf *Buffer) push(x interface{}) { switch x.(type) { case DNCReport: + if len(buf.DNCReports) >= MaxNumReports { + return + } dncReport := x.(DNCReport) dncReport.Metadata = metadata buf.DNCReports = append(buf.DNCReports, dncReport) case CNIReport: + if len(buf.CNIReports) >= MaxNumReports { + return + } cniReport := x.(CNIReport) cniReport.Metadata = metadata buf.CNIReports = append(buf.CNIReports, cniReport) case NPMReport: + if len(buf.NPMReports) >= MaxNumReports { + return + } npmReport := x.(NPMReport) npmReport.Metadata = metadata buf.NPMReports = append(buf.NPMReports, npmReport) case CNSReport: + if len(buf.CNSReports) >= MaxNumReports { + return + } cnsReport := x.(CNSReport) cnsReport.Metadata = metadata buf.CNSReports = append(buf.CNSReports, cnsReport) From 7571856737438e67522f169eed134799fed615f7 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 20 Jun 2019 15:04:05 -0700 Subject: [PATCH 25/64] rename const --- npm/iptm/iptm.go | 2 +- npm/translatePolicy.go | 41 ++++++++++++++++++----- npm/util/const.go | 75 ++++++++++++++++++++++-------------------- 3 files changed, 73 insertions(+), 45 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index ff12e413e2..7c252bc15f 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -81,8 +81,8 @@ func (iptMgr *IptablesManager) InitNpmChains() error { entry.Chain = util.IptablesAzureChain entry.Specs = []string{ util.IptablesMatchFlag, + util.IptablesStateModuleFlag, util.IptablesStateFlag, - util.IptablesMatchStateFlag, util.IptablesRelatedState + "," + util.IptablesEstablishedState, util.IptablesJumpFlag, util.IptablesAccept, diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 544dce7371..ed285308d9 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -32,8 +32,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne label := labels[i] log.Printf("Parsing iptables for label %s", label) - //hashedLabelName := util.GetHashedName(label) - + hashedLabelName := util.GetHashedName(label) for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -56,9 +55,35 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } } - // TODO if !portRuleExists && !fromRuleExists { - break + entry := &iptm.IptEntry{ + Name: "allow-all-to-"+label, + HashedName:hashedLabelName, + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesMatchFlag, + util.IptablesCommentFlag, + + } + } + entries = append(entries, entry) + continue + } + + if !fromRuleExists { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Name: "allow-to-ports-of-"+label, + HashedName: + } + } } } } @@ -85,12 +110,12 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesMatchFlag, - util.IptablesSetFlag, + util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedKubeSystemSet, util.IptablesSrcFlag, util.IptablesMatchFlag, - util.IptablesSetFlag, + util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, @@ -106,12 +131,12 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ Chain: util.IptablesAzureEgressPortChain, Specs: []string{ util.IptablesMatchFlag, - util.IptablesSetFlag, + util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesSrcFlag, util.IptablesMatchFlag, - util.IptablesSetFlag, + util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedKubeSystemSet, util.IptablesDstFlag, diff --git a/npm/util/const.go b/npm/util/const.go index 3c7e52b1b4..462cda62a2 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -21,42 +21,45 @@ const ( //iptables related constants. const ( - Iptables string = "iptables" - Ip6tables string = "ip6tables" - IptablesSave string = "iptables-save" - IptablesRestore string = "iptables-restore" - IptablesConfigFile string = "/var/log/iptables.conf" - IptablesTestConfigFile string = "/var/log/iptables-test.conf" - IptablesLockFile string = "/run/xtables.lock" - IptablesChainCreationFlag string = "-N" - IptablesInsertionFlag string = "-I" - IptablesAppendFlag string = "-A" - IptablesDeletionFlag string = "-D" - IptablesFlushFlag string = "-F" - IptablesCheckFlag string = "-C" - IptablesDestroyFlag string = "-X" - IptablesJumpFlag string = "-j" - IptablesWaitFlag string = "-w" - IptablesAccept string = "ACCEPT" - IptablesReject string = "REJECT" - IptablesDrop string = "DROP" - IptablesSrcFlag string = "src" - IptablesDstFlag string = "dst" - IptablesNotFlag string = "!" - IptablesProtFlag string = "-p" - IptablesSFlag string = "-s" - IptablesDFlag string = "-d" - IptablesDstPortFlag string = "--dport" - IptablesMatchFlag string = "-m" - IptablesSetFlag string = "set" - IptablesMatchSetFlag string = "--match-set" - IptablesStateFlag string = "state" - IptablesMatchStateFlag string = "--state" - IptablesMultiportFlag string = "multiport" - IptablesMultiDestportFlag string = "--dports" - IptablesRelatedState string = "RELATED" - IptablesEstablishedState string = "ESTABLISHED" - IptablesFilterTable string = "filter" + Iptables string = "iptables" + Ip6tables string = "ip6tables" + IptablesSave string = "iptables-save" + IptablesRestore string = "iptables-restore" + IptablesConfigFile string = "/var/log/iptables.conf" + IptablesTestConfigFile string = "/var/log/iptables-test.conf" + IptablesLockFile string = "/run/xtables.lock" + IptablesChainCreationFlag string = "-N" + IptablesInsertionFlag string = "-I" + IptablesAppendFlag string = "-A" + IptablesDeletionFlag string = "-D" + IptablesFlushFlag string = "-F" + IptablesCheckFlag string = "-C" + IptablesDestroyFlag string = "-X" + IptablesJumpFlag string = "-j" + IptablesWaitFlag string = "-w" + IptablesAccept string = "ACCEPT" + IptablesReject string = "REJECT" + IptablesDrop string = "DROP" + IptablesSrcFlag string = "src" + IptablesDstFlag string = "dst" + IptablesNotFlag string = "!" + IptablesProtFlag string = "-p" + IptablesSFlag string = "-s" + IptablesDFlag string = "-d" + IptablesDstPortFlag string = "--dport" + IptablesMatchFlag string = "-m" + IptablesSetModuleFlag string = "set" + IptablesMatchSetFlag string = "--match-set" + IptablesStateModuleFlag string = "state" + IptablesStateFlag string = "--state" + IptablesMultiportFlag string = "multiport" + IptablesMultiDestportFlag string = "--dports" + IptablesRelatedState string = "RELATED" + IptablesEstablishedState string = "ESTABLISHED" + IptablesFilterTable string = "filter" + IptablesCommentModuleFlag string = "comment" + IptablesCommentFlag string = "--comment" + IptablesAddCommentFlag IptablesAzureChain string = "AZURE-NPM" IptablesAzureIngressPortChain string = "AZURE-NPM-INGRESS-PORT" IptablesAzureIngressFromChain string = "AZURE-NPM-INGRESS-FROM" From 5441b4c0f9b203f6f713cc769912e834171e639a Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 20 Jun 2019 15:12:34 -0700 Subject: [PATCH 26/64] handle ingress port rules --- npm/translatePolicy.go | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index ed285308d9..87559909d2 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -81,10 +81,28 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ Name: "allow-to-ports-of-"+label, - HashedName: + HashedName: hashedLabelName, + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + } } + entries = append(entries, entry) } + continue } + + //TODO: !portRuleExists } } From 556f1a4da2ed4ed956bf89989aa84b11a2e4b512 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 20 Jun 2019 15:13:17 -0700 Subject: [PATCH 27/64] add comma --- npm/translatePolicy.go | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 87559909d2..0969e4417a 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -57,9 +57,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !portRuleExists && !fromRuleExists { entry := &iptm.IptEntry{ - Name: "allow-all-to-"+label, - HashedName:hashedLabelName, - Chain: util.IptablesAzureIngressFromChain, + Name: "allow-all-to-" + label, + HashedName: hashedLabelName, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, @@ -70,8 +70,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesAccept, util.IptablesMatchFlag, util.IptablesCommentFlag, - - } + }, } entries = append(entries, entry) continue @@ -80,9 +79,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !fromRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ - Name: "allow-to-ports-of-"+label, + Name: "allow-to-ports-of-" + label, HashedName: hashedLabelName, - Chain: util.IptablesAzureIngressPortChain, + Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesProtFlag, protPortPair.protocol, @@ -95,9 +94,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAzureIngressFromNsChain, - } + }, } - entries = append(entries, entry) + entries = append(entries, entry) } continue } From 5e44b77961c152b8db4c7ab35a02a0d818443d04 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 20 Jun 2019 15:14:11 -0700 Subject: [PATCH 28/64] rename npNs --- npm/nwpolicy.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 784e9b65d9..c58200ff6d 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -155,12 +155,12 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo log.Printf("NETWORK POLICY DELETING: %v", npObj) var exists bool - if ns, exists = npMgr.nsMap[npNs]; !exists { - ns, err = newNs(npNs) + if ns, exists = npMgr.nsMap[npName]; !exists { + ns, err = newNs(npName) if err != nil { - log.Printf("Error creating namespace %s\n", npNs) + log.Printf("Error creating namespace %s\n", npName) } - npMgr.nsMap[npNs] = ns + npMgr.nsMap[npName] = ns } if !ns.policyExists(npObj) { From 1d71e67a990e778f6320cfc5c0b82b14aac919f3 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 20 Jun 2019 16:05:27 -0700 Subject: [PATCH 29/64] handle ipblock --- npm/translatePolicy.go | 47 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 0969e4417a..d2149b1f00 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -101,7 +101,52 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne continue } - //TODO: !portRuleExists + if !portRuleExists { + for _, fromRule := range rule.From { + // Handle IPBlock field of NetworkPolicyPeer + if fromRule.IPBlock != nil { + if len(fromRule.IPBlock.CIDR) > 0 { + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, cidrEntry) + } + + if len(fromRule.IPBlock.Except) > 0 { + for _, except := range fromRule.IPBlock.Except { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedTargetSetName, + util.IptablesDstFlag, + util.IptablesSFlag, + except, + util.IptablesJumpFlag, + util.IptablesDrop, + }, + } + entries = append(entries, entry) + } + } + } + + // Handle podSelector and namespaceSelector + } + } } } From 2c834f40f8fd8a954c0bfc359950cb33c4372be2 Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Thu, 27 Jun 2019 15:49:53 -0700 Subject: [PATCH 30/64] going to remvoe nsChain --- npm/iptm/iptm.go | 1 - npm/translatePolicy.go | 20 +- npm/translatePolicy_test.go | 353 ++++++++++++++++++++++++++++++++++++ 3 files changed, 361 insertions(+), 13 deletions(-) create mode 100644 npm/translatePolicy_test.go diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 7c252bc15f..8f80a7f974 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -27,7 +27,6 @@ const ( type IptEntry struct { Command string Name string - HashedName string Chain string Flag string LockWaitTimeInSeconds string diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index d2149b1f00..f5054fefdf 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -57,9 +57,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !portRuleExists && !fromRuleExists { entry := &iptm.IptEntry{ - Name: "allow-all-to-" + label, - HashedName: hashedLabelName, - Chain: util.IptablesAzureIngressFromChain, + Name: "allow-all-to-" + label, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, @@ -79,9 +78,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !fromRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ - Name: "allow-to-ports-of-" + label, - HashedName: hashedLabelName, - Chain: util.IptablesAzureIngressPortChain, + Name: "allow-to-ports-of-" + label, + Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesProtFlag, protPortPair.protocol, @@ -167,9 +165,8 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ for _, label := range labels { hashedLabelName := util.GetHashedName(label) allowKubeSystemIngress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureIngressPortChain, + Name: util.KubeSystemFlag, + Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, @@ -188,9 +185,8 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ entries = append(entries, allowKubeSystemIngress) allowKubeSystemEgress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureEgressPortChain, + Name: util.KubeSystemFlag, + Chain: util.IptablesAzureEgressPortChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go new file mode 100644 index 0000000000..d2ce933919 --- /dev/null +++ b/npm/translatePolicy_test.go @@ -0,0 +1,353 @@ +package npm + +import ( + "testing" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + networkingv1 "k8s.io/api/networking/v1" + "github.com/Azure/azure-container-networking/npm/iptm" + "github.com/Azure/azure-container-networking/npm/util" + "k8s.io/apimachinery/pkg/util/intstr" +) + +func TestTranslateIngress(t *testing.T) { + ns := "testnamespace" + + targetSelector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "context": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + } + }, + } + + tcp := v1.ProtocolTCP + port6783 := intstr.FromInt(6783) + ingressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "db", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + }, + }, + }, + } + ingressNamespaceSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontendns", + }, + }, + }, + } + + compositeNetworkPolicyPeer := networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "region": "northpole", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "k", + Operator: metav1.LabelSelectorOpDoesNotExist, + }, + }, + }, + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "planet": "earth", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "keyExists", + Operator: metav1.LabelSelectorOpExists, + }, + }, + }, + } + + rules := []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6783, + }, + }, + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: ingressPodSelector, + }, + networkingv1.NetworkPolicyPeer{ + PodSelector: ingressNamespaceSelector, + }, + compositeNetworkPolicyPeer, + }, + }, + } + + sets, lists, iptEntries := translateIngress(ns, targetSelector, rules) + expectedSets := []string{ + "context:dev", + "!testNotIn:frontend", + "app:db", + "testIn:frontend", + } + + expectedLists := []string{ + "ns:dev", + "ns-testIn:frontendns", + } + + iptEntries := []&iptm.IptEntry{ + &iptm.IptEntry{ + Name: "allow-tcp:6783-to-context:dev", + Chain: util.IptablesAzureIngressPortChain, + Specs : []string{ + util.IptablesProtFlag, + v1.ProtocolTCP, + util.IptablesDstPortFlag, + intstr.FromInt(6783), + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + }, + }, + &iptm.IptEntry{ + Name: "allow-app:db-to-context:dev", + Chain: util.IptablesAzureIngressFromPodChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:db"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-testIn:frontend-to-context:dev", + Chain: util.IptablesAzureIngressFromPodChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testIn:frontend"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-ns-ns:dev-to-context:dev", + Chain: util.IptablesAzureIngressFromNsChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-ns:dev"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-ns-testIn:frontendns-to-context:dev", + Chain: util.IptablesAzureIngressFromNsChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-testIn:frontends"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-tcp:6783-to-testNotIn:frontend", + Chain: util.IptablesAzureIngressPortChain, + Specs : []string{ + util.IptablesProtFlag, + v1.ProtocolTCP, + util.IptablesDstPortFlag, + intstr.FromInt(6783), + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("!testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + }, + }, + &iptm.IptEntry{ + Name: "allow-app:db-to-testNotIn:frontend", + Chain: util.IptablesAzureIngressFromPodChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:db"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("!testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-testIn:frontend-to-testNotIn:frontend", + Chain: util.IptablesAzureIngressFromChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testIn:frontend"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("!testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-ns-ns:dev-to-testNotIn:frontend", + Chain: util.IptablesAzureIngressFromNsChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-ns:dev"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("!testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "allow-ns-testIn:frontendns-to-testNotIn:frontend", + Chain: util.IptablesAzureIngressFromNsChain, + Specs : []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-testIn:frontendns"), + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("!testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + &iptm.IptEntry{ + Name: "TODO", + Chain: "TODO", + Specs: []string{ + + }, + }, + } +} \ No newline at end of file From 5ff724565c01003ddc0f521702178cb8aca1046d Mon Sep 17 00:00:00 2001 From: Yongli Chen Date: Tue, 16 Jul 2019 15:59:33 -0700 Subject: [PATCH 31/64] update translatePolicy_test.go --- npm/translatePolicy_test.go | 116 ++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 65 deletions(-) diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index d2ce933919..3d91afb54d 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2,10 +2,12 @@ package npm import ( "testing" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - networkingv1 "k8s.io/api/networking/v1" + "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" + "k8s.io/api/core/v1" + networkingv1 "k8s.io/api/networking/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" ) @@ -17,14 +19,14 @@ func TestTranslateIngress(t *testing.T) { "context": "dev", }, MatchExpressions: []metav1.LabelSelectorRequirement{ - Key: "testNotIn", + Key: "testNotIn", Operator: metav1.LabelSelectorOpNotIn, Values: []string{ "frontend", - } + }, }, } - + tcp := v1.ProtocolTCP port6783 := intstr.FromInt(6783) ingressPodSelector := &metav1.LabelSelector{ @@ -63,7 +65,7 @@ func TestTranslateIngress(t *testing.T) { }, MatchExpressions: []metav1.LabelSelectorRequirement{ metav1.LabelSelectorRequirement{ - Key: "k", + Key: "k", Operator: metav1.LabelSelectorOpDoesNotExist, }, }, @@ -74,7 +76,7 @@ func TestTranslateIngress(t *testing.T) { }, MatchExpressions: []metav1.LabelSelectorRequirement{ metav1.LabelSelectorRequirement{ - Key: "keyExists", + Key: "keyExists", Operator: metav1.LabelSelectorOpExists, }, }, @@ -114,11 +116,11 @@ func TestTranslateIngress(t *testing.T) { "ns-testIn:frontendns", } - iptEntries := []&iptm.IptEntry{ + iptEntries := []*iptm.IptEntry{ &iptm.IptEntry{ - Name: "allow-tcp:6783-to-context:dev", + Name: "allow-tcp:6783-to-context:dev", Chain: util.IptablesAzureIngressPortChain, - Specs : []string{ + Specs: []string{ util.IptablesProtFlag, v1.ProtocolTCP, util.IptablesDstPortFlag, @@ -133,9 +135,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-app:db-to-context:dev", + Name: "allow-app:db-to-context:dev", Chain: util.IptablesAzureIngressFromPodChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -151,9 +153,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-testIn:frontend-to-context:dev", + Name: "allow-testIn:frontend-to-context:dev", Chain: util.IptablesAzureIngressFromPodChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -169,9 +171,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-ns-ns:dev-to-context:dev", + Name: "allow-ns-ns:dev-to-context:dev", Chain: util.IptablesAzureIngressFromNsChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -187,9 +189,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-ns-testIn:frontendns-to-context:dev", + Name: "allow-ns-testIn:frontendns-to-context:dev", Chain: util.IptablesAzureIngressFromNsChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -201,13 +203,13 @@ func TestTranslateIngress(t *testing.T) { util.GetHashedName("context:dev"), util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAccept, + util.IptablesAccept, }, }, &iptm.IptEntry{ - Name: "allow-tcp:6783-to-testNotIn:frontend", + Name: "allow-tcp:6783-to-testNotIn:frontend", Chain: util.IptablesAzureIngressPortChain, - Specs : []string{ + Specs: []string{ util.IptablesProtFlag, v1.ProtocolTCP, util.IptablesDstPortFlag, @@ -218,13 +220,13 @@ func TestTranslateIngress(t *testing.T) { util.GetHashedName("!testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, + util.IptablesAzureIngressFromNsChain, }, }, &iptm.IptEntry{ - Name: "allow-app:db-to-testNotIn:frontend", + Name: "allow-app:db-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromPodChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -240,9 +242,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-testIn:frontend-to-testNotIn:frontend", + Name: "allow-testIn:frontend-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -258,9 +260,9 @@ func TestTranslateIngress(t *testing.T) { }, }, &iptm.IptEntry{ - Name: "allow-ns-ns:dev-to-testNotIn:frontend", + Name: "allow-ns-ns:dev-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromNsChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -272,13 +274,13 @@ func TestTranslateIngress(t *testing.T) { util.GetHashedName("!testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAccept, + util.IptablesAccept, }, }, &iptm.IptEntry{ - Name: "allow-ns-testIn:frontendns-to-testNotIn:frontend", + Name: "allow-ns-testIn:frontendns-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromNsChain, - Specs : []string{ + Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -290,64 +292,48 @@ func TestTranslateIngress(t *testing.T) { util.GetHashedName("!testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAccept, + util.IptablesAccept, }, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, &iptm.IptEntry{ - Name: "TODO", + Name: "TODO", Chain: "TODO", - Specs: []string{ - - }, + Specs: []string{}, }, } -} \ No newline at end of file +} From 08923afb26f62df4fff55d3c5671cdd7928fa6bc Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 23 Jul 2019 22:51:11 +0000 Subject: [PATCH 32/64] parse ingress namespaceSelector --- npm/parsePolicy.go | 6 +- npm/parseSelector_test.go | 1 + npm/translatePolicy.go | 311 ++++++++++++++++++++++++++++++------ npm/translatePolicy_test.go | 32 +++- npm/util/util.go | 29 ++++ npm/util/util_test.go | 61 +++++++ 6 files changed, 378 insertions(+), 62 deletions(-) diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 1118b1d48a..252dc45148 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -46,15 +46,15 @@ func addPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolic // if namespace matches && podSelector matches, then merge // else return as is. if !reflect.DeepEqual(old.TypeMeta, new.TypeMeta) { - return nil, fmt.Errorf("Old and new networkpolicy don't have the same TypeMeta") + return nil, fmt.Errorf("Old and new networkpolicies don't have the same TypeMeta") } if old.ObjectMeta.Namespace != new.ObjectMeta.Namespace { - return nil, fmt.Errorf("Old and new networkpolicy don't have the same namespace") + return nil, fmt.Errorf("Old and new networkpolicies don't have the same namespace") } if len(old.Spec.PodSelector.MatchLabels) != 1 || !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { - return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") + return nil, fmt.Errorf("Old and new networkpolicies don't have apply to the same set of target pods") } addedPolicy := &networkingv1.NetworkPolicy{ diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index df98151438..21a70e9cc7 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -57,6 +57,7 @@ func TestParseSelector(t *testing.T) { selector, expectedSelector = nil, nil labels, keys, vals := ParseSelector(selector) expectedLabels, expectedKeys, expectedVals := []string{}, []string{}, []string{} + if len(labels) != len(expectedLabels) { t.Errorf("TestparseSelector failed @ labels length comparison") } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index f5054fefdf..1c4a0f9f51 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -28,8 +28,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne ) labels, _, _ := ParseSelector(&targetSelector) + policyRuleSets = append(policyRuleSets, labels...) for i := range labels { - label := labels[i] + op, label := util.GetOperatorAndLabel(labels[i]) log.Printf("Parsing iptables for label %s", label) hashedLabelName := util.GetHashedName(label) @@ -56,44 +57,94 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if !portRuleExists && !fromRuleExists { - entry := &iptm.IptEntry{ - Name: "allow-all-to-" + label, - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesMatchFlag, - util.IptablesCommentFlag, - }, - } - entries = append(entries, entry) - continue - } - - if !fromRuleExists { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Name: "allow-to-ports-of-" + label, - Chain: util.IptablesAzureIngressPortChain, + var entry *iptm.IptEntry + if op != util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-all-to-" + op + label, + }, + } + } else { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, util.IptablesMatchFlag, util.IptablesSetModuleFlag, + util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, + util.IptablesAccept, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-all-to-" + op + label, }, } + } + entries = append(entries, entry) + continue + } + + if !fromRuleExists { + for _, protPortPair := range protPortPairSlice { + var entry *iptm.IptEntry + if op != util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-to-ports-of-" + op + label, + }, + } + } else { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromNsChain, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-to-ports-of-" + op + label, + }, + } + } entries = append(entries, entry) } continue @@ -104,45 +155,203 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne // Handle IPBlock field of NetworkPolicyPeer if fromRule.IPBlock != nil { if len(fromRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - fromRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - }, + var cidrEntry *iptm.IptEntry + if op != util.IptablesNotFlag { + cidrEntry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + fromRule.IPBlock.CIDR + "-to-" + op + label, + }, + } + } else { + cidrEntry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + fromRule.IPBlock.CIDR + "-to-" + op + label, + }, + } } entries = append(entries, cidrEntry) } if len(fromRule.IPBlock.Except) > 0 { for _, except := range fromRule.IPBlock.Except { - entry := &iptm.IptEntry{ + var entry *iptm.IptEntry + if op != util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + except, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "block-" + except + "-to-" + op + label, + }, + } + } else { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + except, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "block-" + except + "-to-" + op + label, + }, + } + } + entries = append(entries, entry) + } + } + } + + // Handle podSelector and namespaceSelector. + // For PodSelector, use hash:net in ipset. + // For NamespaceSelector, use set:list in ipset. + if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { + continue + } + + if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { + selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) + for _, sLabel := range selectorLabels { + selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) + hashedSelectorLabelName := util.GetHashedName(selectorLabel) + var entry *iptm.IptEntry + if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { + entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - hashedTargetSetName, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, util.IptablesDstFlag, - util.IptablesSFlag, - except, util.IptablesJumpFlag, - util.IptablesDrop, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + } else if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + } else if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + } else { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, }, } - entries = append(entries, entry) } + entries = append(entries, entry) } } - - // Handle podSelector and namespaceSelector } } } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 3d91afb54d..5e14dcf0d4 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2,6 +2,7 @@ package npm import ( "testing" + "reflect" "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" @@ -19,10 +20,12 @@ func TestTranslateIngress(t *testing.T) { "context": "dev", }, MatchExpressions: []metav1.LabelSelectorRequirement{ - Key: "testNotIn", - Operator: metav1.LabelSelectorOpNotIn, - Values: []string{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ "frontend", + }, }, }, } @@ -111,20 +114,29 @@ func TestTranslateIngress(t *testing.T) { "testIn:frontend", } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedIngress failed @ sets comparison") + t.Errorf("sets: %v\nexpectedSets: %v", sets, expectedSets) + } + expectedLists := []string{ "ns:dev", "ns-testIn:frontendns", } - iptEntries := []*iptm.IptEntry{ + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedIngress failed @ lists comparison") + } + + expectedIptEntries := []*iptm.IptEntry{ &iptm.IptEntry{ Name: "allow-tcp:6783-to-context:dev", Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesProtFlag, - v1.ProtocolTCP, + string(v1.ProtocolTCP), util.IptablesDstPortFlag, - intstr.FromInt(6783), + "6783", util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -211,9 +223,9 @@ func TestTranslateIngress(t *testing.T) { Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesProtFlag, - v1.ProtocolTCP, + string(v1.ProtocolTCP), util.IptablesDstPortFlag, - intstr.FromInt(6783), + "6783", util.IptablesMatchFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -336,4 +348,8 @@ func TestTranslateIngress(t *testing.T) { Specs: []string{}, }, } + + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedIngress failed @ iptEntries comparison") + } } diff --git a/npm/util/util.go b/npm/util/util.go index 0494273164..b56c0e9ce8 100644 --- a/npm/util/util.go +++ b/npm/util/util.go @@ -152,3 +152,32 @@ func SetIsNewNwPolicyVerFlag(ver *version.Info) error { return nil } + +// GetOperatorAndLabel returns the operator associated with the label and the label without operator. +func GetOperatorAndLabel(label string) (string, string) { + if len(label) == 0 { + return "", "" + } + + if string(label[0]) == IptablesNotFlag { + return IptablesNotFlag, label[1:] + } + + return "", label +} + +// GetLabelsWithoutOperators returns labels without operators. +func GetLabelsWithoutOperators(labels []string) []string { + var res []string + for _, label := range labels { + if len(label) > 0 { + if string(label[0]) == IptablesNotFlag { + res = append(res, label[1:]) + } else { + res = append(res, label) + } + } + } + + return res +} \ No newline at end of file diff --git a/npm/util/util_test.go b/npm/util/util_test.go index 2192efec40..faad25aee9 100644 --- a/npm/util/util_test.go +++ b/npm/util/util_test.go @@ -2,6 +2,7 @@ package util import ( "testing" + "reflect" "k8s.io/apimachinery/pkg/version" ) @@ -105,3 +106,63 @@ func TestIsNewNwPolicyVer(t *testing.T) { t.Errorf("TestIsNewNwPolicyVer failed @ newer version test") } } + +func TestGetOperatorAndLabel(t *testing.T) { + testLabels := []string{ + "a", + "k:v", + "", + "!a:b", + "!a", + } + + resultOperators, resultLabels := []string{}, []string{} + for _, testLabel := range testLabels { + resultOperator, resultLabel := GetOperatorAndLabel(testLabel) + resultOperators = append(resultOperators, resultOperator) + resultLabels = append(resultLabels, resultLabel) + } + + expectedOperators := []string{ + "", + "", + "", + IptablesNotFlag, + IptablesNotFlag, + } + + expectedLabels := []string{ + "a", + "k:v", + "", + "a:b", + "a", + } + + if !reflect.DeepEqual(resultOperators, expectedOperators) { + t.Errorf("TestGetOperatorAndLabel failed @ operator comparison") + } + + + if !reflect.DeepEqual(resultLabels, expectedLabels) { + t.Errorf("TestGetOperatorAndLabel failed @ label comparison") + } +} + +func TestGetLabelsWithoutOperators(t *testing.T) { + testLabels := []string{ + "k:v", + "", + "!a:b", + } + + resultLabels := GetLabelsWithoutOperators(testLabels) + expectedLabels := []string{ + "k:v", + "a:b", + } + + if !reflect.DeepEqual(resultLabels, expectedLabels) { + t.Errorf("TestGetLabelsWithoutOperators failed @ label comparision") + } +} \ No newline at end of file From 7373f067bc72ad9dc4b7df1c335947b5ee76b7d1 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 24 Jul 2019 00:27:28 +0000 Subject: [PATCH 33/64] TODO: namespaceSelector & podSelector --- npm/translatePolicy.go | 133 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 129 insertions(+), 4 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 1c4a0f9f51..86f36a067f 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -281,7 +281,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne "allow-" + selectorOp + selectorLabel + "-to-" + op + label, }, } - } else if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { + entries = append(entries, entry) + continue + } + + if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ @@ -303,7 +307,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne "allow-" + selectorOp + selectorLabel + "-to-" + op + label, }, } - } else if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { + entries = append(entries, entry) + continue + } + + if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ @@ -325,9 +333,71 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne "allow-" + selectorOp + selectorLabel + "-to-" + op + label, }, } - } else { + entries = append(entries, entry) + continue + } + + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromNsChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + entries = append(entries, entry) + } + continue + } + + if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { + selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) + for _, sLabel := range selectorLabels { + selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) + hashedSelectorLabelName := util.GetHashedName(selectorLabel) + var entry *iptm.IptEntry + if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + entries = append(entries, entry) + continue + } + + if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromPodChain, Specs: []string{ util.IptablesMatchFlag, util.IptablesSetModuleFlag, @@ -337,6 +407,31 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesSrcFlag, util.IptablesMatchFlag, util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, + } + entries = append(entries, entry) + continue + } + + if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, @@ -348,10 +443,40 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne "allow-" + selectorOp + selectorLabel + "-to-" + op + label, }, } + entries = append(entries, entry) + continue + } + + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromPodChain, + Specs: []string{ + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesMatchFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesMatchFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + }, } entries = append(entries, entry) + continue } } + + // fromRule has both namespaceSelector and podSelector set. + // We should match the selected pods in the selected namespaces. + } } } From 3dc765bc774ae3c20ce8120e310d1a6b80c4014f Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 30 Jul 2019 18:51:11 +0000 Subject: [PATCH 34/64] rename sets and lists --- npm/translatePolicy.go | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 86f36a067f..13150fa51f 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -20,15 +20,13 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne portRuleExists = false fromRuleExists = false protPortPairSlice []*portsInfo - //podNsRuleSets []string // pod sets listed in one ingress rules. - //nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets + sets []string // ipsets with type: net:hash + lists []string // ipsets with type: list:set entries []*iptm.IptEntry ) labels, _, _ := ParseSelector(&targetSelector) - policyRuleSets = append(policyRuleSets, labels...) + sets = append(sets, labels...) for i := range labels { op, label := util.GetOperatorAndLabel(labels[i]) log.Printf("Parsing iptables for label %s", label) @@ -256,6 +254,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) + lists = append(lists, selectorLabels...) for _, sLabel := range selectorLabels { selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) hashedSelectorLabelName := util.GetHashedName(selectorLabel) @@ -366,6 +365,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) + sets = append(sets, selectorLabels...) for _, sLabel := range selectorLabels { selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) hashedSelectorLabelName := util.GetHashedName(selectorLabel) @@ -476,14 +476,39 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne // fromRule has both namespaceSelector and podSelector set. // We should match the selected pods in the selected namespaces. - + // This allows traffic from podSelector intersects namespaceSelector + // This is only supported in kubernetes version >= 1.11 + if !util.IsNewNwPolicyVerFlag { + continue + } + + nsSelectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) + lists = append(lists, nsSelectorLabels...) + for _, nsLabel := range nsSelectorLabels { + nsSelectorOp, nsSelectorLabel := util.GetOperatorAndLabel(nsLabel) + hashedNsSelectorLabelName := util.GetHashedName(nsSelectorLabel) + + podSelectorLabels, _, _ := ParseSelector(fromRule.PodSelector) + sets = append(sets, podSelectorLabels...) + for _, podLabel := range podSelectorLabels { + podSelectorOp, podSelectorLabel := util.GetOperatorAndLabel(podLabel) + hashedPodSelectorLabelName := util.GetHashedName(podSelectorLabel) + + var entry *iptm.IptEntry + if op != util.IptablesNotFlag && + nsSelectorOp != util.IptablesNotFlag && + podSelectorOp != util.IptablesNotFlag { + + } + } + } } } } } log.Printf("finished parsing ingress rule") - return policyRuleSets, policyRuleLists, entries + return sets, lists, entries } func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { From 609331c0f18ff70694587b15d197c7ff396bc518 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 1 Aug 2019 00:32:33 +0000 Subject: [PATCH 35/64] rename iptablesMatchFlag to iptablesModuleFlag --- npm/iptm/iptm.go | 38 ++----- npm/namespace.go | 4 +- npm/translatePolicy.go | 220 +++++++++++++++++++++++++----------- npm/translatePolicy_test.go | 36 +++--- npm/util/const.go | 6 +- npm/util/util.go | 5 - 6 files changed, 183 insertions(+), 126 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 8f80a7f974..a9d57cb0d0 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -79,7 +79,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { // Add default allow CONNECTED/RELATED rule to AZURE-NPM chain. entry.Chain = util.IptablesAzureChain entry.Specs = []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesStateModuleFlag, util.IptablesStateFlag, util.IptablesRelatedState + "," + util.IptablesEstablishedState, @@ -120,13 +120,8 @@ func (iptMgr *IptablesManager) InitNpmChains() error { } } - // Create AZURE-NPM-INGRESS-FROM-NS chain. - if err = iptMgr.AddChain(util.IptablesAzureIngressFromNsChain); err != nil { - return err - } - - // Create AZURE-NPM-INGRESS-FROM-POD chain. - if err = iptMgr.AddChain(util.IptablesAzureIngressFromPodChain); err != nil { + // Create AZURE-NPM-INGRESS-FROM chain. + if err = iptMgr.AddChain(util.IptablesAzureIngressFromChain); err != nil { return err } @@ -151,24 +146,14 @@ func (iptMgr *IptablesManager) InitNpmChains() error { } } - // Create AZURE-NPM-EGRESS-TO-NS chain. - if err = iptMgr.AddChain(util.IptablesAzureEgressToNsChain); err != nil { - return err - } - - // Create AZURE-NPM-EGRESS-TO-POD chain. - if err = iptMgr.AddChain(util.IptablesAzureEgressToPodChain); err != nil { - return err - } - - // Create AZURE-NPM-TARGET-SETS chain. - if err := iptMgr.AddChain(util.IptablesAzureTargetSetsChain); err != nil { + // Create AZURE-NPM-EGRESS-TO chain. + if err = iptMgr.AddChain(util.IptablesAzureEgressToChain); err != nil { return err } - // Insert AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain. + // Add default DROP rule to AZURE-NPM chain. entry.Chain = util.IptablesAzureChain - entry.Specs = []string{util.IptablesJumpFlag, util.IptablesAzureTargetSetsChain} + entry.Specs = []string{util.IptablesJumpFlag, util.IptablesDrop} exists, err = iptMgr.Exists(entry) if err != nil { return err @@ -177,7 +162,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("Error: failed to add AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain.") + log.Errorf("Error: failed to add default DROP rule to AZURE-NPM chain.") return err } } @@ -190,12 +175,9 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { IptablesAzureChainList := []string{ util.IptablesAzureChain, util.IptablesAzureIngressPortChain, - util.IptablesAzureIngressFromNsChain, - util.IptablesAzureIngressFromPodChain, + util.IptablesAzureIngressFromChain, util.IptablesAzureEgressPortChain, - util.IptablesAzureEgressToNsChain, - util.IptablesAzureEgressToPodChain, - util.IptablesAzureTargetSetsChain, + util.IptablesAzureEgressToChain, } // Remove AZURE-NPM chain from FORWARD chain. diff --git a/npm/namespace.go b/npm/namespace.go index 62e3b4a1ee..1f89bf7212 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -112,7 +112,7 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var labelKeys []string nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) + labelKey := util.GetHashedName(nsLabelKey + ":" + nsLabelVal) log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) if err = ipsMgr.AddToList(labelKey, nsName); err != nil { log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) @@ -174,7 +174,7 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var labelKeys []string nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetNsIpsetName(nsLabelKey, nsLabelVal) + labelKey := util.GetHashedName(nsLabelKey + ":" + nsLabelVal) log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 13150fa51f..8b03a7dadd 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -60,14 +60,14 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "allow-all-to-" + op + label, @@ -77,7 +77,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, @@ -85,7 +85,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "allow-all-to-" + op + label, @@ -107,14 +107,14 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne protPortPair.protocol, util.IptablesDstPortFlag, protPortPair.port, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "allow-to-ports-of-" + op + label, @@ -128,15 +128,15 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne protPortPair.protocol, util.IptablesDstPortFlag, protPortPair.port, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "allow-to-ports-of-" + op + label, @@ -158,7 +158,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne cidrEntry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, @@ -167,17 +167,18 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne fromRule.IPBlock.CIDR, util.IptablesJumpFlag, util.IptablesAccept, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + fromRule.IPBlock.CIDR + "-to-" + op + label, + "allow-" + fromRule.IPBlock.CIDR + + "-to-" + op + label, }, } } else { cidrEntry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, @@ -187,10 +188,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne fromRule.IPBlock.CIDR, util.IptablesJumpFlag, util.IptablesAccept, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + fromRule.IPBlock.CIDR + "-to-" + op + label, + "allow-" + fromRule.IPBlock.CIDR + + "-to-" + op + label, }, } } @@ -204,7 +206,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, @@ -213,17 +215,18 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne except, util.IptablesJumpFlag, util.IptablesDrop, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "block-" + except + "-to-" + op + label, + "block-" + except + + "-to-" + op + label, }, } } else { entry = &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, @@ -233,10 +236,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne except, util.IptablesJumpFlag, util.IptablesDrop, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "block-" + except + "-to-" + op + label, + "block-" + except + + "-to-" + op + label, }, } } @@ -261,23 +265,25 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne var entry *iptm.IptEntry if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -286,24 +292,26 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -312,24 +320,26 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -337,25 +347,27 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -372,23 +384,25 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne var entry *iptm.IptEntry if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromPodChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -397,24 +411,26 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromPodChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -423,24 +439,26 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromPodChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -448,25 +466,27 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromPodChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesMatchFlag, + util.IptablesAccept, + util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + "-to-" + op + label, + "allow-" + selectorOp + selectorLabel + + "-to-" + op + label, }, } entries = append(entries, entry) @@ -494,11 +514,75 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne podSelectorOp, podSelectorLabel := util.GetOperatorAndLabel(podLabel) hashedPodSelectorLabelName := util.GetHashedName(podSelectorLabel) - var entry *iptm.IptEntry if op != util.IptablesNotFlag && nsSelectorOp != util.IptablesNotFlag && podSelectorOp != util.IptablesNotFlag { - + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedNsSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedPodSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + nsSelectorOp + nsSelectorLabel + + "-AND-" + podSelectorOp + podSelectorLabel + + "-to-" + op + label, + }, + } + entries = append(entries, entry) + continue + } + + if op != util.IptablesNotFlag && + nsSelectorOp != util.IptablesNotFlag && + podSelectorOp == util.IptablesNotFlag { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedNsSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + hashedPodSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + nsSelectorOp + nsSelectorLabel + + "-AND-" + podSelectorOp + podSelectorLabel + + "-to-" + op + label, + }, + } + entries = append(entries, entry) + continue } } } @@ -527,12 +611,12 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ Name: util.KubeSystemFlag, Chain: util.IptablesAzureIngressPortChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedKubeSystemSet, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, @@ -547,12 +631,12 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ Name: util.KubeSystemFlag, Chain: util.IptablesAzureEgressPortChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, hashedKubeSystemSet, diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 5e14dcf0d4..f885d3f7af 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -137,7 +137,7 @@ func TestTranslateIngress(t *testing.T) { string(v1.ProtocolTCP), util.IptablesDstPortFlag, "6783", - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), @@ -150,12 +150,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-app:db-to-context:dev", Chain: util.IptablesAzureIngressFromPodChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("app:db"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), @@ -168,12 +168,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-testIn:frontend-to-context:dev", Chain: util.IptablesAzureIngressFromPodChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("testIn:frontend"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), @@ -186,12 +186,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-ns-ns:dev-to-context:dev", Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("ns-ns:dev"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), @@ -204,12 +204,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-ns-testIn:frontendns-to-context:dev", Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("ns-testIn:frontends"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), @@ -226,7 +226,7 @@ func TestTranslateIngress(t *testing.T) { string(v1.ProtocolTCP), util.IptablesDstPortFlag, "6783", - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("!testNotIn:frontend"), @@ -239,12 +239,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-app:db-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromPodChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("app:db"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("!testNotIn:frontend"), @@ -257,12 +257,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-testIn:frontend-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("testIn:frontend"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("!testNotIn:frontend"), @@ -275,12 +275,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-ns-ns:dev-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("ns-ns:dev"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("!testNotIn:frontend"), @@ -293,12 +293,12 @@ func TestTranslateIngress(t *testing.T) { Name: "allow-ns-testIn:frontendns-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromNsChain, Specs: []string{ - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("ns-testIn:frontendns"), util.IptablesSrcFlag, - util.IptablesMatchFlag, + util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("!testNotIn:frontend"), diff --git a/npm/util/const.go b/npm/util/const.go index 462cda62a2..d81d499501 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -47,7 +47,7 @@ const ( IptablesSFlag string = "-s" IptablesDFlag string = "-d" IptablesDstPortFlag string = "--dport" - IptablesMatchFlag string = "-m" + IptablesModuleFlag string = "-m" IptablesSetModuleFlag string = "set" IptablesMatchSetFlag string = "--match-set" IptablesStateModuleFlag string = "state" @@ -63,12 +63,8 @@ const ( IptablesAzureChain string = "AZURE-NPM" IptablesAzureIngressPortChain string = "AZURE-NPM-INGRESS-PORT" IptablesAzureIngressFromChain string = "AZURE-NPM-INGRESS-FROM" - IptablesAzureIngressFromNsChain string = "AZURE-NPM-INGRESS-FROM-NS" - IptablesAzureIngressFromPodChain string = "AZURE-NPM-INGRESS-FROM-POD" IptablesAzureEgressPortChain string = "AZURE-NPM-EGRESS-PORT" IptablesAzureEgressToChain string = "AZURE-NPM-EGRESS-TO" - IptablesAzureEgressToNsChain string = "AZURE-NPM-EGRESS-TO-NS" - IptablesAzureEgressToPodChain string = "AZURE-NPM-EGRESS-TO-POD" IptablesAzureTargetSetsChain string = "AZURE-NPM-TARGET-SETS" IptablesForwardChain string = "FORWARD" IptablesInputChain string = "INPUT" diff --git a/npm/util/util.go b/npm/util/util.go index b56c0e9ce8..856c73e90d 100644 --- a/npm/util/util.go +++ b/npm/util/util.go @@ -36,11 +36,6 @@ func GetClusterID(nodeName string) string { return s[2] } -// GetNsIpsetName returns ipset name from namespaceSelector. -func GetNsIpsetName(k, v string) string { - return "ns-" + k + ":" + v -} - // Hash hashes a string to another string with length <= 32. func Hash(s string) string { h := fnv.New32a() From 648bc1c4acfc5338af89303e98d1e2203518373c Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 1 Aug 2019 22:43:42 +0000 Subject: [PATCH 36/64] reduce cases by generalizing operators --- npm/translatePolicy.go | 499 +++++++++-------------------------------- npm/util/util.go | 19 ++ npm/util/util_test.go | 32 +++ 3 files changed, 154 insertions(+), 396 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 8b03a7dadd..f9972684be 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -55,31 +55,39 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if !portRuleExists && !fromRuleExists { - var entry *iptm.IptEntry - if op != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-all-to-" + op + label, - }, - } - } else { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + op, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-all-to-" + op + label, + }, + } + entries = append(entries, entry) + continue + } + + if !fromRuleExists { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + op, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, @@ -88,61 +96,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-all-to-" + op + label, + "allow-to-ports-of-" + op + label, }, } - } - entries = append(entries, entry) - continue - } - - if !fromRuleExists { - for _, protPortPair := range protPortPairSlice { - var entry *iptm.IptEntry - if op != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-to-ports-of-" + op + label, - }, - } - } else { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-to-ports-of-" + op + label, - }, - } - } entries = append(entries, entry) } continue @@ -153,96 +109,50 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne // Handle IPBlock field of NetworkPolicyPeer if fromRule.IPBlock != nil { if len(fromRule.IPBlock.CIDR) > 0 { - var cidrEntry *iptm.IptEntry - if op != util.IptablesNotFlag { - cidrEntry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - fromRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + fromRule.IPBlock.CIDR + - "-to-" + op + label, - }, - } - } else { - cidrEntry = &iptm.IptEntry{ + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + op, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + fromRule.IPBlock.CIDR + + "-to-" + op + label, + }, + } + entries = append(entries, cidrEntry) + } + + if len(fromRule.IPBlock.Except) > 0 { + for _, except := range fromRule.IPBlock.Except { + entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + op, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, util.IptablesSFlag, - fromRule.IPBlock.CIDR, + except, util.IptablesJumpFlag, - util.IptablesAccept, + util.IptablesDrop, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-" + fromRule.IPBlock.CIDR + + "block-" + except + "-to-" + op + label, }, - } - } - entries = append(entries, cidrEntry) - } - - if len(fromRule.IPBlock.Except) > 0 { - for _, except := range fromRule.IPBlock.Except { - var entry *iptm.IptEntry - if op != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "block-" + except + - "-to-" + op + label, - }, - } - } else { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "block-" + except + - "-to-" + op + label, - }, - } } entries = append(entries, entry) } @@ -261,103 +171,19 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne lists = append(lists, selectorLabels...) for _, sLabel := range selectorLabels { selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) - hashedSelectorLabelName := util.GetHashedName(selectorLabel) - var entry *iptm.IptEntry - if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - entry = &iptm.IptEntry{ + hashedSelectorLabelName := util.GetHashedName(selectorLabel) + entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + selectorOp, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + op, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, @@ -381,102 +207,18 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne for _, sLabel := range selectorLabels { selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) hashedSelectorLabelName := util.GetHashedName(selectorLabel) - var entry *iptm.IptEntry - if op != util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - if op != util.IptablesNotFlag && selectorOp == util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - if op == util.IptablesNotFlag && selectorOp != util.IptablesNotFlag { - entry = &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - entry = &iptm.IptEntry{ + entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + selectorOp, util.IptablesMatchSetFlag, hashedSelectorLabelName, util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, - util.IptablesNotFlag, + op, util.IptablesMatchSetFlag, hashedLabelName, util.IptablesDstFlag, @@ -513,77 +255,38 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne for _, podLabel := range podSelectorLabels { podSelectorOp, podSelectorLabel := util.GetOperatorAndLabel(podLabel) hashedPodSelectorLabelName := util.GetHashedName(podSelectorLabel) - - if op != util.IptablesNotFlag && - nsSelectorOp != util.IptablesNotFlag && - podSelectorOp != util.IptablesNotFlag { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedNsSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedPodSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromChain, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + nsSelectorOp + nsSelectorLabel + - "-AND-" + podSelectorOp + podSelectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - - if op != util.IptablesNotFlag && - nsSelectorOp != util.IptablesNotFlag && - podSelectorOp == util.IptablesNotFlag { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedNsSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesNotFlag, - util.IptablesMatchSetFlag, - hashedPodSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromChain, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + nsSelectorOp + nsSelectorLabel + - "-AND-" + podSelectorOp + podSelectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + nsSelectorOp, + util.IptablesMatchSetFlag, + hashedNsSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + podSelectorOp, + util.IptablesMatchSetFlag, + hashedPodSelectorLabelName, + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + op, + util.IptablesMatchSetFlag, + hashedLabelName, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "allow-" + nsSelectorOp + nsSelectorLabel + + "-AND-" + podSelectorOp + podSelectorLabel + + "-to-" + op + label, + }, } + entries = append(entries, entry) } } } @@ -591,6 +294,10 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } } + for _, entry := range entries { + entry.Specs = util.DropEmptyFields(entry.Specs) + } + log.Printf("finished parsing ingress rule") return sets, lists, entries } diff --git a/npm/util/util.go b/npm/util/util.go index 856c73e90d..321d1dc6a4 100644 --- a/npm/util/util.go +++ b/npm/util/util.go @@ -175,4 +175,23 @@ func GetLabelsWithoutOperators(labels []string) []string { } return res +} + +// DropEmptyFields deletes empty entries from a slice. +func DropEmptyFields(s []string) []string { + i := 0 + for { + if i == len(s) { + break + } + + if s[i] == "" { + s = append(s[:i], s[i+1:]...) + continue + } + + i++ + } + + return s } \ No newline at end of file diff --git a/npm/util/util_test.go b/npm/util/util_test.go index faad25aee9..e7be960abc 100644 --- a/npm/util/util_test.go +++ b/npm/util/util_test.go @@ -165,4 +165,36 @@ func TestGetLabelsWithoutOperators(t *testing.T) { if !reflect.DeepEqual(resultLabels, expectedLabels) { t.Errorf("TestGetLabelsWithoutOperators failed @ label comparision") } +} + +func TestDropEmptyFields(t *testing.T) { + testSlice := []string{ + "", + "a:b", + "", + "!", + "-m", + "--match-set", + "", + } + + resultSlice := DropEmptyFields(testSlice) + expectedSlice := []string{ + "a:b", + "!", + "-m", + "--match-set", + } + + if !reflect.DeepEqual(resultSlice, expectedSlice) { + t.Errorf("TestDropEmptyFields failed @ slice comparison") + } + + testSlice = []string{""} + resultSlice = DropEmptyFields(testSlice) + expectedSlice = []string{} + + if !reflect.DeepEqual(resultSlice, expectedSlice) { + t.Errorf("TestDropEmptyFields failed @ slice comparison") + } } \ No newline at end of file From a0ef9958b52d9773ef51c81b9f11d12c8f203269 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 6 Aug 2019 00:23:25 +0000 Subject: [PATCH 37/64] parse entry from selector --- npm/parseSelector.go | 25 +++ npm/parseSelector_test.go | 70 ++++++++ npm/pod.go | 25 ++- npm/translatePolicy.go | 28 +++- npm/translatePolicy_test.go | 314 +++++++++++++++++++++--------------- npm/util/util_test.go | 60 ------- 6 files changed, 324 insertions(+), 198 deletions(-) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index d83ca57280..3d9c2bedf1 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -18,6 +18,31 @@ func ParseLabel(label string) (string, bool) { return label, false } +// GetOperatorAndLabel returns the operator associated with the label and the label without operator. +func GetOperatorAndLabel(label string) (string, string) { + if len(label) == 0 { + return "", "" + } + + if string(label[0]) == util.IptablesNotFlag { + return util.IptablesNotFlag, label[1:] + } + + return "", label +} + +// GetOperatorsAndLabels returns the operators along with the associated labels. +func GetOperatorsAndLabels(labelsWithOps []string) ([]string, []string) { + var ops, labelsWithoutOps []string + for _, labelWithOp := range labelsWithOps { + op, labelWithoutOp := GetOperatorAndLabel(labelWithOp) + ops = append(ops, op) + labelsWithoutOps = append(labelsWithoutOps, labelWithoutOp) + } + + return ops, labelsWithoutOps +} + // ParseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { var ( diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index 21a70e9cc7..00a7aad0dc 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -52,6 +52,76 @@ func TestParseLabel(t *testing.T) { } } +func TestGetOperatorAndLabel(t *testing.T) { + testLabels := []string{ + "a", + "k:v", + "", + "!a:b", + "!a", + } + + resultOperators, resultLabels := []string{}, []string{} + for _, testLabel := range testLabels { + resultOperator, resultLabel := GetOperatorAndLabel(testLabel) + resultOperators = append(resultOperators, resultOperator) + resultLabels = append(resultLabels, resultLabel) + } + + expectedOperators := []string{ + "", + "", + "", + util.IptablesNotFlag, + util.IptablesNotFlag, + } + + expectedLabels := []string{ + "a", + "k:v", + "", + "a:b", + "a", + } + + if !reflect.DeepEqual(resultOperators, expectedOperators) { + t.Errorf("TestGetOperatorAndLabel failed @ operator comparison") + } + + + if !reflect.DeepEqual(resultLabels, expectedLabels) { + t.Errorf("TestGetOperatorAndLabel failed @ label comparison") + } +} + +func TestGetOperatorsAndLabels(t *testing.T) { + testLabels := []string{ + "k:v", + "", + "!a:b", + } + + resultOps, resultLabels := GetOperatorsAndLabels(testLabels) + expectedOps := []string{ + "", + "", + "!", + } + expectedLabels := []string{ + "k:v", + "", + "a:b", + } + + if !reflect.DeepEqual(resultOps, expectedOps) { + t.Errorf("TestGetOperatorsAndLabels failed @ op comparision") + } + + if !reflect.DeepEqual(resultLabels, expectedLabels) { + t.Errorf("TestGetOperatorsAndLabels failed @ label comparision") + } +} + func TestParseSelector(t *testing.T) { var selector, expectedSelector *metav1.LabelSelector selector, expectedSelector = nil, nil diff --git a/npm/pod.go b/npm/pod.go index af35897a9a..f2575c3313 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -50,20 +50,24 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { } // Add the pod to its label's ipset. - var labelKeys []string for podLabelKey, podLabelVal := range podLabels { //Ignore pod-template-hash label. if strings.Contains(podLabelKey, util.KubePodTemplateHashFlag) { continue } - labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - log.Printf("Adding pod %s to ipset %s", podIP, labelKey) - if err = ipsMgr.AddToSet(labelKey, podIP); err != nil { + log.Printf("Adding pod %s to ipset %s", podIP, podLabelKey) + if err = ipsMgr.AddToSet(podLabelKey, podIP); err != nil { + log.Errorf("Error: failed to add pod to label ipset.") + return err + } + + label := podLabelKey + ":" + podLabelVal + log.Printf("Adding pod %s to ipset %s", podIP, label) + if err = ipsMgr.AddToSet(label, podIP); err != nil { log.Errorf("Error: failed to add pod to label ipset.") return err } - labelKeys = append(labelKeys, labelKey) } ns, err := newNs(podNs) @@ -146,8 +150,15 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { continue } - labelKey := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - if err = ipsMgr.DeleteFromSet(labelKey, podIP); err != nil { + log.Printf("Deleting pod %s from ipset %s", podIP, podLabelKey) + if err = ipsMgr.DeleteFromSet(podLabelKey, podIP); err != nil { + log.Errorf("Error: failed to delete pod from label ipset.") + return err + } + + label := podLabelKey + ":" + podLabelVal + log.Printf("Deleting pod %s from ipset %s", podIP, label) + if err = ipsMgr.DeleteFromSet(label, podIP); err != nil { log.Errorf("Error: failed to delete pod from label ipset.") return err } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index f9972684be..0bb685cbdc 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -15,6 +15,29 @@ type portsInfo struct { port string } +func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string) []string { + partialSpec := []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + op, + util.IptablesMatchSetFlag, + util.GetHashedName(label), + srcOrDstFlag, + } + + return util.DropEmptyFields(partialSpec) +} + +func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag string) []string { + var spec []string + + for i, _ := range ops { + spec = append(spec, craftPartialIptEntrySpecFromOpAndLabel(ops[i], labels[i], srcOrDstFlag)...) + } + + return spec +} + func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( portRuleExists = false @@ -26,9 +49,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne ) labels, _, _ := ParseSelector(&targetSelector) - sets = append(sets, labels...) for i := range labels { op, label := util.GetOperatorAndLabel(labels[i]) + sets = append(sets, label) log.Printf("Parsing iptables for label %s", label) hashedLabelName := util.GetHashedName(label) @@ -96,7 +119,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-to-ports-of-" + op + label, + "allow-to-" + protPortPair.port + "-port-of-" + + op + label, }, } entries = append(entries, entry) diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index f885d3f7af..12e937c252 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -12,6 +12,147 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) +func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { + srcOp, srcLabel := "", "src" + iptEntry := craftPartialIptEntrySpecFromOpAndLabel(srcOp, srcLabel, util.IptablesSrcFlag) + expectedIptEntry := []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(srcLabel), + util.IptablesSrcFlag, + } + + if !reflect.DeepEqual(iptEntry, expectedIptEntry) { + t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ src iptEntry comparison") + } + + dstOp, dstLabel := "!", "dst" + iptEntry = craftPartialIptEntrySpecFromOpAndLabel(dstOp, dstLabel, util.IptablesDstFlag) + expectedIptEntry = []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(dstLabel), + util.IptablesDstFlag, + } + + if !reflect.DeepEqual(iptEntry, expectedIptEntry) { + t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ dst iptEntry comparison") + } +} + +func TestCraftPartialIptEntrySpecFromOpsAndLabels(t *testing.T) { + srcOps := []string{ + "", + "", + "!", + } + srcLabels := []string{ + "src", + "src:firstLabel", + "src:secondLabel", + } + + dstOps := []string{ + "!", + "!", + "", + } + dstLabels := []string{ + "dst", + "dst:firstLabel", + "dst:secondLabel", + } + + + srcIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(srcOps, srcLabels, util.IptablesSrcFlag) + dstIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(dstOps, dstLabels, util.IptablesDstFlag) + iptEntrySpec := append(srcIptEntry, dstIptEntry...) + expectedIptEntrySpec := []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("src"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("src:firstLabel"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("src:secondLabel"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("dst"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("dst:firstLabel"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("dst:secondLabel"), + util.IptablesDstFlag, + } + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftIptEntrySpecFromOpsAndLabels failed @ iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } +} + +func TestCraftPartialIptEntryFromSelector(t *testing.T) { + srcSelector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "label": "src", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "labelNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "src", + }, + }, + }, + } + + labelsWithOps, _, _ := ParseSelector(&srcSelector) + ops, labelsWithoutOps := GetOperatorsAndLabels(labelsWithOps) + iptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labelsWithoutOps, util.IptablesSrcFlag) + expectedIptEntrySpec := []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("label:src"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("labelNotIn:src"), + util.IptablesSrcFlag, + } + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftPartialIptEntryFromSelector failed @ iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } +} + func TestTranslateIngress(t *testing.T) { ns := "testnamespace" @@ -130,7 +271,6 @@ func TestTranslateIngress(t *testing.T) { expectedIptEntries := []*iptm.IptEntry{ &iptm.IptEntry{ - Name: "allow-tcp:6783-to-context:dev", Chain: util.IptablesAzureIngressPortChain, Specs: []string{ util.IptablesProtFlag, @@ -142,32 +282,28 @@ func TestTranslateIngress(t *testing.T) { util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesDstFlag, util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend", }, }, &iptm.IptEntry{ - Name: "allow-app:db-to-context:dev", - Chain: util.IptablesAzureIngressFromPodChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, util.GetHashedName("app:db"), util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - util.GetHashedName("context:dev"), - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - }, - &iptm.IptEntry{ - Name: "allow-testIn:frontend-to-context:dev", - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -178,175 +314,95 @@ func TestTranslateIngress(t *testing.T) { util.IptablesMatchSetFlag, util.GetHashedName("context:dev"), util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - }, - &iptm.IptEntry{ - Name: "allow-ns-ns:dev-to-context:dev", - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - util.GetHashedName("ns-ns:dev"), - util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, + util.IptablesNotFlag, util.IptablesMatchSetFlag, - util.GetHashedName("context:dev"), + util.GetHashedName("testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-app:db-AND-testIn:frontend-TO-context:dev-AND-testNotIn:frontend", }, }, &iptm.IptEntry{ - Name: "allow-ns-testIn:frontendns-to-context:dev", - Chain: util.IptablesAzureIngressFromNsChain, + Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("ns-testIn:frontends"), + util.GetHashedName("ns:dev"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("context:dev"), - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - }, - &iptm.IptEntry{ - Name: "allow-tcp:6783-to-testNotIn:frontend", - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - string(v1.ProtocolTCP), - util.IptablesDstPortFlag, - "6783", + util.GetHashedName("testIn:frontendns"), + util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("!testNotIn:frontend"), + util.GetHashedName("context:dev"), util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - }, - }, - &iptm.IptEntry{ - Name: "allow-app:db-to-testNotIn:frontend", - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - util.GetHashedName("app:db"), - util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, + util.IptablesNotFlag, util.IptablesMatchSetFlag, - util.GetHashedName("!testNotIn:frontend"), + util.GetHashedName("testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ns:dev-AND-testIn:frontendns-TO-context:dev-AND-!testNotIn:frontend", }, }, &iptm.IptEntry{ - Name: "allow-testIn:frontend-to-testNotIn:frontend", Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("testIn:frontend"), + util.GetHashedName("planet:earth"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("!testNotIn:frontend"), - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - }, - &iptm.IptEntry{ - Name: "allow-ns-ns:dev-to-testNotIn:frontend", - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ + util.GetHashedName("keyExists"), + util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("ns-ns:dev"), + util.GetHashedName("region:northpole"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, + util.IptablesNotFlag, util.IptablesMatchSetFlag, - util.GetHashedName("!testNotIn:frontend"), - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - }, - &iptm.IptEntry{ - Name: "allow-ns-testIn:frontendns-to-testNotIn:frontend", - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ + util.GetHashedName("k"), + util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("ns-testIn:frontendns"), - util.IptablesSrcFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, + util.IptablesNotFlag, util.IptablesMatchSetFlag, - util.GetHashedName("!testNotIn:frontend"), + util.GetHashedName("testNotIn:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-planet:earth-AND-keyExists-AND-region:northpole-AND-!k-TO-context:dev-AND-!testNotIn:frontend", }, }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, - &iptm.IptEntry{ - Name: "TODO", - Chain: "TODO", - Specs: []string{}, - }, } if !reflect.DeepEqual(iptEntries, expectedIptEntries) { diff --git a/npm/util/util_test.go b/npm/util/util_test.go index e7be960abc..00603815f5 100644 --- a/npm/util/util_test.go +++ b/npm/util/util_test.go @@ -107,66 +107,6 @@ func TestIsNewNwPolicyVer(t *testing.T) { } } -func TestGetOperatorAndLabel(t *testing.T) { - testLabels := []string{ - "a", - "k:v", - "", - "!a:b", - "!a", - } - - resultOperators, resultLabels := []string{}, []string{} - for _, testLabel := range testLabels { - resultOperator, resultLabel := GetOperatorAndLabel(testLabel) - resultOperators = append(resultOperators, resultOperator) - resultLabels = append(resultLabels, resultLabel) - } - - expectedOperators := []string{ - "", - "", - "", - IptablesNotFlag, - IptablesNotFlag, - } - - expectedLabels := []string{ - "a", - "k:v", - "", - "a:b", - "a", - } - - if !reflect.DeepEqual(resultOperators, expectedOperators) { - t.Errorf("TestGetOperatorAndLabel failed @ operator comparison") - } - - - if !reflect.DeepEqual(resultLabels, expectedLabels) { - t.Errorf("TestGetOperatorAndLabel failed @ label comparison") - } -} - -func TestGetLabelsWithoutOperators(t *testing.T) { - testLabels := []string{ - "k:v", - "", - "!a:b", - } - - resultLabels := GetLabelsWithoutOperators(testLabels) - expectedLabels := []string{ - "k:v", - "a:b", - } - - if !reflect.DeepEqual(resultLabels, expectedLabels) { - t.Errorf("TestGetLabelsWithoutOperators failed @ label comparision") - } -} - func TestDropEmptyFields(t *testing.T) { testSlice := []string{ "", From 2d0bc2d6ea962842f4f32fdac1ffe2d425143b19 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 Aug 2019 00:15:53 +0000 Subject: [PATCH 38/64] finished translateIngress --- npm/translatePolicy.go | 503 +++++++++++++++++++----------------- npm/translatePolicy_test.go | 80 +++++- npm/util/const.go | 2 +- 3 files changed, 332 insertions(+), 253 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 0bb685cbdc..295b6a7ed0 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -38,6 +38,31 @@ func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag return spec } +func craftPartialIptEntrySpecFromSelector(selector *metav1.LabelSelector, srcOrDstFlag string) []string { + labelsWithOps, _, _ := ParseSelector(selector) + ops, labels := GetOperatorsAndLabels(labelsWithOps) + return craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, srcOrDstFlag) +} + +func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector) string { + if selector == nil { + return "none" + } + + if len(selector.MatchExpressions) == 0 && len(selector.MatchLabels) == 0 { + return util.KubeAllNamespacesFlag + } + + labelsWithOps, _, _ := ParseSelector(selector) + var comment string + for _, labelWithOp := range labelsWithOps { + comment += labelWithOp + comment += "-AND-" + } + + return comment[:len(comment)-len("-AND-")] +} + func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( portRuleExists = false @@ -48,280 +73,274 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entries []*iptm.IptEntry ) - labels, _, _ := ParseSelector(&targetSelector) - for i := range labels { - op, label := util.GetOperatorAndLabel(labels[i]) - sets = append(sets, label) - log.Printf("Parsing iptables for label %s", label) + log.Printf("started parsing ingress rule") + + labelsWithOps, _, _ := ParseSelector(&targetSelector) + ops, labels := GetOperatorsAndLabels(labelsWithOps) + sets = append(sets, labels...) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag) + targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector) + for _, rule := range rules { + // parse Ports field + for _, portRule := range rule.Ports { + protPortPairSlice = append( + protPortPairSlice, + &portsInfo{ + protocol: string(*portRule.Protocol), + port: portRule.Port.String(), + }, + ) + portRuleExists = true + } - hashedLabelName := util.GetHashedName(label) - for _, rule := range rules { - // parse Ports field - for _, portRule := range rule.Ports { - protPortPairSlice = append(protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: portRule.Port.String(), - }, - ) - portRuleExists = true + if rule.From != nil { + for _, fromRule := range rule.From { + if fromRule.PodSelector != nil || + fromRule.NamespaceSelector != nil || + fromRule.IPBlock != nil { + fromRuleExists = true + } } + } - if rule.From != nil { - for _, fromRule := range rule.From { - if fromRule.PodSelector != nil || - fromRule.NamespaceSelector != nil || - fromRule.IPBlock != nil { - fromRuleExists = true - } - } + if !portRuleExists && !fromRuleExists { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: targetSelectorIptEntrySpec, } + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + targetSelectorComment, + ) + + entries = append(entries, entry) + continue + } - if !portRuleExists && !fromRuleExists { + // Only Ports rules exist + if !fromRuleExists { + for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, + Chain: util.IptablesAzureIngressPortChain, Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + }, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + + targetSelectorComment, + ) + entries = append(entries, entry) + } + continue + } + + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + }, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + + targetSelectorComment, + ) + entries = append(entries, entry) + } + + for _, fromRule := range rule.From { + // Handle IPBlock field of NetworkPolicyPeer + if fromRule.IPBlock != nil { + if len(fromRule.IPBlock.CIDR) > 0 { + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + } + cidrEntry.Specs = append( + cidrEntry.Specs, + util.IptablesSFlag, + fromRule.IPBlock.CIDR, + ) + cidrEntry.Specs = append(cidrEntry.Specs, targetSelectorIptEntrySpec...) + cidrEntry.Specs = append( + cidrEntry.Specs, util.IptablesJumpFlag, util.IptablesAccept, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-all-to-" + op + label, - }, + "ALLOW-" + fromRule.IPBlock.CIDR + + "-TO-" + craftPartialIptablesCommentFromSelector(&targetSelector), + ) + entries = append(entries, cidrEntry) } - entries = append(entries, entry) - continue - } - - if !fromRuleExists { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, + if len(fromRule.IPBlock.Except) > 0 { + for _, except := range fromRule.IPBlock.Except { + exceptEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + } + exceptEntry.Specs = append( + exceptEntry.Specs, + util.IptablesSFlag, + except, + ) + exceptEntry.Specs = append(exceptEntry.Specs, targetSelectorIptEntrySpec...) + exceptEntry.Specs = append( + exceptEntry.Specs, util.IptablesJumpFlag, - util.IptablesAccept, + util.IptablesDrop, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "allow-to-" + protPortPair.port + "-port-of-" + - op + label, - }, + "DROP-" + except + + "-TO-" + targetSelectorComment, + ) + entries = append(entries, exceptEntry) } - entries = append(entries, entry) } continue } - if !portRuleExists { - for _, fromRule := range rule.From { - // Handle IPBlock field of NetworkPolicyPeer - if fromRule.IPBlock != nil { - if len(fromRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - fromRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + fromRule.IPBlock.CIDR + - "-to-" + op + label, - }, - } - entries = append(entries, cidrEntry) - } + // Handle podSelector and namespaceSelector. + // For PodSelector, use hash:net in ipset. + // For NamespaceSelector, use set:list in ipset. + if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { + continue + } - if len(fromRule.IPBlock.Except) > 0 { - for _, except := range fromRule.IPBlock.Except { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesSFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "block-" + except + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - } - } - } + if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { + nsLabelsWithOps, _, _ := ParseSelector(fromRule.NamespaceSelector) + _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + lists = append(lists, nsLabelsWithoutOps...) - // Handle podSelector and namespaceSelector. - // For PodSelector, use hash:net in ipset. - // For NamespaceSelector, use set:list in ipset. - if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { - continue - } + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + fromRule.NamespaceSelector, + util.IptablesSrcFlag, + )..., + ) + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector) + + "-TO-" + targetSelectorComment, + ) + entries = append(entries, entry) + continue + } - if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { - selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) - lists = append(lists, selectorLabels...) - for _, sLabel := range selectorLabels { - selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) - hashedSelectorLabelName := util.GetHashedName(selectorLabel) - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - selectorOp, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - } - continue - } + if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { + podLabelsWithOps, _, _ := ParseSelector(fromRule.PodSelector) + _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + sets = append(sets, podLabelsWithoutOps...) - if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { - selectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) - sets = append(sets, selectorLabels...) - for _, sLabel := range selectorLabels { - selectorOp, selectorLabel := util.GetOperatorAndLabel(sLabel) - hashedSelectorLabelName := util.GetHashedName(selectorLabel) - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - selectorOp, - util.IptablesMatchSetFlag, - hashedSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + selectorOp + selectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - continue - } - } + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + fromRule.PodSelector, + util.IptablesSrcFlag, + )..., + ) + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector) + + "-TO-" + targetSelectorComment, + ) + entries = append(entries, entry) + continue + } - // fromRule has both namespaceSelector and podSelector set. - // We should match the selected pods in the selected namespaces. - // This allows traffic from podSelector intersects namespaceSelector - // This is only supported in kubernetes version >= 1.11 - if !util.IsNewNwPolicyVerFlag { - continue - } + // fromRule has both namespaceSelector and podSelector set. + // We should match the selected pods in the selected namespaces. + // This allows traffic from podSelector intersects namespaceSelector + // This is only supported in kubernetes version >= 1.11 + if !util.IsNewNwPolicyVerFlag { + continue + } + nsLabelsWithOps, _, _ := ParseSelector(fromRule.NamespaceSelector) + _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + lists = append(lists, nsLabelsWithoutOps...) - nsSelectorLabels, _, _ := ParseSelector(fromRule.NamespaceSelector) - lists = append(lists, nsSelectorLabels...) - for _, nsLabel := range nsSelectorLabels { - nsSelectorOp, nsSelectorLabel := util.GetOperatorAndLabel(nsLabel) - hashedNsSelectorLabelName := util.GetHashedName(nsSelectorLabel) - - podSelectorLabels, _, _ := ParseSelector(fromRule.PodSelector) - sets = append(sets, podSelectorLabels...) - for _, podLabel := range podSelectorLabels { - podSelectorOp, podSelectorLabel := util.GetOperatorAndLabel(podLabel) - hashedPodSelectorLabelName := util.GetHashedName(podSelectorLabel) - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - nsSelectorOp, - util.IptablesMatchSetFlag, - hashedNsSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - podSelectorOp, - util.IptablesMatchSetFlag, - hashedPodSelectorLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - op, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromChain, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "allow-" + nsSelectorOp + nsSelectorLabel + - "-AND-" + podSelectorOp + podSelectorLabel + - "-to-" + op + label, - }, - } - entries = append(entries, entry) - } - } - } + podLabelsWithOps, _, _ := ParseSelector(fromRule.PodSelector) + _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + sets = append(sets, podLabelsWithoutOps...) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + fromRule.NamespaceSelector, + util.IptablesSrcFlag, + )..., + ) + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + fromRule.PodSelector, + util.IptablesSrcFlag, + )..., + ) + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector) + + "-AND-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector) + + "-TO-" + targetSelectorComment, + ) + entries = append(entries, entry) } } - for _, entry := range entries { - entry.Specs = util.DropEmptyFields(entry.Specs) - } - log.Printf("finished parsing ingress rule") return sets, lists, entries } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 12e937c252..ad41d75a01 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -3,6 +3,7 @@ package npm import ( "testing" "reflect" + "encoding/json" "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/npm/util" @@ -114,7 +115,7 @@ func TestCraftPartialIptEntrySpecFromOpsAndLabels(t *testing.T) { } func TestCraftPartialIptEntryFromSelector(t *testing.T) { - srcSelector := metav1.LabelSelector{ + srcSelector := &metav1.LabelSelector{ MatchLabels: map[string]string{ "label": "src", }, @@ -129,9 +130,7 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { }, } - labelsWithOps, _, _ := ParseSelector(&srcSelector) - ops, labelsWithoutOps := GetOperatorsAndLabels(labelsWithOps) - iptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labelsWithoutOps, util.IptablesSrcFlag) + iptEntrySpec := craftPartialIptEntrySpecFromSelector(srcSelector, util.IptablesSrcFlag) expectedIptEntrySpec := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -153,6 +152,55 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { } } +func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { + var selector *metav1.LabelSelector + selector = nil + comment := craftPartialIptablesCommentFromSelector(selector) + expectedComment := "none" + if comment != expectedComment { + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ nil selector comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + + selector = &metav1.LabelSelector{} + comment = craftPartialIptablesCommentFromSelector(selector) + expectedComment = util.KubeAllNamespacesFlag + if comment != expectedComment { + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ empty selector comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + + selector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k0": "v0", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "k1", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "v10", + "v11", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "k2", + Operator: metav1.LabelSelectorOpDoesNotExist, + Values: []string{}, + }, + }, + } + comment = craftPartialIptablesCommentFromSelector(selector) + expectedComment = "k0:v0-AND-k1:v10-AND-k1:v11-AND-!k2" + if comment != expectedComment { + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ normal selector comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } +} + func TestTranslateIngress(t *testing.T) { ns := "testnamespace" @@ -240,33 +288,41 @@ func TestTranslateIngress(t *testing.T) { PodSelector: ingressPodSelector, }, networkingv1.NetworkPolicyPeer{ - PodSelector: ingressNamespaceSelector, + NamespaceSelector: ingressNamespaceSelector, }, compositeNetworkPolicyPeer, }, }, } + util.IsNewNwPolicyVerFlag = true sets, lists, iptEntries := translateIngress(ns, targetSelector, rules) expectedSets := []string{ "context:dev", - "!testNotIn:frontend", + "testNotIn:frontend", "app:db", "testIn:frontend", + "region:northpole", + "k", } if !reflect.DeepEqual(sets, expectedSets) { t.Errorf("translatedIngress failed @ sets comparison") - t.Errorf("sets: %v\nexpectedSets: %v", sets, expectedSets) + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) } expectedLists := []string{ "ns:dev", - "ns-testIn:frontendns", + "testIn:frontendns", + "planet:earth", + "keyExists", } if !reflect.DeepEqual(lists, expectedLists) { t.Errorf("translatedIngress failed @ lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) } expectedIptEntries := []*iptm.IptEntry{ @@ -293,7 +349,7 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend", + "ALLOW-ALL-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend", }, }, &iptm.IptEntry{ @@ -325,7 +381,7 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-app:db-AND-testIn:frontend-TO-context:dev-AND-testNotIn:frontend", + "ALLOW-app:db-AND-testIn:frontend-TO-context:dev-AND-!testNotIn:frontend", }, }, &iptm.IptEntry{ @@ -407,5 +463,9 @@ func TestTranslateIngress(t *testing.T) { if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedIngress failed @ iptEntries comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } } diff --git a/npm/util/const.go b/npm/util/const.go index d81d499501..c05bf9a029 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -7,7 +7,7 @@ const ( KubeSystemFlag string = "kube-system" KubePodTemplateHashFlag string = "pod-template-hash" KubeAllPodsFlag string = "all-pod" - KubeAllNamespacesFlag string = "all-namespace" + KubeAllNamespacesFlag string = "all-namespaces" KubeAppFlag string = "k8s-app" KubeProxyFlag string = "kube-proxy" KubePodStatusFailedFlag string = "Failed" From 59638818117e12ca09b38364b45c87f0727dadf1 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 Aug 2019 00:27:43 +0000 Subject: [PATCH 39/64] rename ParseSelector to parseSelector --- npm/parsePolicy.go | 2 +- npm/parseSelector.go | 6 +- npm/parseSelector_test.go | 12 +- npm/translatePolicy.go | 16 +- npm/translatePolicyOld.goa | 1003 ------------------------------------ 5 files changed, 18 insertions(+), 1021 deletions(-) delete mode 100644 npm/translatePolicyOld.goa diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 252dc45148..585c1989f8 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -29,7 +29,7 @@ func isSamePolicy(old, new *networkingv1.NetworkPolicy) bool { func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.NetworkPolicy) { var policies []*networkingv1.NetworkPolicy - labels, keys, vals := ParseSelector(&(npObj.Spec.PodSelector)) + labels, keys, vals := parseSelector(&(npObj.Spec.PodSelector)) for i := range keys { policy := *npObj policy.ObjectMeta.Name = labels[i] diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 3d9c2bedf1..1e6acc59eb 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -11,7 +11,7 @@ import ( // and if so, returns the original set as well. func ParseLabel(label string) (string, bool) { //The input label is guaranteed to have a non-zero length validated by k8s. - //For label definition, see below ParseSelector() function. + //For label definition, see below parseSelector() function. if label[0:1] == util.IptablesNotFlag { return label[1:], true } @@ -43,8 +43,8 @@ func GetOperatorsAndLabels(labelsWithOps []string) ([]string, []string) { return ops, labelsWithoutOps } -// ParseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. -func ParseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { +// parseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. +func parseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { var ( labels []string keys []string diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index 00a7aad0dc..0264ced7a9 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -125,7 +125,7 @@ func TestGetOperatorsAndLabels(t *testing.T) { func TestParseSelector(t *testing.T) { var selector, expectedSelector *metav1.LabelSelector selector, expectedSelector = nil, nil - labels, keys, vals := ParseSelector(selector) + labels, keys, vals := parseSelector(selector) expectedLabels, expectedKeys, expectedVals := []string{}, []string{}, []string{} if len(labels) != len(expectedLabels) { @@ -145,7 +145,7 @@ func TestParseSelector(t *testing.T) { } selector = &metav1.LabelSelector{} - labels, keys, vals = ParseSelector(selector) + labels, keys, vals = parseSelector(selector) expectedLabels = []string{util.KubeAllNamespacesFlag} expectedKeys = []string{util.KubeAllNamespacesFlag} expectedVals = []string{""} @@ -174,7 +174,7 @@ func TestParseSelector(t *testing.T) { }, } - labels, keys, vals = ParseSelector(selector) + labels, keys, vals = parseSelector(selector) expectedLabels = []string{ "testIn:frontend", "testIn:backend", @@ -222,7 +222,7 @@ func TestParseSelector(t *testing.T) { me := &selector.MatchExpressions *me = append(*me, notIn) - labels, keys, vals = ParseSelector(selector) + labels, keys, vals = parseSelector(selector) addedLabels := []string{ "!testNotIn:frontend", "!testNotIn:backend", @@ -269,7 +269,7 @@ func TestParseSelector(t *testing.T) { *me = append(*me, exists) - labels, keys, vals = ParseSelector(selector) + labels, keys, vals = parseSelector(selector) addedLabels = []string{ "testExists", } @@ -313,7 +313,7 @@ func TestParseSelector(t *testing.T) { *me = append(*me, doesNotExist) - labels, keys, vals = ParseSelector(selector) + labels, keys, vals = parseSelector(selector) addedLabels = []string{ "!testDoesNotExist", } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 295b6a7ed0..0ee78e3ed2 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -39,7 +39,7 @@ func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag } func craftPartialIptEntrySpecFromSelector(selector *metav1.LabelSelector, srcOrDstFlag string) []string { - labelsWithOps, _, _ := ParseSelector(selector) + labelsWithOps, _, _ := parseSelector(selector) ops, labels := GetOperatorsAndLabels(labelsWithOps) return craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, srcOrDstFlag) } @@ -53,7 +53,7 @@ func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector) str return util.KubeAllNamespacesFlag } - labelsWithOps, _, _ := ParseSelector(selector) + labelsWithOps, _, _ := parseSelector(selector) var comment string for _, labelWithOp := range labelsWithOps { comment += labelWithOp @@ -75,7 +75,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne log.Printf("started parsing ingress rule") - labelsWithOps, _, _ := ParseSelector(&targetSelector) + labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) sets = append(sets, labels...) targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag) @@ -234,7 +234,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { - nsLabelsWithOps, _, _ := ParseSelector(fromRule.NamespaceSelector) + nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) lists = append(lists, nsLabelsWithoutOps...) @@ -264,7 +264,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { - podLabelsWithOps, _, _ := ParseSelector(fromRule.PodSelector) + podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) @@ -300,11 +300,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !util.IsNewNwPolicyVerFlag { continue } - nsLabelsWithOps, _, _ := ParseSelector(fromRule.NamespaceSelector) + nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) lists = append(lists, nsLabelsWithoutOps...) - podLabelsWithOps, _, _ := ParseSelector(fromRule.PodSelector) + podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) @@ -353,7 +353,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { var entries []*iptm.IptEntry - labels, _, _ := ParseSelector(&targetSelector) + labels, _, _ := parseSelector(&targetSelector) hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) for _, label := range labels { hashedLabelName := util.GetHashedName(label) diff --git a/npm/translatePolicyOld.goa b/npm/translatePolicyOld.goa deleted file mode 100644 index 977256c6a8..0000000000 --- a/npm/translatePolicyOld.goa +++ /dev/null @@ -1,1003 +0,0 @@ -// Copyright 2018 Microsoft. All rights reserved. -// MIT License -package npm - -import ( - "fmt" - - "github.com/Azure/azure-container-networking/log" - "github.com/Azure/azure-container-networking/npm/iptm" - "github.com/Azure/azure-container-networking/npm/util" - networkingv1 "k8s.io/api/networking/v1" -) - -type portsInfo struct { - protocol string - port string -} - -func appendAndClearSets(podNsRuleSets *[]string, nsRuleLists *[]string, policyRuleSets *[]string, policyRuleLists *[]string) { - *policyRuleSets = append(*policyRuleSets, *podNsRuleSets...) - *policyRuleLists = append(*policyRuleLists, *nsRuleLists...) - podNsRuleSets, nsRuleLists = nil, nil -} - -func parseIngress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { - var ( - portRuleExists = false - fromRuleExists = false - isAppliedToNs = false - protPortPairSlice []*portsInfo - podNsRuleSets []string // pod sets listed in one ingress rules. - nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets - entries []*iptm.IptEntry - ) - - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - isAppliedToNs = true - } - - if isAppliedToNs { - hashedTargetSetName := util.GetHashedName(ns) - - nsDrop := &iptm.IptEntry{ - Name: ns, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, nsDrop) - } - - // Use hashed string for ipset name to avoid string length limit of ipset. - for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) - - hashedTargetSetName := util.GetHashedName(targetSet) - - if len(rules) == 0 { - drop := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, drop) - continue - } - - // allow kube-system - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - allowKubeSystemIngress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemIngress) - - for _, rule := range rules { - for _, portRule := range rule.Ports { - protPortPairSlice = append(protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: fmt.Sprint(portRule.Port.IntVal), - }) - - portRuleExists = true - } - - if rule.From != nil { - for _, fromRule := range rule.From { - if fromRule.PodSelector != nil { - fromRuleExists = true - } - if fromRule.NamespaceSelector != nil { - fromRuleExists = true - } - if fromRule.IPBlock != nil { - fromRuleExists = true - } - } - } - } - - for _, rule := range rules { - if !portRuleExists && !fromRuleExists { - allow := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allow) - continue - } - - if !portRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - }, - } - entries = append(entries, entry) - } else { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromNsChain, - }, - } - entries = append(entries, entry) - } - } - - if !fromRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - continue - } - - for _, fromRule := range rule.From { - // Handle IPBlock field of NetworkPolicyPeer - if fromRule.IPBlock != nil { - if len(fromRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesSFlag, - fromRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, cidrEntry) - } - - if len(fromRule.IPBlock.Except) > 0 { - for _, except := range fromRule.IPBlock.Except { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesSFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - } - } - - if fromRule.PodSelector == nil && fromRule.NamespaceSelector == nil { - continue - } - - // Allow traffic from namespaceSelector - if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { - // allow traffic from all namespaces - if len(fromRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector - if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { - // allow traffic from the same namespace - if len(fromRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - nsEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromPodChain, - }, - } - entries = append(entries, nsEntry) - - podEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, podEntry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector intersects namespaceSelector - // This is only supported in kubernetes version >= 1.11 - if util.IsNewNwPolicyVerFlag { - // allow traffic from all namespaces - if len(fromRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range fromRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureIngressFromNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromPodChain, - }, - } - entries = append(entries, entry) - } - - // allow traffic from the same namespace - if len(fromRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range fromRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - entry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureIngressFromPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - } - } - } - } - - log.Printf("finished parsing ingress rule") - return policyRuleSets, policyRuleLists, entries -} - -func parseEgress(ns string, targetSets []string, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { - var ( - portRuleExists = false - toRuleExists = false - isAppliedToNs = false - protPortPairSlice []*portsInfo - podNsRuleSets []string // pod sets listed in one ingress rules. - nsRuleLists []string // namespace sets listed in one ingress rule - policyRuleSets []string // policy-wise pod sets - policyRuleLists []string // policy-wise namespace sets - entries []*iptm.IptEntry - ) - - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - isAppliedToNs = true - } - - if isAppliedToNs { - hashedTargetSetName := util.GetHashedName(ns) - - nsDrop := &iptm.IptEntry{ - Name: ns, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, nsDrop) - } - - // Use hashed string for ipset name to avoid string length limit of ipset. - for _, targetSet := range targetSets { - log.Printf("Parsing iptables for label %s", targetSet) - - hashedTargetSetName := util.GetHashedName(targetSet) - - if len(rules) == 0 { - drop := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, drop) - continue - } - - // allow kube-system - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - allowKubeSystemEgress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemEgress) - - for _, rule := range rules { - for _, portRule := range rule.Ports { - protPortPairSlice = append(protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: fmt.Sprint(portRule.Port.IntVal), - }) - - portRuleExists = true - } - - if rule.To != nil { - for _, toRule := range rule.To { - if toRule.PodSelector != nil { - toRuleExists = true - } - if toRule.NamespaceSelector != nil { - toRuleExists = true - } - if toRule.IPBlock != nil { - toRuleExists = true - } - } - } - } - - for _, rule := range rules { - if !portRuleExists && !toRuleExists { - allow := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allow) - continue - } - - if !portRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToNsChain, - }, - } - entries = append(entries, entry) - } else { - for _, protPortPair := range protPortPairSlice { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToNsChain, - }, - } - entries = append(entries, entry) - } - } - - if !toRuleExists { - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - continue - } - - for _, toRule := range rule.To { - // Handle IPBlock field of NetworkPolicyPeer - if toRule.IPBlock != nil { - if len(toRule.IPBlock.CIDR) > 0 { - cidrEntry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesDFlag, - toRule.IPBlock.CIDR, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, cidrEntry) - } - - if len(toRule.IPBlock.Except) > 0 { - for _, except := range toRule.IPBlock.Except { - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesDFlag, - except, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - } - } - - if toRule.PodSelector == nil && toRule.NamespaceSelector == nil { - continue - } - - // Allow traffic from namespaceSelector - if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { - // allow traffic from all namespaces - if len(toRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector - if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { - // allow traffic from the same namespace - if len(toRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - nsEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToPodChain, - }, - } - entries = append(entries, nsEntry) - - podEntry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, podEntry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - continue - } - - // Allow traffic from podSelector intersects namespaceSelector - // This is only supported in kubernetes version >= 1.11 - if util.IsNewNwPolicyVerFlag { - log.Printf("Kubernetes version > 1.11, parsing podSelector AND namespaceSelector") - // allow traffic from all namespaces - if len(toRule.NamespaceSelector.MatchLabels) == 0 { - nsRuleLists = append(nsRuleLists, util.KubeAllNamespacesFlag) - } - - for nsLabelKey, nsLabelVal := range toRule.NamespaceSelector.MatchLabels { - nsRuleLists = append(nsRuleLists, util.GetNsIpsetName(nsLabelKey, nsLabelVal)) - } - - for _, nsRuleSet := range nsRuleLists { - hashedNsRuleSetName := util.GetHashedName(nsRuleSet) - entry := &iptm.IptEntry{ - Name: nsRuleSet, - HashedName: hashedNsRuleSetName, - Chain: util.IptablesAzureEgressToNsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedNsRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureEgressToPodChain, - }, - } - entries = append(entries, entry) - } - - // allow traffic from the same namespace - if len(toRule.PodSelector.MatchLabels) == 0 { - podNsRuleSets = append(podNsRuleSets, ns) - } - - for podLabelKey, podLabelVal := range toRule.PodSelector.MatchLabels { - podNsRuleSets = append(podNsRuleSets, util.KubeAllNamespacesFlag+"-"+podLabelKey+":"+podLabelVal) - } - - // Handle PodSelector field of NetworkPolicyPeer. - for _, podRuleSet := range podNsRuleSets { - hashedPodRuleSetName := util.GetHashedName(podRuleSet) - entry := &iptm.IptEntry{ - Name: podRuleSet, - HashedName: hashedPodRuleSetName, - Chain: util.IptablesAzureEgressToPodChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedPodRuleSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, entry) - } - appendAndClearSets(&podNsRuleSets, &nsRuleLists, &policyRuleSets, &policyRuleLists) - } - } - } - } - - log.Printf("finished parsing ingress rule") - return policyRuleSets, policyRuleLists, entries -} - -// Drop all non-whitelisted packets. -func getDefaultDropEntries(targetSets []string) []*iptm.IptEntry { - var entries []*iptm.IptEntry - - for _, targetSet := range targetSets { - hashedTargetSetName := util.GetHashedName(targetSet) - entry := &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - - entry = &iptm.IptEntry{ - Name: targetSet, - HashedName: hashedTargetSetName, - Chain: util.IptablesAzureTargetSetsChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesDrop, - }, - } - entries = append(entries, entry) - } - - return entries -} - -// Allow traffic from/to kube-system pods -func getAllowKubeSystemEntries(ns string, targetSets []string) []*iptm.IptEntry { - var entries []*iptm.IptEntry - - if len(targetSets) == 0 { - targetSets = append(targetSets, ns) - } - - for _, targetSet := range targetSets { - hashedTargetSetName := util.GetHashedName(targetSet) - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - allowKubeSystemIngress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemIngress) - - allowKubeSystemEgress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - HashedName: hashedKubeSystemSet, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedTargetSetName, - util.IptablesSrcFlag, - util.IptablesMatchFlag, - util.IptablesSetFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemEgress) - } - - return entries -} - -// ParsePolicy parses network policy. -func parsePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []*iptm.IptEntry) { - var ( - resultPodSets []string - resultNsLists []string - affectedSets []string - entries []*iptm.IptEntry - ) - - // Get affected pods. - npNs, selector := npObj.ObjectMeta.Namespace, npObj.Spec.PodSelector.MatchLabels - for podLabelKey, podLabelVal := range selector { - affectedSet := util.KubeAllNamespacesFlag + "-" + podLabelKey + ":" + podLabelVal - affectedSets = append(affectedSets, affectedSet) - } - - if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { - entries = append(entries, getAllowKubeSystemEntries(npNs, affectedSets)...) - } - - if len(npObj.Spec.PolicyTypes) == 0 { - ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) - resultPodSets = append(resultPodSets, ingressPodSets...) - resultNsLists = append(resultNsLists, ingressNsSets...) - entries = append(entries, ingressEntries...) - - egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) - resultPodSets = append(resultPodSets, egressPodSets...) - resultNsLists = append(resultNsLists, egressNsSets...) - entries = append(entries, egressEntries...) - - entries = append(entries, getDefaultDropEntries(affectedSets)...) - - resultPodSets = append(resultPodSets, affectedSets...) - - return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries - } - - for _, ptype := range npObj.Spec.PolicyTypes { - if ptype == networkingv1.PolicyTypeIngress { - ingressPodSets, ingressNsSets, ingressEntries := parseIngress(npNs, affectedSets, npObj.Spec.Ingress) - resultPodSets = append(resultPodSets, ingressPodSets...) - resultNsLists = append(resultNsLists, ingressNsSets...) - entries = append(entries, ingressEntries...) - } - - if ptype == networkingv1.PolicyTypeEgress { - egressPodSets, egressNsSets, egressEntries := parseEgress(npNs, affectedSets, npObj.Spec.Egress) - resultPodSets = append(resultPodSets, egressPodSets...) - resultNsLists = append(resultNsLists, egressNsSets...) - entries = append(entries, egressEntries...) - } - - entries = append(entries, getDefaultDropEntries(affectedSets)...) - } - - resultPodSets = append(resultPodSets, affectedSets...) - resultPodSets = append(resultPodSets, npNs) - - return util.UniqueStrSlice(resultPodSets), util.UniqueStrSlice(resultNsLists), entries -} From 0a00823aabf3be827abefd967b35cbb183dfd590 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 7 Aug 2019 21:05:21 +0000 Subject: [PATCH 40/64] finished translateEgress --- npm/translatePolicy.go | 362 +++++++++++++++++++++++++++++++++--- npm/translatePolicy_test.go | 275 ++++++++++++++++++++++++++- 2 files changed, 613 insertions(+), 24 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 0ee78e3ed2..b88051e7db 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -150,15 +150,34 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne continue } - for _, protPortPair := range protPortPairSlice { + if portRuleExists { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + }, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + + targetSelectorComment + + "-TO-JUMP-TO-" + util.IptablesAzureIngressFromChain, + ) + entries = append(entries, entry) + } + } else { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - }, } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( @@ -168,8 +187,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + - targetSelectorComment, + "ALLOW-ALL-TO-" + + targetSelectorComment + + "-TO-JUMP-TO-" + util.IptablesAzureIngressFromChain, ) entries = append(entries, entry) } @@ -346,7 +366,305 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { - return nil, nil, nil + var ( + portRuleExists = false + toRuleExists = false + protPortPairSlice []*portsInfo + sets []string // ipsets with type: net:hash + lists []string // ipsets with type: list:set + entries []*iptm.IptEntry + ) + + log.Printf("started parsing egress rule") + + labelsWithOps, _, _ := parseSelector(&targetSelector) + ops, labels := GetOperatorsAndLabels(labelsWithOps) + sets = append(sets, labels...) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesSrcFlag) + targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector) + for _, rule := range rules { + // parse Ports field + for _, portRule := range rule.Ports { + protPortPairSlice = append( + protPortPairSlice, + &portsInfo{ + protocol: string(*portRule.Protocol), + port: portRule.Port.String(), + }, + ) + portRuleExists = true + } + + if rule.To != nil { + for _, toRule := range rule.To { + if toRule.PodSelector != nil || + toRule.NamespaceSelector != nil || + toRule.IPBlock != nil { + toRuleExists = true + } + } + } + + if !portRuleExists && !toRuleExists { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-" + targetSelectorComment, + ) + + entries = append(entries, entry) + continue + } + + // Only Ports rules exist + if !toRuleExists { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + }, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-" + protPortPair.port + "-PORT-OF-" + + targetSelectorComment, + ) + entries = append(entries, entry) + } + continue + } + + if portRuleExists { + for _, protPortPair := range protPortPairSlice { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + protPortPair.protocol, + util.IptablesDstPortFlag, + protPortPair.port, + }, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAzureEgressToChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-" + protPortPair.port + "-PORT-OF-" + + targetSelectorComment + + "-TO-JUMP-TO-" + util.IptablesAzureEgressToChain, + ) + entries = append(entries, entry) + } + } else { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAzureEgressToChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + + targetSelectorComment + + "-TO-JUMP-TO-" + util.IptablesAzureEgressToChain, + ) + entries = append(entries, entry) + } + + for _, toRule := range rule.To { + // Handle IPBlock field of NetworkPolicyPeer + if toRule.IPBlock != nil { + if len(toRule.IPBlock.CIDR) > 0 { + cidrEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + cidrEntry.Specs = append( + cidrEntry.Specs, + util.IptablesDFlag, + toRule.IPBlock.CIDR, + ) + cidrEntry.Specs = append( + cidrEntry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + toRule.IPBlock.CIDR + + "-FROM-" + craftPartialIptablesCommentFromSelector(&targetSelector), + ) + entries = append(entries, cidrEntry) + } + if len(toRule.IPBlock.Except) > 0 { + for _, except := range toRule.IPBlock.Except { + exceptEntry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + exceptEntry.Specs = append( + exceptEntry.Specs, + util.IptablesDFlag, + except, + ) + exceptEntry.Specs = append( + exceptEntry.Specs, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-" + except + + "-FROM-" + targetSelectorComment, + ) + entries = append(entries, exceptEntry) + } + } + continue + } + + // Handle podSelector and namespaceSelector. + // For PodSelector, use hash:net in ipset. + // For NamespaceSelector, use set:list in ipset. + if toRule.PodSelector == nil && toRule.NamespaceSelector == nil { + continue + } + + if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { + nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) + _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + lists = append(lists, nsLabelsWithoutOps...) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + toRule.NamespaceSelector, + util.IptablesDstFlag, + )..., + ) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + targetSelectorComment + + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector), + ) + entries = append(entries, entry) + continue + } + + if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { + podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) + _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + sets = append(sets, podLabelsWithoutOps...) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + toRule.PodSelector, + util.IptablesDstFlag, + )..., + ) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + targetSelectorComment + + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector), + ) + entries = append(entries, entry) + continue + } + + // toRule has both namespaceSelector and podSelector set. + // We should match the selected pods in the selected namespaces. + // This allows traffic from podSelector intersects namespaceSelector + // This is only supported in kubernetes version >= 1.11 + if !util.IsNewNwPolicyVerFlag { + continue + } + nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) + _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + lists = append(lists, nsLabelsWithoutOps...) + + podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) + _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + sets = append(sets, podLabelsWithoutOps...) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: targetSelectorIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + toRule.NamespaceSelector, + util.IptablesDstFlag, + )..., + ) + entry.Specs = append( + entry.Specs, + craftPartialIptEntrySpecFromSelector( + toRule.PodSelector, + util.IptablesDstFlag, + )..., + ) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + targetSelectorComment + + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector) + + "-AND-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector), + ) + entries = append(entries, entry) + } + } + + log.Printf("finished parsing egress rule") + return sets, lists, entries } // Allow traffic from/to kube-system pods @@ -423,14 +741,14 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* } if len(npObj.Spec.PolicyTypes) == 0 { - ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) - resultSets = append(resultSets, ingressPodSets...) - resultLists = append(resultLists, ingressNsSets...) + ingressSets, ingressLists, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) + resultSets = append(resultSets, ingressSets...) + resultLists = append(resultLists, ingressLists...) entries = append(entries, ingressEntries...) - egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) - resultSets = append(resultSets, egressPodSets...) - resultLists = append(resultLists, egressNsSets...) + egressSets, egressLists, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) + resultSets = append(resultSets, egressSets...) + resultLists = append(resultLists, egressLists...) entries = append(entries, egressEntries...) return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries @@ -438,16 +756,16 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* for _, ptype := range npObj.Spec.PolicyTypes { if ptype == networkingv1.PolicyTypeIngress { - ingressPodSets, ingressNsSets, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) - resultSets = append(resultSets, ingressPodSets...) - resultLists = append(resultLists, ingressNsSets...) + ingressSets, ingressLists, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) + resultSets = append(resultSets, ingressSets...) + resultLists = append(resultLists, ingressLists...) entries = append(entries, ingressEntries...) } if ptype == networkingv1.PolicyTypeEgress { - egressPodSets, egressNsSets, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) - resultSets = append(resultSets, egressPodSets...) - resultLists = append(resultLists, egressNsSets...) + egressSets, egressLists, egressEntries := translateEgress(npNs, npObj.Spec.PodSelector, npObj.Spec.Egress) + resultSets = append(resultSets, egressSets...) + resultLists = append(resultLists, egressLists...) entries = append(entries, egressEntries...) } } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index ad41d75a01..bec09e65ab 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -349,7 +349,8 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend", + "ALLOW-ALL-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, }, }, &iptm.IptEntry{ @@ -462,10 +463,280 @@ func TestTranslateIngress(t *testing.T) { } if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedIngress failed @ iptEntries comparison") + t.Errorf("translatedIngress failed @ composite ingress rule comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } } + +func TestTranslateEgress(t *testing.T) { + ns := "testnamespace" + + targetSelector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "context": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + }, + }, + }, + } + + tcp := v1.ProtocolTCP + port6783 := intstr.FromInt(6783) + egressPodSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "db", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + }, + }, + }, + } + egressNamespaceSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontendns", + }, + }, + }, + } + + compositeNetworkPolicyPeer := networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "region": "northpole", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "k", + Operator: metav1.LabelSelectorOpDoesNotExist, + }, + }, + }, + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "planet": "earth", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "keyExists", + Operator: metav1.LabelSelectorOpExists, + }, + }, + }, + } + + rules := []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6783, + }, + }, + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: egressPodSelector, + }, + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: egressNamespaceSelector, + }, + compositeNetworkPolicyPeer, + }, + }, + } + + util.IsNewNwPolicyVerFlag = true + sets, lists, iptEntries := translateEgress(ns, targetSelector, rules) + expectedSets := []string{ + "context:dev", + "testNotIn:frontend", + "app:db", + "testIn:frontend", + "region:northpole", + "k", + } + + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedEgress failed @ sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists := []string{ + "ns:dev", + "testIn:frontendns", + "planet:earth", + "keyExists", + } + + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedEgress failed @ lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries := []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + string(v1.ProtocolTCP), + util.IptablesDstPortFlag, + "6783", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-6783-PORT-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + + util.IptablesAzureEgressToChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:db"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-context:dev-AND-!testNotIn:frontend-TO-app:db-AND-testIn:frontend", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns:dev"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testIn:frontendns"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-context:dev-AND-!testNotIn:frontend-TO-ns:dev-AND-testIn:frontendns", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("planet:earth"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("keyExists"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("region:northpole"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-context:dev-AND-!testNotIn:frontend-TO-planet:earth-AND-keyExists-AND-region:northpole-AND-!k", + }, + }, + } + + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedEgress failed @ composite egress rule comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } +} \ No newline at end of file From 7761057cca74496310e9cdc2e0869cceb0ef7359 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 8 Aug 2019 00:02:20 +0000 Subject: [PATCH 41/64] add prefix "ns-" to namespace ipsets --- npm/namespace.go | 30 ++++--- npm/parseSelector.go | 8 +- npm/parseSelector_test.go | 4 +- npm/translatePolicy.go | 168 ++++++++++++++++++++---------------- npm/translatePolicy_test.go | 111 +++++++++++++++++------- 5 files changed, 200 insertions(+), 121 deletions(-) diff --git a/npm/namespace.go b/npm/namespace.go index 1f89bf7212..03939a579d 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -93,7 +93,7 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var err error - nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + nsName, nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels log.Printf("NAMESPACE CREATING: [%s/%s/%+v]", nsName, nsNs, nsLabel) ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr @@ -109,16 +109,21 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { } // Add the namespace to its label's ipset list. - var labelKeys []string nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetHashedName(nsLabelKey + ":" + nsLabelVal) + labelKey := util.GetHashedName("ns-" + nsLabelKey) log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) if err = ipsMgr.AddToList(labelKey, nsName); err != nil { log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) return err } - labelKeys = append(labelKeys, labelKey) + + label := util.GetHashedName("ns-" + nsLabelKey + ":" + nsLabelVal) + log.Printf("Adding namespace %s to ipset list %s", nsName, label) + if err = ipsMgr.AddToList(label, nsName); err != nil { + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, label) + return err + } } ns, err := newNs(nsName) @@ -134,8 +139,8 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { func (npMgr *NetworkPolicyManager) UpdateNamespace(oldNsObj *corev1.Namespace, newNsObj *corev1.Namespace) error { var err error - oldNsName, oldNsNs, oldNsLabel := oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels - newNsName, newNsNs, newNsLabel := newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels + oldNsName, oldNsNs, oldNsLabel := "ns-" + oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels + newNsName, newNsNs, newNsLabel := "ns-" + newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels log.Printf( "NAMESPACE UPDATING:\n old namespace: [%s/%s/%+v]\n new namespace: [%s/%s/%+v]", oldNsName, oldNsNs, oldNsLabel, newNsName, newNsNs, newNsLabel, @@ -161,7 +166,7 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var err error - nsName, nsNs, nsLabel := nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + nsName, nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels log.Printf("NAMESPACE DELETING: [%s/%s/%+v]", nsName, nsNs, nsLabel) _, exists := npMgr.nsMap[nsName] @@ -171,16 +176,21 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro // Delete the namespace from its label's ipset list. ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr - var labelKeys []string nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetHashedName(nsLabelKey + ":" + nsLabelVal) + labelKey := util.GetHashedName("ns-" + nsLabelKey) log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) return err } - labelKeys = append(labelKeys, labelKey) + + label := util.GetHashedName("ns-" + nsLabelKey + ":" + nsLabelVal) + log.Printf("Deleting namespace %s from ipset list %s", nsName, label) + if err = ipsMgr.DeleteFromList(label, nsName); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, label) + return err + } } // Delete the namespace from all-namespace ipset list. diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 1e6acc59eb..14b56a7ada 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -51,16 +51,10 @@ func parseSelector(selector *metav1.LabelSelector) ([]string, []string, []string vals []string ) - if selector == nil { + if selector == nil || (len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0) { return labels, keys, vals } - if len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0 { - labels = append(labels, util.KubeAllNamespacesFlag) - keys = append(keys, util.KubeAllNamespacesFlag) - vals = append(vals, "") - } - for k, v := range selector.MatchLabels { labels = append(labels, k+":"+v) keys = append(keys, k) diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index 0264ced7a9..c0fe17fa4f 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -146,9 +146,7 @@ func TestParseSelector(t *testing.T) { selector = &metav1.LabelSelector{} labels, keys, vals = parseSelector(selector) - expectedLabels = []string{util.KubeAllNamespacesFlag} - expectedKeys = []string{util.KubeAllNamespacesFlag} - expectedVals = []string{""} + expectedLabels, expectedKeys, expectedVals = []string{}, []string{}, []string{} if len(labels) != len(expectedLabels) { t.Errorf("TestparseSelector failed @ labels length comparison") } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index b88051e7db..70c307e4e5 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -15,7 +15,10 @@ type portsInfo struct { port string } -func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string) []string { +func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string, isNamespaceSelector bool) []string { + if isNamespaceSelector { + label = "ns-" + label + } partialSpec := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -28,23 +31,23 @@ func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string) []st return util.DropEmptyFields(partialSpec) } -func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag string) []string { +func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag string, isNamespaceSelector bool) []string { var spec []string for i, _ := range ops { - spec = append(spec, craftPartialIptEntrySpecFromOpAndLabel(ops[i], labels[i], srcOrDstFlag)...) + spec = append(spec, craftPartialIptEntrySpecFromOpAndLabel(ops[i], labels[i], srcOrDstFlag, isNamespaceSelector)...) } return spec } -func craftPartialIptEntrySpecFromSelector(selector *metav1.LabelSelector, srcOrDstFlag string) []string { +func craftPartialIptEntrySpecFromSelector(selector *metav1.LabelSelector, srcOrDstFlag string, isNamespaceSelector bool) []string { labelsWithOps, _, _ := parseSelector(selector) ops, labels := GetOperatorsAndLabels(labelsWithOps) - return craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, srcOrDstFlag) + return craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, srcOrDstFlag, isNamespaceSelector) } -func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector) string { +func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector, isNamespaceSelector bool) string { if selector == nil { return "none" } @@ -54,9 +57,15 @@ func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector) str } labelsWithOps, _, _ := parseSelector(selector) - var comment string - for _, labelWithOp := range labelsWithOps { - comment += labelWithOp + ops, labelsWithoutOps := GetOperatorsAndLabels(labelsWithOps) + + var comment, prefix string + if isNamespaceSelector { + prefix = "ns-" + } + + for i, _ := range labelsWithoutOps { + comment += prefix + ops[i] + labelsWithoutOps[i] comment += "-AND-" } @@ -78,8 +87,13 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) sets = append(sets, labels...) - targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag) - targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector) + // targetSelector is empty. Select all pods within the namespace + if len(ops) == 0 && len(labels) == 0 { + ops = append(ops, "") + labels = append(labels, "ns-" + ns) + } + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -215,7 +229,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + fromRule.IPBlock.CIDR + - "-TO-" + craftPartialIptablesCommentFromSelector(&targetSelector), + "-TO-" + targetSelectorComment, ) entries = append(entries, cidrEntry) } @@ -256,8 +270,12 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + for i, _ := range nsLabelsWithoutOps { + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } lists = append(lists, nsLabelsWithoutOps...) - + entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, } @@ -266,6 +284,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne craftPartialIptEntrySpecFromSelector( fromRule.NamespaceSelector, util.IptablesSrcFlag, + true, )..., ) entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) @@ -276,7 +295,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector, true) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -296,6 +315,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne craftPartialIptEntrySpecFromSelector( fromRule.PodSelector, util.IptablesSrcFlag, + false, )..., ) entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) @@ -306,7 +326,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector, false) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -322,6 +342,10 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + for i, _ := range nsLabelsWithoutOps { + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } lists = append(lists, nsLabelsWithoutOps...) podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) @@ -336,6 +360,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne craftPartialIptEntrySpecFromSelector( fromRule.NamespaceSelector, util.IptablesSrcFlag, + true, )..., ) entry.Specs = append( @@ -343,6 +368,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne craftPartialIptEntrySpecFromSelector( fromRule.PodSelector, util.IptablesSrcFlag, + false, )..., ) entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) @@ -353,8 +379,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector) + - "-AND-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector, true) + + "-AND-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector, false) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -362,7 +388,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } log.Printf("finished parsing ingress rule") - return sets, lists, entries + return util.DropEmptyFields(sets), util.DropEmptyFields(lists), entries } func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { @@ -379,9 +405,14 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) + // targetSelector is empty. Select all pods within the namespace + if len(ops) == 0 && len(labels) == 0 { + ops = append(ops, "") + labels = append(labels, "ns-" + ns) + } sets = append(sets, labels...) - targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesSrcFlag) - targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesSrcFlag, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -517,7 +548,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + toRule.IPBlock.CIDR + - "-FROM-" + craftPartialIptablesCommentFromSelector(&targetSelector), + "-FROM-" + targetSelectorComment, ) entries = append(entries, cidrEntry) } @@ -558,6 +589,10 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + for i, _ := range nsLabelsWithoutOps { + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } lists = append(lists, nsLabelsWithoutOps...) entry := &iptm.IptEntry{ @@ -569,6 +604,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net craftPartialIptEntrySpecFromSelector( toRule.NamespaceSelector, util.IptablesDstFlag, + true, )..., ) entry.Specs = append( @@ -579,7 +615,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector), + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector, true), ) entries = append(entries, entry) continue @@ -599,6 +635,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net craftPartialIptEntrySpecFromSelector( toRule.PodSelector, util.IptablesDstFlag, + false, )..., ) entry.Specs = append( @@ -609,7 +646,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector), + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector, false), ) entries = append(entries, entry) continue @@ -624,6 +661,10 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + for i, _ := range nsLabelsWithoutOps { + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } lists = append(lists, nsLabelsWithoutOps...) podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) @@ -639,6 +680,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net craftPartialIptEntrySpecFromSelector( toRule.NamespaceSelector, util.IptablesDstFlag, + true, )..., ) entry.Specs = append( @@ -646,6 +688,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net craftPartialIptEntrySpecFromSelector( toRule.PodSelector, util.IptablesDstFlag, + false, )..., ) entry.Specs = append( @@ -656,65 +699,48 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector) + - "-AND-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector), + "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector, true) + + "-AND-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector, false), ) entries = append(entries, entry) } } log.Printf("finished parsing egress rule") - return sets, lists, entries + return util.DropEmptyFields(sets), util.DropEmptyFields(lists), entries } // Allow traffic from/to kube-system pods func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { - var entries []*iptm.IptEntry - - labels, _, _ := parseSelector(&targetSelector) + var entries []*iptm.IptEntry hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) - for _, label := range labels { - hashedLabelName := util.GetHashedName(label) - allowKubeSystemIngress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemIngress) - - allowKubeSystemEgress := &iptm.IptEntry{ - Name: util.KubeSystemFlag, - Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedLabelName, - util.IptablesSrcFlag, - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - hashedKubeSystemSet, - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - }, - } - entries = append(entries, allowKubeSystemEgress) + allowKubeSystemIngress := &iptm.IptEntry{ + Chain: util.IptablesAzureChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, + } + entries = append(entries, allowKubeSystemIngress) + + allowKubeSystemEgress := &iptm.IptEntry{ + Chain: util.IptablesAzureChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + hashedKubeSystemSet, + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + }, } + entries = append(entries, allowKubeSystemEgress) return entries } @@ -770,7 +796,5 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* } } - resultSets = append(resultSets, npNs) - return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index bec09e65ab..6335cc4ffb 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -15,7 +15,7 @@ import ( func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { srcOp, srcLabel := "", "src" - iptEntry := craftPartialIptEntrySpecFromOpAndLabel(srcOp, srcLabel, util.IptablesSrcFlag) + iptEntry := craftPartialIptEntrySpecFromOpAndLabel(srcOp, srcLabel, util.IptablesSrcFlag, false) expectedIptEntry := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -29,7 +29,7 @@ func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { } dstOp, dstLabel := "!", "dst" - iptEntry = craftPartialIptEntrySpecFromOpAndLabel(dstOp, dstLabel, util.IptablesDstFlag) + iptEntry = craftPartialIptEntrySpecFromOpAndLabel(dstOp, dstLabel, util.IptablesDstFlag, false) expectedIptEntry = []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -68,8 +68,8 @@ func TestCraftPartialIptEntrySpecFromOpsAndLabels(t *testing.T) { } - srcIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(srcOps, srcLabels, util.IptablesSrcFlag) - dstIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(dstOps, dstLabels, util.IptablesDstFlag) + srcIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(srcOps, srcLabels, util.IptablesSrcFlag, false) + dstIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(dstOps, dstLabels, util.IptablesDstFlag, false) iptEntrySpec := append(srcIptEntry, dstIptEntry...) expectedIptEntrySpec := []string{ util.IptablesModuleFlag, @@ -130,7 +130,7 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { }, } - iptEntrySpec := craftPartialIptEntrySpecFromSelector(srcSelector, util.IptablesSrcFlag) + iptEntrySpec := craftPartialIptEntrySpecFromSelector(srcSelector, util.IptablesSrcFlag, false) expectedIptEntrySpec := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -155,7 +155,7 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { var selector *metav1.LabelSelector selector = nil - comment := craftPartialIptablesCommentFromSelector(selector) + comment := craftPartialIptablesCommentFromSelector(selector, false) expectedComment := "none" if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ nil selector comparison") @@ -164,7 +164,7 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { } selector = &metav1.LabelSelector{} - comment = craftPartialIptablesCommentFromSelector(selector) + comment = craftPartialIptablesCommentFromSelector(selector, false) expectedComment = util.KubeAllNamespacesFlag if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ empty selector comparison") @@ -192,13 +192,42 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { }, }, } - comment = craftPartialIptablesCommentFromSelector(selector) + comment = craftPartialIptablesCommentFromSelector(selector, false) expectedComment = "k0:v0-AND-k1:v10-AND-k1:v11-AND-!k2" if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ normal selector comparison") t.Errorf("comment:\n%v", comment) t.Errorf("expectedComment:\n%v", expectedComment) } + + nsSelector := &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "k0": "v0", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "k1", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "v10", + "v11", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "k2", + Operator: metav1.LabelSelectorOpDoesNotExist, + Values: []string{}, + }, + }, + } + comment = craftPartialIptablesCommentFromSelector(nsSelector, true) + expectedComment = "ns-k0:v0-AND-ns-k1:v10-AND-ns-k1:v11-AND-ns-!k2" + if comment != expectedComment { + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ namespace selector comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + } func TestTranslateIngress(t *testing.T) { @@ -313,10 +342,10 @@ func TestTranslateIngress(t *testing.T) { } expectedLists := []string{ - "ns:dev", - "testIn:frontendns", - "planet:earth", - "keyExists", + "ns-ns:dev", + "ns-testIn:frontendns", + "ns-planet:earth", + "ns-keyExists", } if !reflect.DeepEqual(lists, expectedLists) { @@ -391,12 +420,12 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("ns:dev"), + util.GetHashedName("ns-ns:dev"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("testIn:frontendns"), + util.GetHashedName("ns-testIn:frontendns"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -414,7 +443,7 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ns:dev-AND-testIn:frontendns-TO-context:dev-AND-!testNotIn:frontend", + "ALLOW-ns-ns:dev-AND-ns-testIn:frontendns-TO-context:dev-AND-!testNotIn:frontend", }, }, &iptm.IptEntry{ @@ -423,12 +452,12 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("planet:earth"), + util.GetHashedName("ns-planet:earth"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("keyExists"), + util.GetHashedName("ns-keyExists"), util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -457,7 +486,7 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-planet:earth-AND-keyExists-AND-region:northpole-AND-!k-TO-context:dev-AND-!testNotIn:frontend", + "ALLOW-ns-planet:earth-AND-ns-keyExists-AND-region:northpole-AND-!k-TO-context:dev-AND-!testNotIn:frontend", }, }, } @@ -583,10 +612,10 @@ func TestTranslateEgress(t *testing.T) { } expectedLists := []string{ - "ns:dev", - "testIn:frontendns", - "planet:earth", - "keyExists", + "ns-ns:dev", + "ns-testIn:frontendns", + "ns-planet:earth", + "ns-keyExists", } if !reflect.DeepEqual(lists, expectedLists) { @@ -672,19 +701,19 @@ func TestTranslateEgress(t *testing.T) { util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("ns:dev"), + util.GetHashedName("ns-ns:dev"), util.IptablesDstFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("testIn:frontendns"), + util.GetHashedName("ns-testIn:frontendns"), util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-context:dev-AND-!testNotIn:frontend-TO-ns:dev-AND-testIn:frontendns", + "ALLOW-context:dev-AND-!testNotIn:frontend-TO-ns-ns:dev-AND-ns-testIn:frontendns", }, }, &iptm.IptEntry{ @@ -704,12 +733,12 @@ func TestTranslateEgress(t *testing.T) { util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("planet:earth"), + util.GetHashedName("ns-planet:earth"), util.IptablesDstFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("keyExists"), + util.GetHashedName("ns-keyExists"), util.IptablesDstFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -727,7 +756,7 @@ func TestTranslateEgress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-context:dev-AND-!testNotIn:frontend-TO-planet:earth-AND-keyExists-AND-region:northpole-AND-!k", + "ALLOW-context:dev-AND-!testNotIn:frontend-TO-ns-planet:earth-AND-ns-keyExists-AND-region:northpole-AND-!k", }, }, } @@ -739,4 +768,28 @@ func TestTranslateEgress(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } -} \ No newline at end of file +} + +/* +func TestTranslatePolicy(t *testing.T) { + denyAllPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "denyall-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: metav1.LabelSelector{} + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{}, + } + } + + sets, lists, iptEntries := translatePolicy(denyAllPolicy) + expectedSets := []string{ + "test" + } + if !reflect.DeepEqual(sets, ) +} +*/ From 954d8a0f388dd80d4e63f7b9f10a17d94ae06709 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 15 Aug 2019 00:05:29 +0000 Subject: [PATCH 42/64] consistent hashing of metav1.LabelSelector --- npm/parseSelector.go | 84 ++++++++++++ npm/parseSelector_test.go | 177 +++++++++++++++++++++++++ npm/translatePolicy.go | 33 ++++- npm/translatePolicy_test.go | 253 ++++++++++++++++++++++++++++++++++-- npm/util/util.go | 18 +++ npm/util/util_test.go | 20 +++ 6 files changed, 571 insertions(+), 14 deletions(-) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 14b56a7ada..554e8c3c65 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -1,12 +1,72 @@ package npm import ( + "fmt" + "sort" + "container/heap" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/npm/util" ) +// An ReqHeap is a min-heap of labelSelectorRequirements. +type ReqHeap []metav1.LabelSelectorRequirement + +func (h ReqHeap) Len() int { + return len(h) +} + +func (h ReqHeap) Less(i, j int) bool { + sort.Strings(h[i].Values) + sort.Strings(h[j].Values) + + if int(h[i].Key[0]) < int(h[j].Key[0]) { + return true + } + + if int(h[i].Key[0]) > int(h[j].Key[0]) { + return false + } + + if len(h[i].Values) == 0 { + return true + } + + if len(h[j].Values) == 0 { + return false + } + + if len(h[i].Values[0]) == 0 { + return true + } + + if len(h[j].Values[0]) == 0 { + return false + } + + return int(h[i].Values[0][0]) < int(h[j].Values[0][0]) +} + +func (h ReqHeap) Swap(i, j int) { + h[i], h[j] = h[j], h[i] +} + +func (h *ReqHeap) Push(x interface{}) { + sort.Strings(x.(metav1.LabelSelectorRequirement).Values) + *h = append(*h, x.(metav1.LabelSelectorRequirement)) +} + +func (h *ReqHeap) Pop() interface{} { + old := *h + n := len(old) + x := old[n -1] + *h = old[0 : n - 1] + + return x +} + // ParseLabel takes a Azure-NPM processed label then returns if it's referring to complement set, // and if so, returns the original set as well. func ParseLabel(label string) (string, bool) { @@ -43,6 +103,30 @@ func GetOperatorsAndLabels(labelsWithOps []string) ([]string, []string) { return ops, labelsWithoutOps } +// sortSelector sorts the member fields of the selector in an alphebatical order. +func sortSelector(selector *metav1.LabelSelector) { + util.SortMap(&selector.MatchLabels) + + reqHeap := &ReqHeap{} + heap.Init(reqHeap) + for _, req := range selector.MatchExpressions { + heap.Push(reqHeap, req) + } + + var sortedReqs []metav1.LabelSelectorRequirement + for reqHeap.Len() > 0 { + sortedReqs = append(sortedReqs, heap.Pop(reqHeap).(metav1.LabelSelectorRequirement)) + + } + selector.MatchExpressions = sortedReqs +} + +// HashSelector returns the hash value of the selector. +func HashSelector(selector *metav1.LabelSelector) string { + sortSelector(selector) + return util.Hash(fmt.Sprintf("%v", selector)) +} + // parseSelector takes a LabelSelector and returns a slice of processed labels, keys and values. func parseSelector(selector *metav1.LabelSelector) ([]string, []string, []string) { var ( diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index c0fe17fa4f..42e205da82 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -3,6 +3,7 @@ package npm import ( "reflect" "testing" + "container/heap" "github.com/Azure/azure-container-networking/npm/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -122,6 +123,182 @@ func TestGetOperatorsAndLabels(t *testing.T) { } } +func TestReqHeap(t *testing.T) { + reqHeap := &ReqHeap{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "a", + Operator: metav1.LabelSelectorOpIn, + Values: []string{}, + }, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "b", + "a", + }, + }, + } + + heap.Init(reqHeap) + heap.Push( + reqHeap, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "a", + }, + }, + ) + + expectedReqHeap := &ReqHeap{ + metav1.LabelSelectorRequirement{ + Key: "a", + Operator: metav1.LabelSelectorOpIn, + Values: []string{}, + }, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "a", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "a", + "b", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "backend", + "frontend", + }, + }, + } + + if !reflect.DeepEqual(reqHeap, expectedReqHeap) { + t.Errorf("TestReqHeap failed @ heap comparison") + t.Errorf("reqHeap: %v", reqHeap) + t.Errorf("expectedReqHeap: %v", expectedReqHeap) + } +} + +func TestSortSelector(t *testing.T) { + selector := &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "a", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "b", + }, + }, + }, + MatchLabels: map[string]string{ + "c": "d", + "a": "b", + }, + } + + sortSelector(selector) + expectedSelector := &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "a", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "b", + }, + }, + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "backend", + "frontend", + }, + }, + }, + MatchLabels: map[string]string{ + "a": "b", + "c": "d", + }, + } + + if !reflect.DeepEqual(selector, expectedSelector) { + t.Errorf("TestSortSelector failed @ sort selector comparison") + t.Errorf("selector: %v", selector) + t.Errorf("expectedSelector: %v", expectedSelector) + } +} + +func TestHashSelector(t *testing.T) { + firstSelector := &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "frontend", + "backend", + }, + }, + }, + MatchLabels: map[string]string{ + "a": "b", + "c": "d", + }, + } + + secondSelector := &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testIn", + Operator: metav1.LabelSelectorOpIn, + Values: []string{ + "backend", + "frontend", + }, + }, + }, + MatchLabels: map[string]string{ + "c": "d", + "a": "b", + }, + } + + hashedFirstSelector := HashSelector(firstSelector) + hashedSecondSelector := HashSelector(secondSelector) + if hashedFirstSelector != hashedSecondSelector { + t.Errorf("TestHashSelector failed @ hashed selector comparison") + t.Errorf("hashedFirstSelector: %v", hashedFirstSelector) + t.Errorf("hashedSecondSelector: %v", hashedSecondSelector) + } +} + func TestParseSelector(t *testing.T) { var selector, expectedSelector *metav1.LabelSelector selector, expectedSelector = nil, nil diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 70c307e4e5..b209f17d4a 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -94,6 +94,28 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) + + // Allow all ingress + if len(rules) == 0 { + lists = append(lists, util.KubeAllNamespacesFlag) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: targetSelectorIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + targetSelectorComment, + ) + + entries = append(entries, entry) + } + for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -119,7 +141,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !portRuleExists && !fromRuleExists { entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, + Chain: util.IptablesAzureIngressPortChain, Specs: targetSelectorIptEntrySpec, } entry.Specs = append( @@ -275,7 +297,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] } lists = append(lists, nsLabelsWithoutOps...) - + entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressFromChain, } @@ -438,7 +460,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if !portRuleExists && !toRuleExists { entry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToChain, + Chain: util.IptablesAzureEgressPortChain, Specs: targetSelectorIptEntrySpec, } entry.Specs = append( @@ -762,9 +784,8 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* log.Printf("Translating network policy:\n %+v", npObj) npNs := npObj.ObjectMeta.Namespace - if len(npObj.Spec.Ingress) > 0 || len(npObj.Spec.Egress) > 0 { - entries = append(entries, getAllowKubeSystemEntries(npNs, npObj.Spec.PodSelector)...) - } + // Allow kube-system pods + entries = append(entries, getAllowKubeSystemEntries(npNs, npObj.Spec.PodSelector)...) if len(npObj.Spec.PolicyTypes) == 0 { ingressSets, ingressLists, ingressEntries := translateIngress(npNs, npObj.Spec.PodSelector, npObj.Spec.Ingress) diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 6335cc4ffb..cc842e4ee9 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -770,26 +770,263 @@ func TestTranslateEgress(t *testing.T) { } } -/* func TestTranslatePolicy(t *testing.T) { + targetSelector := metav1.LabelSelector{} denyAllPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "denyall-policy", + Name: "deny-all-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{} + PodSelector: targetSelector, PolicyTypes: []networkingv1.PolicyType{ networkingv1.PolicyTypeIngress, }, Ingress: []networkingv1.NetworkPolicyIngressRule{}, - } + }, } sets, lists, iptEntries := translatePolicy(denyAllPolicy) - expectedSets := []string{ - "test" + + expectedSets := []string{} + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ deny-all-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists := []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ deny-all-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + /* + expectedIptEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-testnamespace"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-ns-testnamespace", + }, + }, + } + */ + expectedIptEntries := []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ deny-all-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "backend", + }, + } + allowFromPodsPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allow-from-pods-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + }, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowFromPodsPolicy) + + expectedSets = []string{ + "app:backend", + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ deny-all-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ deny-all-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries := []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:backend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-app:frontend-TO-app:backend", + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ allow-from-pods-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + allowToFrontendPodsPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allow-all-to-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{}, + }, + } + + sets, lists, iptEntries = translatePolicy(allowToFrontendPodsPolicy) + + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + util.KubeAllNamespacesFlag, + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend", + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } - if !reflect.DeepEqual(sets, ) + } -*/ diff --git a/npm/util/util.go b/npm/util/util.go index 321d1dc6a4..d8200e3ec1 100644 --- a/npm/util/util.go +++ b/npm/util/util.go @@ -8,6 +8,7 @@ import ( "os" "strconv" "strings" + "sort" "k8s.io/apimachinery/pkg/version" ) @@ -43,6 +44,23 @@ func Hash(s string) string { return fmt.Sprint(h.Sum32()) } +// SortMap sorts the map by key in alphabetical order. +// Note: even though the map is sorted, accessing it through range will still result in random order. +func SortMap(m *map[string]string) { + var sortedKeys []string + for k := range *m { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + + sortedMap := &map[string]string{} + for _, k := range sortedKeys { + (*sortedMap)[k] = (*m)[k] + } + + m = sortedMap +} + // UniqueStrSlice removes duplicate elements from the input string. func UniqueStrSlice(s []string) []string { m, unique := map[string]bool{}, []string{} diff --git a/npm/util/util_test.go b/npm/util/util_test.go index 00603815f5..85ef95c26b 100644 --- a/npm/util/util_test.go +++ b/npm/util/util_test.go @@ -7,6 +7,26 @@ import ( "k8s.io/apimachinery/pkg/version" ) +func TestSortMap(t *testing.T) { + m := &map[string]string{ + "e": "f", + "c": "d", + "a": "b", + } + + SortMap(m) + expectedMap := &map[string]string{ + "a": "b", + "c": "d", + "e": "f", + } + if !reflect.DeepEqual(m, expectedMap) { + t.Errorf("TestSortMap failed @ map comparison") + t.Errorf("m: %v", m) + t.Errorf("expectedMap: %v", expectedMap) + } +} + func TestCompareK8sVer(t *testing.T) { firstVer := &version.Info{ Major: "!", From 3f3d120c6c17bd7170476358a0404cb6174f4fc4 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 16 Aug 2019 00:13:27 +0000 Subject: [PATCH 43/64] use podSelector as key for processedNpMap --- npm/nwpolicy.go | 102 +++++++++++++++++------------------- npm/parsePolicy.go | 6 +-- npm/translatePolicy.go | 25 ++------- npm/translatePolicy_test.go | 23 ++------ 4 files changed, 57 insertions(+), 99 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index c58200ff6d..b7acc3c6b1 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -3,6 +3,7 @@ package npm import ( + "github.com/Azure/azure-container-networking/npm/iptm" "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/npm/util" networkingv1 "k8s.io/api/networking/v1" @@ -60,65 +61,54 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP npMgr.isAzureNpmChainCreated = true } - labels, newPolicies := splitPolicy(npObj) - var ( - addedPolicy *networkingv1.NetworkPolicy - oldPolicies []*networkingv1.NetworkPolicy - addedPolicies []*networkingv1.NetworkPolicy - ) - for i := range newPolicies { - label, newPolicy := labels[i], newPolicies[i] - if oldPolicy, exists := ns.processedNpMap[label]; exists { - addedPolicy, err = addPolicy(oldPolicy, newPolicy) - oldPolicies = append(oldPolicies, oldPolicy) - addedPolicies = append(addedPolicies, addedPolicy) - } else { - ns.processedNpMap[label] = newPolicy - addedPolicies = append(addedPolicies, newPolicy) - } - } + hashedSelector := HashSelector(&npObj.Spec.PodSelector) - npMgr.Unlock() - for _, oldPolicy := range oldPolicies { + var addedPolicy *networkingv1.NetworkPolicy + addedPolicy = nil + if oldPolicy, oldPolicyExists := ns.processedNpMap[hashedSelector]; oldPolicyExists { + addedPolicy, err = addPolicy(oldPolicy, npObj) + if err != nil { + log.Printf("Error adding policy %s to %s", npName, oldPolicy.ObjectMeta.Name) + } + npMgr.Unlock() npMgr.DeleteNetworkPolicy(oldPolicy) + npMgr.Lock() + } else { + ns.processedNpMap[hashedSelector] = npObj } - npMgr.Lock() - - for _, addedPolicy = range addedPolicies { - sets, lists, iptEntries := translatePolicy(addedPolicy) - ipsMgr := allNs.ipsMgr - for _, set := range sets { - if err = ipsMgr.CreateSet(set); err != nil { - log.Printf("Error creating ipset %s-%s\n", npNs, set) - return err - } - } - - for _, list := range lists { - if err = ipsMgr.CreateList(list); err != nil { - log.Printf("Error creating ipset list %s-%s\n", npNs, list) - return err - } + var sets, lists []string + var iptEntries []*iptm.IptEntry + if addedPolicy != nil { + sets, lists, iptEntries = translatePolicy(addedPolicy) + } else { + sets, lists, iptEntries = translatePolicy(npObj) + } + ipsMgr := allNs.ipsMgr + for _, set := range sets { + if err = ipsMgr.CreateSet(set); err != nil { + log.Printf("Error creating ipset %s-%s\n", npNs, set) + return err } - - if err = npMgr.InitAllNsList(); err != nil { - log.Printf("Error initializing all-namespace ipset list.\n") + } + for _, list := range lists { + if err = ipsMgr.CreateList(list); err != nil { + log.Printf("Error creating ipset list %s-%s\n", npNs, list) return err } - - iptMgr := allNs.iptMgr - for _, iptEntry := range iptEntries { - if err = iptMgr.Add(iptEntry); err != nil { - log.Printf("Error applying iptables rule\n. Rule: %+v", iptEntry) - return err - } + } + if err = npMgr.InitAllNsList(); err != nil { + log.Printf("Error initializing all-namespace ipset list.\n") + return err + } + iptMgr := allNs.iptMgr + for _, iptEntry := range iptEntries { + if err = iptMgr.Add(iptEntry); err != nil { + log.Printf("Error applying iptables rule\n. Rule: %+v", iptEntry) + return err } - } - ns.rawNpMap[npName] = npObj - return nil } @@ -163,10 +153,6 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo npMgr.nsMap[npName] = ns } - if !ns.policyExists(npObj) { - return nil - } - allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] _, _, iptEntries := translatePolicy(npObj) @@ -179,8 +165,14 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo } } - delete(ns.rawNpMap, npName) - + hashedSelector := HashSelector(&npObj.Spec.PodSelector) + if oldPolicy, oldPolicyExists := ns.processedNpMap[hashedSelector]; oldPolicyExists { + ns.processedNpMap[hashedSelector], err = deductPolicy(oldPolicy, npObj) + if err != nil { + log.Printf("Error deducting policy %s from %s", npName, oldPolicy.ObjectMeta.Name) + } + } + if npMgr.canCleanUpNpmChains() { if err = iptMgr.UninitNpmChains(); err != nil { log.Errorf("Error: failed to uninitialize azure-npm chains.") diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 585c1989f8..cea002c6cf 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -53,8 +53,8 @@ func addPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolic return nil, fmt.Errorf("Old and new networkpolicies don't have the same namespace") } - if len(old.Spec.PodSelector.MatchLabels) != 1 || !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { - return nil, fmt.Errorf("Old and new networkpolicies don't have apply to the same set of target pods") + if !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { + return nil, fmt.Errorf("Old and new networkpolicies don't apply to the same set of target pods") } addedPolicy := &networkingv1.NetworkPolicy{ @@ -99,7 +99,7 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo return nil, fmt.Errorf("Old and new networkpolicy don't have the same namespace") } - if len(old.Spec.PodSelector.MatchLabels) != 1 || !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { + if !reflect.DeepEqual(old.Spec.PodSelector, new.Spec.PodSelector) { return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index b209f17d4a..7d913a458c 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -86,36 +86,15 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) - sets = append(sets, labels...) // targetSelector is empty. Select all pods within the namespace if len(ops) == 0 && len(labels) == 0 { ops = append(ops, "") labels = append(labels, "ns-" + ns) } + sets = append(sets, labels...) targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) - // Allow all ingress - if len(rules) == 0 { - lists = append(lists, util.KubeAllNamespacesFlag) - - entry := &iptm.IptEntry{ - Chain: util.IptablesAzureIngressPortChain, - Specs: targetSelectorIptEntrySpec, - } - entry.Specs = append( - entry.Specs, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + targetSelectorComment, - ) - - entries = append(entries, entry) - } - for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -155,6 +134,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne ) entries = append(entries, entry) + lists = append(lists, util.KubeAllNamespacesFlag) continue } @@ -474,6 +454,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net ) entries = append(entries, entry) + lists = append(lists, util.KubeAllNamespacesFlag) continue } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index cc842e4ee9..190c127432 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -788,7 +788,7 @@ func TestTranslatePolicy(t *testing.T) { sets, lists, iptEntries := translatePolicy(denyAllPolicy) - expectedSets := []string{} + expectedSets := []string{"ns-testnamespace"} if !reflect.DeepEqual(sets, expectedSets) { t.Errorf("translatedPolicy failed @ deny-all-policy sets comparison") t.Errorf("sets: %v", sets) @@ -955,7 +955,9 @@ func TestTranslatePolicy(t *testing.T) { PolicyTypes: []networkingv1.PolicyType{ networkingv1.PolicyTypeIngress, }, - Ingress: []networkingv1.NetworkPolicyIngressRule{}, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{}, + }, }, } @@ -988,23 +990,6 @@ func TestTranslatePolicy(t *testing.T) { nonKubeSystemEntries = []*iptm.IptEntry{ &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - util.GetHashedName("app:frontend"), - util.IptablesDstFlag, - util.IptablesJumpFlag, - util.IptablesAzureIngressFromChain, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + - util.IptablesAzureIngressFromChain, - }, - }, - &iptm.IptEntry{ - Chain: util.IptablesAzureIngressFromChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, From 01abe6d6510fa21c6fe283ef55c132e861adb39c Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 16 Aug 2019 00:43:10 +0000 Subject: [PATCH 44/64] address Kaleb's comments --- npm/namespace.go | 8 ++++---- npm/nwpolicy.go | 8 ++++---- npm/pod.go | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/npm/namespace.go b/npm/namespace.go index 03939a579d..8539cebdf8 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -111,14 +111,14 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { // Add the namespace to its label's ipset list. nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetHashedName("ns-" + nsLabelKey) + labelKey := "ns-" + nsLabelKey log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) if err = ipsMgr.AddToList(labelKey, nsName); err != nil { log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) return err } - label := util.GetHashedName("ns-" + nsLabelKey + ":" + nsLabelVal) + label := "ns-" + nsLabelKey + ":" + nsLabelVal log.Printf("Adding namespace %s to ipset list %s", nsName, label) if err = ipsMgr.AddToList(label, nsName); err != nil { log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, label) @@ -178,14 +178,14 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { - labelKey := util.GetHashedName("ns-" + nsLabelKey) + labelKey := "ns-" + nsLabelKey log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) return err } - label := util.GetHashedName("ns-" + nsLabelKey + ":" + nsLabelVal) + label := "ns-" + nsLabelKey + ":" + nsLabelVal log.Printf("Deleting namespace %s from ipset list %s", nsName, label) if err = ipsMgr.DeleteFromList(label, nsName); err != nil { log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, label) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index b7acc3c6b1..98d8718f78 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -87,18 +87,18 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ipsMgr := allNs.ipsMgr for _, set := range sets { if err = ipsMgr.CreateSet(set); err != nil { - log.Printf("Error creating ipset %s-%s\n", npNs, set) + log.Printf("Error creating ipset %s", set) return err } } for _, list := range lists { if err = ipsMgr.CreateList(list); err != nil { - log.Printf("Error creating ipset list %s-%s\n", npNs, list) + log.Printf("Error creating ipset list %s", list) return err } } if err = npMgr.InitAllNsList(); err != nil { - log.Printf("Error initializing all-namespace ipset list.\n") + log.Printf("Error initializing all-namespace ipset list.") return err } iptMgr := allNs.iptMgr @@ -148,7 +148,7 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo if ns, exists = npMgr.nsMap[npName]; !exists { ns, err = newNs(npName) if err != nil { - log.Printf("Error creating namespace %s\n", npName) + log.Printf("Error creating namespace %s", npName) } npMgr.nsMap[npName] = ns } diff --git a/npm/pod.go b/npm/pod.go index f2575c3313..3c63e49ebb 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -44,7 +44,7 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Add the pod to its namespace's ipset. log.Printf("Adding pod %s to ipset %s", podIP, podNs) - if err = ipsMgr.AddToSet(podNs, podIP); err != nil { + if err = ipsMgr.AddToSet("ns-" + podNs, podIP); err != nil { log.Errorf("Error: failed to add pod to namespace ipset.") return err } @@ -139,7 +139,7 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { // Delete pod from ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Delete the pod from its namespace's ipset. - if err = ipsMgr.DeleteFromSet(podNs, podIP); err != nil { + if err = ipsMgr.DeleteFromSet("ns-" + podNs, podIP); err != nil { log.Errorf("Error: failed to delete pod from namespace ipset.") return err } From 4fd8b8a9ddb4710a520db9971f8746aacf0fe78a Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 16 Aug 2019 00:45:52 +0000 Subject: [PATCH 45/64] consistent prefix to namespace --- npm/nwpolicy.go | 2 +- npm/pod.go | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 98d8718f78..ca0c2ec68d 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -29,7 +29,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP ns *namespace ) - npNs, npName := npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name + npNs, npName := "ns-" + npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name log.Printf("NETWORK POLICY CREATING: %v", npObj) var exists bool diff --git a/npm/pod.go b/npm/pod.go index 3c63e49ebb..5902cbfb0a 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -33,7 +33,7 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { var err error - podNs := podObj.ObjectMeta.Namespace + podNs := "ns-" + podObj.ObjectMeta.Namespace podName := podObj.ObjectMeta.Name podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels @@ -44,7 +44,7 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Add the pod to its namespace's ipset. log.Printf("Adding pod %s to ipset %s", podIP, podNs) - if err = ipsMgr.AddToSet("ns-" + podNs, podIP); err != nil { + if err = ipsMgr.AddToSet(podNs, podIP); err != nil { log.Errorf("Error: failed to add pod to namespace ipset.") return err } @@ -129,7 +129,7 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { var err error - podNs := podObj.ObjectMeta.Namespace + podNs := "ns-" + podObj.ObjectMeta.Namespace podName := podObj.ObjectMeta.Name podNodeName := podObj.Spec.NodeName podLabels := podObj.ObjectMeta.Labels From 4ca90f63b2a998270aa7269916fe846708cfe995 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Sat, 17 Aug 2019 00:05:15 +0000 Subject: [PATCH 46/64] testing --- npm/ipsm/ipsm.go | 4 +++ npm/namespace.go | 82 +++++++++++++++++++++--------------------- npm/npm.go | 2 ++ npm/nwpolicy.go | 26 ++++++++++---- npm/nwpolicy_test.go | 36 ++++++++++++++++--- npm/parsePolicy.go | 6 ++++ npm/translatePolicy.go | 15 ++++++-- 7 files changed, 117 insertions(+), 54 deletions(-) diff --git a/npm/ipsm/ipsm.go b/npm/ipsm/ipsm.go index 7b52c2d233..79c08fc853 100644 --- a/npm/ipsm/ipsm.go +++ b/npm/ipsm/ipsm.go @@ -119,6 +119,10 @@ func (ipsMgr *IpsetManager) DeleteList(listName string) error { // AddToList inserts an ipset to an ipset list. func (ipsMgr *IpsetManager) AddToList(listName string, setName string) error { + if listName == setName { + return nil + } + if ipsMgr.Exists(listName, setName, util.IpsetSetListFlag) { return nil } diff --git a/npm/namespace.go b/npm/namespace.go index 8539cebdf8..135691ed15 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -55,13 +55,13 @@ func (ns *namespace) policyExists(npObj *networkingv1.NetworkPolicy) bool { // InitAllNsList syncs all-namespace ipset list. func (npMgr *NetworkPolicyManager) InitAllNsList() error { allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] - for nsName := range npMgr.nsMap { - if nsName == util.KubeAllNamespacesFlag { + for ns:= range npMgr.nsMap { + if ns == util.KubeAllNamespacesFlag { continue } - if err := allNs.ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("Error: failed to add namespace set %s to list %s", nsName, util.KubeAllNamespacesFlag) + if err := allNs.ipsMgr.AddToList(util.KubeAllNamespacesFlag, ns); err != nil { + log.Errorf("Error: failed to add namespace set %s to ipset list %s", ns, util.KubeAllNamespacesFlag) return err } } @@ -72,13 +72,13 @@ func (npMgr *NetworkPolicyManager) InitAllNsList() error { // UninitAllNsList cleans all-namespace ipset list. func (npMgr *NetworkPolicyManager) UninitAllNsList() error { allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] - for nsName := range npMgr.nsMap { - if nsName == util.KubeAllNamespacesFlag { + for ns := range npMgr.nsMap { + if ns == util.KubeAllNamespacesFlag { continue } - if err := allNs.ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("Error: failed to delete namespace set %s from list %s", nsName, util.KubeAllNamespacesFlag) + if err := allNs.ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, ns); err != nil { + log.Errorf("Error: failed to delete namespace set %s from list %s", ns, util.KubeAllNamespacesFlag) return err } } @@ -93,18 +93,18 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var err error - nsName, nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("NAMESPACE CREATING: [%s/%s/%+v]", nsName, nsNs, nsLabel) + nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + log.Printf("NAMESPACE CREATING: [%s/%v]", nsNs, nsLabel) ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Create ipset for the namespace. - if err = ipsMgr.CreateSet(nsName); err != nil { - log.Errorf("Error: failed to create ipset for namespace %s.", nsName) + if err = ipsMgr.CreateSet(nsNs); err != nil { + log.Errorf("Error: failed to create ipset for namespace %s.", nsNs) return err } - if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("Error: failed to add %s to all-namespace ipset list.", nsName) + if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsNs); err != nil { + log.Errorf("Error: failed to add %s to all-namespace ipset list.", nsNs) return err } @@ -112,25 +112,25 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := "ns-" + nsLabelKey - log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) - if err = ipsMgr.AddToList(labelKey, nsName); err != nil { - log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) + log.Printf("Adding namespace %s to ipset list %s", nsNs, labelKey) + if err = ipsMgr.AddToList(labelKey, nsNs); err != nil { + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsNs, labelKey) return err } label := "ns-" + nsLabelKey + ":" + nsLabelVal - log.Printf("Adding namespace %s to ipset list %s", nsName, label) - if err = ipsMgr.AddToList(label, nsName); err != nil { - log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, label) + log.Printf("Adding namespace %s to ipset list %s", nsNs, label) + if err = ipsMgr.AddToList(label, nsNs); err != nil { + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsNs, label) return err } } - ns, err := newNs(nsName) + ns, err := newNs(nsNs) if err != nil { - log.Errorf("Error: failed to create namespace %s", nsName) + log.Errorf("Error: failed to create namespace %s", nsNs) } - npMgr.nsMap[nsName] = ns + npMgr.nsMap[nsNs] = ns return nil } @@ -139,11 +139,11 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { func (npMgr *NetworkPolicyManager) UpdateNamespace(oldNsObj *corev1.Namespace, newNsObj *corev1.Namespace) error { var err error - oldNsName, oldNsNs, oldNsLabel := "ns-" + oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels - newNsName, newNsNs, newNsLabel := "ns-" + newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels + oldNsNs, oldNsLabel := "ns-" + oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels + newNsNs, newNsLabel := "ns-" + newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels log.Printf( - "NAMESPACE UPDATING:\n old namespace: [%s/%s/%+v]\n new namespace: [%s/%s/%+v]", - oldNsName, oldNsNs, oldNsLabel, newNsName, newNsNs, newNsLabel, + "NAMESPACE UPDATING:\n old namespace: [%s/%v]\n new namespace: [%s/%v]", + oldNsNs, oldNsLabel, newNsNs, newNsLabel, ) if err = npMgr.DeleteNamespace(oldNsObj); err != nil { @@ -166,10 +166,10 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var err error - nsName, nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("NAMESPACE DELETING: [%s/%s/%+v]", nsName, nsNs, nsLabel) + nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels + log.Printf("NAMESPACE DELETING: [%s/%v]", nsNs, nsLabel) - _, exists := npMgr.nsMap[nsName] + _, exists := npMgr.nsMap[nsNs] if !exists { return nil } @@ -179,33 +179,33 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := "ns-" + nsLabelKey - log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) - if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) + log.Printf("Deleting namespace %s from ipset list %s", nsNs, labelKey) + if err = ipsMgr.DeleteFromList(labelKey, nsNs); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, labelKey) return err } label := "ns-" + nsLabelKey + ":" + nsLabelVal - log.Printf("Deleting namespace %s from ipset list %s", nsName, label) - if err = ipsMgr.DeleteFromList(label, nsName); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, label) + log.Printf("Deleting namespace %s from ipset list %s", nsNs, label) + if err = ipsMgr.DeleteFromList(label, nsNs); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, label) return err } } // Delete the namespace from all-namespace ipset list. - if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, util.KubeAllNamespacesFlag) + if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsNs); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, util.KubeAllNamespacesFlag) return err } // Delete ipset for the namespace. - if err = ipsMgr.DeleteSet(nsName); err != nil { - log.Errorf("Error: failed to delete ipset for namespace %s.", nsName) + if err = ipsMgr.DeleteSet(nsNs); err != nil { + log.Errorf("Error: failed to delete ipset for namespace %s.", nsNs) return err } - delete(npMgr.nsMap, nsName) + delete(npMgr.nsMap, nsNs) return nil } diff --git a/npm/npm.go b/npm/npm.go index fdab95e5c0..d7b39af855 100644 --- a/npm/npm.go +++ b/npm/npm.go @@ -48,6 +48,7 @@ type NetworkPolicyManager struct { nodeName string nsMap map[string]*namespace isAzureNpmChainCreated bool + isSafeToCleanUpAzureNpmChain bool clusterState telemetry.ClusterState reportManager *telemetry.ReportManager @@ -219,6 +220,7 @@ func NewNetworkPolicyManager(clientset *kubernetes.Clientset, informerFactory in nodeName: os.Getenv("HOSTNAME"), nsMap: make(map[string]*namespace), isAzureNpmChainCreated: false, + isSafeToCleanUpAzureNpmChain: false, clusterState: telemetry.ClusterState{ PodCount: 0, NsCount: 0, diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index ca0c2ec68d..2c981bb1b1 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -10,8 +10,12 @@ import ( ) func (npMgr *NetworkPolicyManager) canCleanUpNpmChains() bool { + if !npMgr.isSafeToCleanUpAzureNpmChain { + return false + } + for _, ns := range npMgr.nsMap { - if len(ns.rawNpMap) > 0 { + if len(ns.processedNpMap) > 0 { return false } } @@ -70,9 +74,11 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP if err != nil { log.Printf("Error adding policy %s to %s", npName, oldPolicy.ObjectMeta.Name) } + npMgr.isSafeToCleanUpAzureNpmChain = false npMgr.Unlock() npMgr.DeleteNetworkPolicy(oldPolicy) npMgr.Lock() + npMgr.isSafeToCleanUpAzureNpmChain = true } else { ns.processedNpMap[hashedSelector] = npObj } @@ -141,16 +147,16 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo ns *namespace ) - npName := npObj.ObjectMeta.Name + npNs, npName := "ns-" + npObj.ObjectMeta.Namespace, npObj.ObjectMeta.Name log.Printf("NETWORK POLICY DELETING: %v", npObj) var exists bool - if ns, exists = npMgr.nsMap[npName]; !exists { + if ns, exists = npMgr.nsMap[npNs]; !exists { ns, err = newNs(npName) if err != nil { - log.Printf("Error creating namespace %s", npName) + log.Printf("Error creating namespace %s", npNs) } - npMgr.nsMap[npName] = ns + npMgr.nsMap[npNs] = ns } allNs := npMgr.nsMap[util.KubeAllNamespacesFlag] @@ -167,12 +173,18 @@ func (npMgr *NetworkPolicyManager) DeleteNetworkPolicy(npObj *networkingv1.Netwo hashedSelector := HashSelector(&npObj.Spec.PodSelector) if oldPolicy, oldPolicyExists := ns.processedNpMap[hashedSelector]; oldPolicyExists { - ns.processedNpMap[hashedSelector], err = deductPolicy(oldPolicy, npObj) + deductedPolicy, err := deductPolicy(oldPolicy, npObj) if err != nil { log.Printf("Error deducting policy %s from %s", npName, oldPolicy.ObjectMeta.Name) } - } + if deductedPolicy == nil { + delete(ns.processedNpMap, hashedSelector) + } else { + ns.processedNpMap[hashedSelector] = deductedPolicy + } + } + if npMgr.canCleanUpNpmChains() { if err = iptMgr.UninitNpmChains(); err != nil { log.Errorf("Error: failed to uninitialize azure-npm chains.") diff --git a/npm/nwpolicy_test.go b/npm/nwpolicy_test.go index 1a2445929b..616c3ea8e1 100644 --- a/npm/nwpolicy_test.go +++ b/npm/nwpolicy_test.go @@ -54,7 +54,7 @@ func TestAddNetworkPolicy(t *testing.T) { nsObj := &corev1.Namespace{ ObjectMeta: metav1.ObjectMeta{ - Name: "test-nwpolicy", + Namespace: "test-nwpolicy", Labels: map[string]string{ "app": "test-namespace", }, @@ -66,7 +66,7 @@ func TestAddNetworkPolicy(t *testing.T) { } tcp := corev1.ProtocolTCP - allow := &networkingv1.NetworkPolicy{ + allowIngress := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "allow-ingress", Namespace: "test-nwpolicy", @@ -90,8 +90,36 @@ func TestAddNetworkPolicy(t *testing.T) { }, } - if err := npMgr.AddNetworkPolicy(allow); err != nil { - t.Errorf("TestAddNetworkPolicy failed @ AddNetworkPolicy") + if err := npMgr.AddNetworkPolicy(allowIngress); err != nil { + t.Errorf("TestAddNetworkPolicy failed @ allowIngress AddNetworkPolicy") + } + + allowEgress := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "allow-egress", + Namespace: "test-nwpolicy", + }, + Spec: networkingv1.NetworkPolicySpec{ + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + To: []networkingv1.NetworkPolicyPeer{{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "test"}, + }, + }}, + Ports: []networkingv1.NetworkPolicyPort{{ + Protocol: &tcp, + Port: &intstr.IntOrString{ + StrVal: "8000", + }, + }}, + }, + }, + }, + } + + if err := npMgr.AddNetworkPolicy(allowEgress); err != nil { + t.Errorf("TestAddNetworkPolicy failed @ allowEgress AddNetworkPolicy") } } diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index cea002c6cf..a19f4f5907 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -103,6 +103,10 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo return nil, fmt.Errorf("Old and new networkpolicy don't have apply to the same set of target pods") } + if reflect.DeepEqual(old.Spec, new.Spec) { + return nil, nil + } + deductedPolicy := &networkingv1.NetworkPolicy{ TypeMeta: old.TypeMeta, ObjectMeta: metav1.ObjectMeta{ @@ -134,9 +138,11 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo } } + /* if len(deductedIngress) == 0 && len(deductedEgress) == 0 { return nil, nil } + */ deductedPolicy.Spec.Ingress = deductedIngress deductedPolicy.Spec.Egress = deductedEgress diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 7d913a458c..97ae738edd 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -715,8 +715,9 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net // Allow traffic from/to kube-system pods func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { - var entries []*iptm.IptEntry - hashedKubeSystemSet := util.GetHashedName(util.KubeSystemFlag) + var entries []*iptm.IptEntry + hashedKubeSystemSet := util.GetHashedName("ns-" + util.KubeSystemFlag) + targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) allowKubeSystemIngress := &iptm.IptEntry{ Chain: util.IptablesAzureChain, Specs: []string{ @@ -727,6 +728,11 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ util.IptablesSrcFlag, util.IptablesJumpFlag, util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + "ns-" + util.KubeSystemFlag + + "-TO-" + targetSelectorComment, }, } entries = append(entries, allowKubeSystemIngress) @@ -741,6 +747,11 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-" + targetSelectorComment + + "-TO-" + "ns-" + util.KubeSystemFlag, }, } entries = append(entries, allowKubeSystemEgress) From cf832908172f705ae371780c3768169a37c869d6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 19 Aug 2019 21:53:20 +0000 Subject: [PATCH 47/64] address Kaleb's comment --- npm/translatePolicy.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 97ae738edd..8885e735aa 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -513,13 +513,13 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } } else { entry := &iptm.IptEntry{ - Chain: util.IptablesAzureEgressToChain, + Chain: util.IptablesAzureEgressPortChain, } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( entry.Specs, util.IptablesJumpFlag, - util.IptablesAzureEgressToChain, + util.IptablesAzureEgressPortChain, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, From 0e87a719ea1cbf8b8ae1546e194cf82b10ca8bc9 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 22 Aug 2019 23:29:24 +0000 Subject: [PATCH 48/64] handle empty selector --- npm/parseSelector.go | 10 +- npm/translatePolicy.go | 102 ++++++++---- npm/translatePolicy_test.go | 302 +++++++++++++++++++++++++++++++++--- 3 files changed, 367 insertions(+), 47 deletions(-) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 554e8c3c65..1b0f4cd878 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -135,7 +135,15 @@ func parseSelector(selector *metav1.LabelSelector) ([]string, []string, []string vals []string ) - if selector == nil || (len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0) { + if selector == nil { + return labels, keys, vals + } + + if len(selector.MatchLabels) == 0 && len(selector.MatchExpressions) == 0 { + labels = append(labels, "") + keys = append(keys, "") + vals = append(vals, "") + return labels, keys, vals } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 8885e735aa..e0c8a7c887 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -31,8 +31,36 @@ func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string, isNa return util.DropEmptyFields(partialSpec) } -func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag string, isNamespaceSelector bool) []string { +func craftPartialIptEntrySpecFromOpsAndLabels(ns string, ops, labels []string, srcOrDstFlag string, isNamespaceSelector bool) []string { var spec []string + + if len(ops) == 1 && len(labels) == 1 { + if ops[0] == "" && labels[0] == "" { + if !isNamespaceSelector { + // This is an empty podSelector, + // selecting all the pods within its namespace. + spec = []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-" + ns), + srcOrDstFlag, + } + } else { + // This is an empty namespaceSelector, + // selecting all namespaces. + spec = []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + srcOrDstFlag, + } + } + + return spec + } + } for i, _ := range ops { spec = append(spec, craftPartialIptEntrySpecFromOpAndLabel(ops[i], labels[i], srcOrDstFlag, isNamespaceSelector)...) @@ -41,19 +69,23 @@ func craftPartialIptEntrySpecFromOpsAndLabels(ops, labels []string, srcOrDstFlag return spec } -func craftPartialIptEntrySpecFromSelector(selector *metav1.LabelSelector, srcOrDstFlag string, isNamespaceSelector bool) []string { +func craftPartialIptEntrySpecFromSelector(ns string, selector *metav1.LabelSelector, srcOrDstFlag string, isNamespaceSelector bool) []string { labelsWithOps, _, _ := parseSelector(selector) ops, labels := GetOperatorsAndLabels(labelsWithOps) - return craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, srcOrDstFlag, isNamespaceSelector) + return craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, srcOrDstFlag, isNamespaceSelector) } -func craftPartialIptablesCommentFromSelector(selector *metav1.LabelSelector, isNamespaceSelector bool) string { +func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSelector, isNamespaceSelector bool) string { if selector == nil { return "none" } if len(selector.MatchExpressions) == 0 && len(selector.MatchLabels) == 0 { - return util.KubeAllNamespacesFlag + if isNamespaceSelector { + return util.KubeAllNamespacesFlag + } + + return "ns-" + ns } labelsWithOps, _, _ := parseSelector(selector) @@ -86,14 +118,9 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) - // targetSelector is empty. Select all pods within the namespace - if len(ops) == 0 && len(labels) == 0 { - ops = append(ops, "") - labels = append(labels, "ns-" + ns) - } sets = append(sets, labels...) - targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesDstFlag, false) - targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesDstFlag, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { // parse Ports field @@ -284,6 +311,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, fromRule.NamespaceSelector, util.IptablesSrcFlag, true, @@ -297,7 +325,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector, true) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(ns, fromRule.NamespaceSelector, true) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -315,6 +343,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, fromRule.PodSelector, util.IptablesSrcFlag, false, @@ -328,7 +357,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector, false) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(ns, fromRule.PodSelector, false) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -360,6 +389,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, fromRule.NamespaceSelector, util.IptablesSrcFlag, true, @@ -368,6 +398,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, fromRule.PodSelector, util.IptablesSrcFlag, false, @@ -381,8 +412,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-" + craftPartialIptablesCommentFromSelector(fromRule.NamespaceSelector, true) + - "-AND-" + craftPartialIptablesCommentFromSelector(fromRule.PodSelector, false) + + "ALLOW-" + craftPartialIptablesCommentFromSelector(ns, fromRule.NamespaceSelector, true) + + "-AND-" + craftPartialIptablesCommentFromSelector(ns, fromRule.PodSelector, false) + "-TO-" + targetSelectorComment, ) entries = append(entries, entry) @@ -413,8 +444,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net labels = append(labels, "ns-" + ns) } sets = append(sets, labels...) - targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ops, labels, util.IptablesSrcFlag, false) - targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesSrcFlag, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { // parse Ports field for _, portRule := range rule.Ports { @@ -552,7 +583,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentFlag, "ALLOW-" + toRule.IPBlock.CIDR + "-FROM-" + targetSelectorComment, - ) + ) entries = append(entries, cidrEntry) } if len(toRule.IPBlock.Except) > 0 { @@ -592,9 +623,17 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) - // Add namespaces prefix to distinguish namespace ipsets and pod ipsets - for i, _ := range nsLabelsWithoutOps { - nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + log.Printf("len: %d", len(nsLabelsWithOps)) + if len(nsLabelsWithoutOps) == 1 { + if nsLabelsWithoutOps[0] == "" { + // Empty namespaceSelector. This selects all namespaces + nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag + } + } else { + for i, _ := range nsLabelsWithoutOps { + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } } lists = append(lists, nsLabelsWithoutOps...) @@ -605,6 +644,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, toRule.NamespaceSelector, util.IptablesDstFlag, true, @@ -618,7 +658,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector, true), + "-TO-" + craftPartialIptablesCommentFromSelector(ns, toRule.NamespaceSelector, true), ) entries = append(entries, entry) continue @@ -627,6 +667,11 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + if len(podLabelsWithoutOps) == 1 { + if podLabelsWithoutOps[0] == "" { + podLabelsWithoutOps[0] = "ns-" + ns + } + } sets = append(sets, podLabelsWithoutOps...) entry := &iptm.IptEntry{ @@ -636,6 +681,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, toRule.PodSelector, util.IptablesDstFlag, false, @@ -649,7 +695,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector, false), + "-TO-" + craftPartialIptablesCommentFromSelector(ns, toRule.PodSelector, false), ) entries = append(entries, entry) continue @@ -681,6 +727,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, toRule.NamespaceSelector, util.IptablesDstFlag, true, @@ -689,6 +736,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entry.Specs = append( entry.Specs, craftPartialIptEntrySpecFromSelector( + ns, toRule.PodSelector, util.IptablesDstFlag, false, @@ -702,8 +750,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesCommentModuleFlag, util.IptablesCommentFlag, "ALLOW-" + targetSelectorComment + - "-TO-" + craftPartialIptablesCommentFromSelector(toRule.NamespaceSelector, true) + - "-AND-" + craftPartialIptablesCommentFromSelector(toRule.PodSelector, false), + "-TO-" + craftPartialIptablesCommentFromSelector(ns, toRule.NamespaceSelector, true) + + "-AND-" + craftPartialIptablesCommentFromSelector(ns, toRule.PodSelector, false), ) entries = append(entries, entry) } @@ -717,7 +765,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { var entries []*iptm.IptEntry hashedKubeSystemSet := util.GetHashedName("ns-" + util.KubeSystemFlag) - targetSelectorComment := craftPartialIptablesCommentFromSelector(&targetSelector, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) allowKubeSystemIngress := &iptm.IptEntry{ Chain: util.IptablesAzureChain, Specs: []string{ diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 190c127432..e9b9927cfc 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -68,8 +68,8 @@ func TestCraftPartialIptEntrySpecFromOpsAndLabels(t *testing.T) { } - srcIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(srcOps, srcLabels, util.IptablesSrcFlag, false) - dstIptEntry := craftPartialIptEntrySpecFromOpsAndLabels(dstOps, dstLabels, util.IptablesDstFlag, false) + srcIptEntry := craftPartialIptEntrySpecFromOpsAndLabels("testnamespace", srcOps, srcLabels, util.IptablesSrcFlag, false) + dstIptEntry := craftPartialIptEntrySpecFromOpsAndLabels("testnamespace", dstOps, dstLabels, util.IptablesDstFlag, false) iptEntrySpec := append(srcIptEntry, dstIptEntry...) expectedIptEntrySpec := []string{ util.IptablesModuleFlag, @@ -130,7 +130,7 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { }, } - iptEntrySpec := craftPartialIptEntrySpecFromSelector(srcSelector, util.IptablesSrcFlag, false) + iptEntrySpec := craftPartialIptEntrySpecFromSelector("testnamespace", srcSelector, util.IptablesSrcFlag, false) expectedIptEntrySpec := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -155,7 +155,7 @@ func TestCraftPartialIptEntryFromSelector(t *testing.T) { func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { var selector *metav1.LabelSelector selector = nil - comment := craftPartialIptablesCommentFromSelector(selector, false) + comment := craftPartialIptablesCommentFromSelector("testnamespace", selector, false) expectedComment := "none" if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ nil selector comparison") @@ -164,10 +164,18 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { } selector = &metav1.LabelSelector{} - comment = craftPartialIptablesCommentFromSelector(selector, false) + comment = craftPartialIptablesCommentFromSelector("testnamespace", selector, false) + expectedComment = "ns-testnamespace" + if comment != expectedComment { + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ empty podSelector comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + + comment = craftPartialIptablesCommentFromSelector("testnamespace", selector, true) expectedComment = util.KubeAllNamespacesFlag if comment != expectedComment { - t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ empty selector comparison") + t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ empty namespaceSelector comparison") t.Errorf("comment:\n%v", comment) t.Errorf("expectedComment:\n%v", expectedComment) } @@ -192,7 +200,7 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { }, }, } - comment = craftPartialIptablesCommentFromSelector(selector, false) + comment = craftPartialIptablesCommentFromSelector("testnamespace", selector, false) expectedComment = "k0:v0-AND-k1:v10-AND-k1:v11-AND-!k2" if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ normal selector comparison") @@ -220,7 +228,7 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { }, }, } - comment = craftPartialIptablesCommentFromSelector(nsSelector, true) + comment = craftPartialIptablesCommentFromSelector("testnamespace", nsSelector, true) expectedComment = "ns-k0:v0-AND-ns-k1:v10-AND-ns-k1:v11-AND-ns-!k2" if comment != expectedComment { t.Errorf("TestCraftPartialIptablesCommentFromSelector failed @ namespace selector comparison") @@ -840,9 +848,9 @@ func TestTranslatePolicy(t *testing.T) { "app": "backend", }, } - allowFromPodsPolicy := &networkingv1.NetworkPolicy{ + allowBackendToFrontendPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "allow-from-pods-policy", + Name: "allow-app:backend-to-app:frontend-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ @@ -866,21 +874,21 @@ func TestTranslatePolicy(t *testing.T) { }, } - sets, lists, iptEntries = translatePolicy(allowFromPodsPolicy) + sets, lists, iptEntries = translatePolicy(allowBackendToFrontendPolicy) expectedSets = []string{ "app:backend", "app:frontend", } if !reflect.DeepEqual(sets, expectedSets) { - t.Errorf("translatedPolicy failed @ deny-all-policy sets comparison") + t.Errorf("translatedPolicy failed @ allow-app:backend-to-app:frontend-policy sets comparison") t.Errorf("sets: %v", sets) t.Errorf("expectedSets: %v", expectedSets) } expectedLists = []string{} if !reflect.DeepEqual(lists, expectedLists) { - t.Errorf("translatedPolicy failed @ deny-all-policy lists comparison") + t.Errorf("translatedPolicy failed @ allow-app:backend-to-app:frontend-policy lists comparison") t.Errorf("lists: %v", lists) t.Errorf("expectedLists: %v", expectedLists) } @@ -933,7 +941,7 @@ func TestTranslatePolicy(t *testing.T) { } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedPolicy failed @ allow-from-pods-policy policy comparison") + t.Errorf("translatedPolicy failed @ allow-app:frontend-TO-app:backend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) @@ -945,9 +953,9 @@ func TestTranslatePolicy(t *testing.T) { "app": "frontend", }, } - allowToFrontendPodsPolicy := &networkingv1.NetworkPolicy{ + allowToFrontendPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "allow-all-to-app:frontend-policy", + Name: "ALLOW-all-TO-app:frontend-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ @@ -961,13 +969,13 @@ func TestTranslatePolicy(t *testing.T) { }, } - sets, lists, iptEntries = translatePolicy(allowToFrontendPodsPolicy) + sets, lists, iptEntries = translatePolicy(allowToFrontendPolicy) expectedSets = []string{ "app:frontend", } if !reflect.DeepEqual(sets, expectedSets) { - t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy sets comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy sets comparison") t.Errorf("sets: %v", sets) t.Errorf("expectedSets: %v", expectedSets) } @@ -976,7 +984,7 @@ func TestTranslatePolicy(t *testing.T) { util.KubeAllNamespacesFlag, } if !reflect.DeepEqual(lists, expectedLists) { - t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy lists comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy lists comparison") t.Errorf("lists: %v", lists) t.Errorf("expectedLists: %v", expectedLists) } @@ -1014,4 +1022,260 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + denyAllToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "deny-all-TO-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{}, + }, + } + + sets, lists, iptEntries = translatePolicy(denyAllToFrontendPolicy) + + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ deny-all-TO-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ deny-all-TO-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ deny-all-to-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + allowNsTestNamespaceToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-ns-testnamespace-TO-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{}, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowNsTestNamespaceToFrontendPolicy) + + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-testnamespace-TO-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-testnamespace-TO-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-testnamespace"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ns-testnamespace-TO-app:backend", + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-testnamespace-TO-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + allowAllNsToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-all-namespaces-TO-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{}, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowAllNsToFrontendPolicy) + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-all-namespaces-TO-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + util.KubeAllNamespacesFlag, + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-all-namespaces-TO-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-all-namespaces-TO-app:frontend", + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-all-namespaces-TO-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From c75af9d6634c6746ba3e121c31b3cce801e420ef Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 23 Aug 2019 00:20:55 +0000 Subject: [PATCH 49/64] address empty selectors --- npm/translatePolicy.go | 26 ++++++++++++++++++++++---- npm/translatePolicy_test.go | 5 +++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index e0c8a7c887..bf6ffa25df 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -118,6 +118,13 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) + if len(ops) == 1 && len(labels) == 1 { + if ops[0] == "" && labels[0] == "" { + // targetSelector is empty. Select all pods within the namespace + ops = append(ops, "") + labels = append(labels, "ns-" + ns) + } + } sets = append(sets, labels...) targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesDstFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) @@ -299,9 +306,16 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) - // Add namespaces prefix to distinguish namespace ipsets and pod ipsets - for i, _ := range nsLabelsWithoutOps { - nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + if len(nsLabelsWithoutOps) == 1 { + if nsLabelsWithoutOps[0] == "" { + // Empty namespaceSelector. This selects all namespaces + nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag + } + } else { + for i, _ := range nsLabelsWithoutOps { + // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] + } } lists = append(lists, nsLabelsWithoutOps...) @@ -335,6 +349,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) + if len(podLabelsWithoutOps) == 1 { + if podLabelsWithoutOps[0] == "" { + podLabelsWithoutOps[0] = "ns-" + ns + } + } sets = append(sets, podLabelsWithoutOps...) entry := &iptm.IptEntry{ @@ -623,7 +642,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) - log.Printf("len: %d", len(nsLabelsWithOps)) if len(nsLabelsWithoutOps) == 1 { if nsLabelsWithoutOps[0] == "" { // Empty namespaceSelector. This selects all namespaces diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index e9b9927cfc..a530e39d2b 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -1103,6 +1103,7 @@ func TestTranslatePolicy(t *testing.T) { expectedSets = []string{ "app:frontend", + "ns-testnamespace", } if !reflect.DeepEqual(sets, expectedSets) { t.Errorf("translatedPolicy failed @ ALLOW-ns-testnamespace-TO-app:frontend-policy sets comparison") @@ -1152,14 +1153,14 @@ func TestTranslatePolicy(t *testing.T) { util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, - util.GetHashedName("app:backend"), + util.GetHashedName("app:frontend"), util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ns-testnamespace-TO-app:backend", + "ALLOW-ns-testnamespace-TO-app:frontend", }, }, } From cb4d5517283f2ae8f0da10bffa399adddb00cab6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Aug 2019 20:52:14 +0000 Subject: [PATCH 50/64] fix ns prefix in translatePolicy_test.go --- npm/translatePolicy.go | 1 + npm/translatePolicy_test.go | 150 +++++++++++++++++++++++++++++++++--- 2 files changed, 142 insertions(+), 9 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index bf6ffa25df..42a27f9691 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -726,6 +726,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if !util.IsNewNwPolicyVerFlag { continue } + nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) // Add namespaces prefix to distinguish namespace ipsets and pod ipsets diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index a530e39d2b..730169e0a9 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -850,7 +850,7 @@ func TestTranslatePolicy(t *testing.T) { } allowBackendToFrontendPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "allow-app:backend-to-app:frontend-policy", + Name: "ALLOW-app:backend-TO-app:frontend-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ @@ -881,14 +881,14 @@ func TestTranslatePolicy(t *testing.T) { "app:frontend", } if !reflect.DeepEqual(sets, expectedSets) { - t.Errorf("translatedPolicy failed @ allow-app:backend-to-app:frontend-policy sets comparison") + t.Errorf("translatedPolicy failed @ ALLOW-app:backend-TO-app:frontend-policy sets comparison") t.Errorf("sets: %v", sets) t.Errorf("expectedSets: %v", expectedSets) } expectedLists = []string{} if !reflect.DeepEqual(lists, expectedLists) { - t.Errorf("translatedPolicy failed @ allow-app:backend-to-app:frontend-policy lists comparison") + t.Errorf("translatedPolicy failed @ ALLOW-app:backend-TO-app:frontend-policy lists comparison") t.Errorf("lists: %v", lists) t.Errorf("expectedLists: %v", expectedLists) } @@ -941,7 +941,7 @@ func TestTranslatePolicy(t *testing.T) { } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedPolicy failed @ allow-app:frontend-TO-app:backend-policy policy comparison") + t.Errorf("translatedPolicy failed @ ALLOW-app:frontend-TO-app:backend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) @@ -1015,7 +1015,7 @@ func TestTranslatePolicy(t *testing.T) { } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedPolicy failed @ allow-all-to-app:frontend-policy policy comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) @@ -1029,7 +1029,7 @@ func TestTranslatePolicy(t *testing.T) { } denyAllToFrontendPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "deny-all-TO-app:frontend-policy", + Name: "ALLOW-none-TO-app:frontend-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ @@ -1047,14 +1047,14 @@ func TestTranslatePolicy(t *testing.T) { "app:frontend", } if !reflect.DeepEqual(sets, expectedSets) { - t.Errorf("translatedPolicy failed @ deny-all-TO-app:frontend-policy sets comparison") + t.Errorf("translatedPolicy failed @ ALLOW-none-TO-app:frontend-policy sets comparison") t.Errorf("sets: %v", sets) t.Errorf("expectedSets: %v", expectedSets) } expectedLists = []string{} if !reflect.DeepEqual(lists, expectedLists) { - t.Errorf("translatedPolicy failed @ deny-all-TO-app:frontend-policy lists comparison") + t.Errorf("translatedPolicy failed @ ALLOW-none-TO-app:frontend-policy lists comparison") t.Errorf("lists: %v", lists) t.Errorf("expectedLists: %v", expectedLists) } @@ -1065,7 +1065,7 @@ func TestTranslatePolicy(t *testing.T) { getAllowKubeSystemEntries("testnamespace", targetSelector)..., ) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedPolicy failed @ deny-all-to-app:frontend-policy policy comparison") + t.Errorf("translatedPolicy failed @ ALLOW-none-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) @@ -1279,4 +1279,136 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + allowNsDevToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-ns-namespace:dev-AND-!ns-namespace:test0-AND-!ns-namespace:test1-TO-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "namespace": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "namespace", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "test0", + "test1", + }, + }, + }, + }, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowNsDevToFrontendPolicy) + + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-namespace:dev-AND-!ns-namespace:test0-AND-!ns-namespace:test1-TO-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + "ns-namespace:dev", + "ns-namespace:test0", + "ns-namespace:test1", + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-namespace:dev-AND-!ns-namespace:test0-AND-!ns-namespace:test1-TO-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-namespace:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-namespace:test0"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-namespace:test1"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ns-namespace:dev-AND-ns-!namespace:test0-AND-ns-!namespace:test1-TO-app:frontend", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-namespace:dev-AND-!ns-namespace:test0-AND-!ns-namespace:test1-TO-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From fb32b934e018b7d5e50493ccda26eb4ecfcbb8d9 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Mon, 26 Aug 2019 20:52:45 +0000 Subject: [PATCH 51/64] remove splitPolicy --- npm/parsePolicy.go | 15 ----- npm/parsePolicy_test.go | 135 ---------------------------------------- 2 files changed, 150 deletions(-) diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index a19f4f5907..0366c1d647 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -26,21 +26,6 @@ func isSamePolicy(old, new *networkingv1.NetworkPolicy) bool { return true } -func splitPolicy(npObj *networkingv1.NetworkPolicy) ([]string, []*networkingv1.NetworkPolicy) { - var policies []*networkingv1.NetworkPolicy - - labels, keys, vals := parseSelector(&(npObj.Spec.PodSelector)) - for i := range keys { - policy := *npObj - policy.ObjectMeta.Name = labels[i] - policy.Spec.PodSelector.MatchExpressions = []metav1.LabelSelectorRequirement{} - policy.Spec.PodSelector.MatchLabels = map[string]string{keys[i]: vals[i]} - policies = append(policies, &policy) - } - - return labels, policies -} - // addPolicy merges policies based on labels. func addPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPolicy, error) { // if namespace matches && podSelector matches, then merge diff --git a/npm/parsePolicy_test.go b/npm/parsePolicy_test.go index 8658a73d37..dd2b06eb08 100644 --- a/npm/parsePolicy_test.go +++ b/npm/parsePolicy_test.go @@ -10,141 +10,6 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) -func TestSplitPolicy(t *testing.T) { - policy := &networkingv1.NetworkPolicy{ - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "role": "client", - "protocol": "https", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{ - metav1.LabelSelectorRequirement{ - Key: "testIn", - Operator: metav1.LabelSelectorOpIn, - Values: []string{ - "frontend", - "backend", - }, - }, - metav1.LabelSelectorRequirement{ - Key: "testDoesNotExist", - Operator: metav1.LabelSelectorOpDoesNotExist, - }, - }, - }, - }, - } - - labels, policies := splitPolicy(policy) - - expectedLabels := []string{ - "role:client", - "protocol:https", - "testIn:frontend", - "testIn:backend", - "!testDoesNotExist", - } - - expectedPolicies := []*networkingv1.NetworkPolicy{ - &networkingv1.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "role:client", - }, - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "role": "client", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - &networkingv1.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "protocol:https", - }, - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "protocol": "https", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - &networkingv1.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testIn:frontend", - }, - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "testIn": "frontend", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - &networkingv1.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "testIn:backend", - }, - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "testIn": "backend", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - &networkingv1.NetworkPolicy{ - ObjectMeta: metav1.ObjectMeta{ - Name: "!testDoesNotExist", - }, - Spec: networkingv1.NetworkPolicySpec{ - PodSelector: metav1.LabelSelector{ - MatchLabels: map[string]string{ - "!testDoesNotExist": "", - }, - MatchExpressions: []metav1.LabelSelectorRequirement{}, - }, - }, - }, - } - - if len(labels) != len(expectedLabels) { - t.Errorf("TestsplitPolicy failed @ labels length comparison") - } - - if len(policies) != len(expectedPolicies) { - t.Errorf("TestsplitPolicy failed @ policies length comparison") - } - - for i := range labels { - if !reflect.DeepEqual(labels, expectedLabels) { - t.Errorf("TestsplitPolicy failed @ label comparison") - } - - if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchLabels, expectedPolicies[i].Spec.PodSelector.MatchLabels) { - t.Errorf("TestsplitPolicy failed @ MatchLabels comparison") - } - - if !reflect.DeepEqual(policies[i].Spec.PodSelector.MatchExpressions, expectedPolicies[i].Spec.PodSelector.MatchExpressions) { - t.Errorf("TestsplitPolicy failed @ MatchExpressions comparison") - } - - if !reflect.DeepEqual(policies[i].Spec.PodSelector, expectedPolicies[i].Spec.PodSelector) { - t.Error("TestsplitPolicy failed @ PodSelector comparison") - } - - if !reflect.DeepEqual(*(policies[i]), *(expectedPolicies[i])) { - t.Error("TestsplitPolicy failed @ policy comparison") - } - } -} - func TestAddPolicy(t *testing.T) { tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP port6783, port6784 := intstr.FromInt(6783), intstr.FromInt(6784) From ae24b7ae949fd826948d1f6b20a882cdc979e4a9 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 27 Aug 2019 22:17:59 +0000 Subject: [PATCH 52/64] add drop entries for each targetSelector --- npm/iptm/iptm.go | 16 +- npm/nwpolicy.go | 1 + npm/nwpolicy_test.go | 11 +- npm/parseSelector_test.go | 2 +- npm/translatePolicy.go | 112 ++++++++-- npm/translatePolicy_test.go | 404 ++++++++++++++++++++++++++++++++++-- 6 files changed, 510 insertions(+), 36 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index a9d57cb0d0..3bf9b0ca7c 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -104,7 +104,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { return err } - // Insert AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain. + // Append AZURE-NPM-INGRESS-PORT chain to AZURE-NPM chain. entry.Chain = util.IptablesAzureChain entry.Specs = []string{util.IptablesJumpFlag, util.IptablesAzureIngressPortChain} exists, err = iptMgr.Exists(entry) @@ -151,9 +151,14 @@ func (iptMgr *IptablesManager) InitNpmChains() error { return err } - // Add default DROP rule to AZURE-NPM chain. + // Create AZURE-NPM-TARGET-SETS chain. + if err := iptMgr.AddChain(util.IptablesAzureTargetSetsChain); err != nil { + return err + } + + // Append AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain. entry.Chain = util.IptablesAzureChain - entry.Specs = []string{util.IptablesJumpFlag, util.IptablesDrop} + entry.Specs = []string{util.IptablesJumpFlag, util.IptablesAzureTargetSetsChain} exists, err = iptMgr.Exists(entry) if err != nil { return err @@ -162,7 +167,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { if !exists { iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { - log.Errorf("Error: failed to add default DROP rule to AZURE-NPM chain.") + log.Errorf("Error: failed to add AZURE-NPM-TARGET-SETS chain to AZURE-NPM chain.") return err } } @@ -178,6 +183,7 @@ func (iptMgr *IptablesManager) UninitNpmChains() error { util.IptablesAzureIngressFromChain, util.IptablesAzureEgressPortChain, util.IptablesAzureEgressToChain, + util.IptablesAzureTargetSetsChain, } // Remove AZURE-NPM chain from FORWARD chain. @@ -272,7 +278,7 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { // Add adds a rule in iptables. func (iptMgr *IptablesManager) Add(entry *IptEntry) error { - log.Printf("Add iptables entry: %+v.", entry) + log.Printf("Adding iptables entry: %+v.", entry) exists, err := iptMgr.Exists(entry) if err != nil { diff --git a/npm/nwpolicy.go b/npm/nwpolicy.go index 2c981bb1b1..d3006c5e93 100644 --- a/npm/nwpolicy.go +++ b/npm/nwpolicy.go @@ -92,6 +92,7 @@ func (npMgr *NetworkPolicyManager) AddNetworkPolicy(npObj *networkingv1.NetworkP } ipsMgr := allNs.ipsMgr for _, set := range sets { + log.Printf("Creating set: %v, hashedSet: %v", set, util.GetHashedName(set)) if err = ipsMgr.CreateSet(set); err != nil { log.Printf("Error creating ipset %s", set) return err diff --git a/npm/nwpolicy_test.go b/npm/nwpolicy_test.go index 616c3ea8e1..e6f48ce72d 100644 --- a/npm/nwpolicy_test.go +++ b/npm/nwpolicy_test.go @@ -66,6 +66,7 @@ func TestAddNetworkPolicy(t *testing.T) { } tcp := corev1.ProtocolTCP + port8000 := intstr.FromInt(8000) allowIngress := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ Name: "allow-ingress", @@ -81,9 +82,7 @@ func TestAddNetworkPolicy(t *testing.T) { }}, Ports: []networkingv1.NetworkPolicyPort{{ Protocol: &tcp, - Port: &intstr.IntOrString{ - StrVal: "8000", - }, + Port: &port8000, }}, }, }, @@ -92,6 +91,7 @@ func TestAddNetworkPolicy(t *testing.T) { if err := npMgr.AddNetworkPolicy(allowIngress); err != nil { t.Errorf("TestAddNetworkPolicy failed @ allowIngress AddNetworkPolicy") + t.Errorf("Error: %v", err) } allowEgress := &networkingv1.NetworkPolicy{ @@ -109,9 +109,7 @@ func TestAddNetworkPolicy(t *testing.T) { }}, Ports: []networkingv1.NetworkPolicyPort{{ Protocol: &tcp, - Port: &intstr.IntOrString{ - StrVal: "8000", - }, + Port: &port8000, }}, }, }, @@ -120,6 +118,7 @@ func TestAddNetworkPolicy(t *testing.T) { if err := npMgr.AddNetworkPolicy(allowEgress); err != nil { t.Errorf("TestAddNetworkPolicy failed @ allowEgress AddNetworkPolicy") + t.Errorf("Error: %v", err) } } diff --git a/npm/parseSelector_test.go b/npm/parseSelector_test.go index 42e205da82..877530fa9b 100644 --- a/npm/parseSelector_test.go +++ b/npm/parseSelector_test.go @@ -323,7 +323,7 @@ func TestParseSelector(t *testing.T) { selector = &metav1.LabelSelector{} labels, keys, vals = parseSelector(selector) - expectedLabels, expectedKeys, expectedVals = []string{}, []string{}, []string{} + expectedLabels, expectedKeys, expectedVals = []string{""}, []string{""}, []string{""} if len(labels) != len(expectedLabels) { t.Errorf("TestparseSelector failed @ labels length comparison") } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 42a27f9691..5cf7250e84 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -121,11 +121,11 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if len(ops) == 1 && len(labels) == 1 { if ops[0] == "" && labels[0] == "" { // targetSelector is empty. Select all pods within the namespace - ops = append(ops, "") - labels = append(labels, "ns-" + ns) + labels[0] = "ns-" + ns } } sets = append(sets, labels...) + targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesDstFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) @@ -143,6 +143,10 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if rule.From != nil { + if len(rule.From) == 0 { + break + } + for _, fromRule := range rule.From { if fromRule.PodSelector != nil || fromRule.NamespaceSelector != nil || @@ -155,8 +159,16 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !portRuleExists && !fromRuleExists { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, - Specs: targetSelectorIptEntrySpec, } + entry.Specs = append( + entry.Specs, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesSrcFlag, + ) + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( entry.Specs, util.IptablesJumpFlag, @@ -164,7 +176,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + targetSelectorComment, + "ALLOW-ALL-TO-" + targetSelectorComment + + "-FROM-" +util.KubeAllNamespacesFlag, ) entries = append(entries, entry) @@ -173,7 +186,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } // Only Ports rules exist - if !fromRuleExists { + if !fromRuleExists && portRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, @@ -457,10 +470,11 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) - // targetSelector is empty. Select all pods within the namespace - if len(ops) == 0 && len(labels) == 0 { - ops = append(ops, "") - labels = append(labels, "ns-" + ns) + if len(ops) == 1 && len(labels) == 1 { + if ops[0] == "" && labels[0] == "" { + // targetSelector is empty. Select all pods within the namespace + labels[0] = "ns-" + ns + } } sets = append(sets, labels...) targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesSrcFlag, false) @@ -479,6 +493,10 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } if rule.To != nil { + if len(rule.To) == 0 { + break + } + for _, toRule := range rule.To { if toRule.PodSelector != nil || toRule.NamespaceSelector != nil || @@ -495,12 +513,18 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } entry.Specs = append( entry.Specs, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesDstFlag, util.IptablesJumpFlag, util.IptablesAccept, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-FROM-" + targetSelectorComment, + "ALLOW-ALL-FROM-" + targetSelectorComment + + "-TO-" + util.KubeAllNamespacesFlag, ) entries = append(entries, entry) @@ -509,7 +533,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } // Only Ports rules exist - if !toRuleExists { + if !toRuleExists && portRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ Chain: util.IptablesAzureEgressPortChain, @@ -780,6 +804,56 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net return util.DropEmptyFields(sets), util.DropEmptyFields(lists), entries } +// Drop all non-whitelisted packets. +func getDefaultDropEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { + var entries []*iptm.IptEntry + + labelsWithOps, _, _ := parseSelector(&targetSelector) + ops, labels := GetOperatorsAndLabels(labelsWithOps) + if len(ops) == 1 && len(labels) == 1 { + if ops[0] == "" && labels[0] == "" { + // targetSelector is empty. Select all pods within the namespace + labels[0] = "ns-" + ns + } + } + + targetSelectorIngressIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesDstFlag, false) + targetSelectorEgressIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesSrcFlag, false) + targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) + + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureTargetSetsChain, + Specs: targetSelectorIngressIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-ALL-TO-" + targetSelectorComment, + ) + entries = append(entries, entry) + + entry = &iptm.IptEntry{ + Chain: util.IptablesAzureTargetSetsChain, + Specs: targetSelectorEgressIptEntrySpec, + } + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-ALL-FROM-" + targetSelectorComment, + ) + entries = append(entries, entry) + + return entries +} + // Allow traffic from/to kube-system pods func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) []*iptm.IptEntry { var entries []*iptm.IptEntry @@ -857,6 +931,8 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* resultLists = append(resultLists, egressLists...) entries = append(entries, egressEntries...) + entries = append(entries, getDefaultDropEntries(npNs, npObj.Spec.PodSelector)...) + return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries } @@ -876,5 +952,17 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* } } - return util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists), entries + entries = append(entries, getDefaultDropEntries(npNs, npObj.Spec.PodSelector)...) + + resultSets, resultLists = util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists) + + log.Printf("Finished translatePolicy") + log.Printf("sets: %v", resultSets) + log.Printf("lists: %v", resultLists) + log.Printf("entries: ") + for _, entry := range entries { + log.Printf("entry: %+v", entry) + } + + return resultSets, resultLists, entries } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 730169e0a9..ff10bc0574 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -238,6 +238,82 @@ func TestCraftPartialIptablesCommentFromSelector(t *testing.T) { } +func TestGetDefaultDropEntries(t *testing.T) { + ns := "testnamespace" + + targetSelector := metav1.LabelSelector{ + MatchLabels: map[string]string{ + "context": "dev", + }, + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "testNotIn", + Operator: metav1.LabelSelectorOpNotIn, + Values: []string{ + "frontend", + }, + }, + }, + } + + iptEntries := getDefaultDropEntries(ns, targetSelector) + + expectedIptEntries := []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-ALL-TO-context:dev-AND-!testNotIn:frontend", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureTargetSetsChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("context:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("testNotIn:frontend"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-ALL-FROM-context:dev-AND-!testNotIn:frontend", + }, + }, + } + + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("TestGetDefaultDropEntries failed @ iptEntries comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } +} + func TestTranslateIngress(t *testing.T) { ns := "testnamespace" @@ -250,7 +326,7 @@ func TestTranslateIngress(t *testing.T) { Key: "testNotIn", Operator: metav1.LabelSelectorOpNotIn, Values: []string{ - "frontend", + "frontend", }, }, }, @@ -835,6 +911,7 @@ func TestTranslatePolicy(t *testing.T) { expectedIptEntries, getAllowKubeSystemEntries("testnamespace", targetSelector)..., ) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ deny-all-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -940,6 +1017,7 @@ func TestTranslatePolicy(t *testing.T) { }, } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ ALLOW-app:frontend-TO-app:backend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -955,7 +1033,7 @@ func TestTranslatePolicy(t *testing.T) { } allowToFrontendPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: "ALLOW-all-TO-app:frontend-policy", + Name: "ALLOW-all-TO-app:frontend-FROM-all-namespaces-policy", Namespace: "testnamespace", }, Spec: networkingv1.NetworkPolicySpec{ @@ -975,7 +1053,7 @@ func TestTranslatePolicy(t *testing.T) { "app:frontend", } if !reflect.DeepEqual(sets, expectedSets) { - t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy sets comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-FROM-all-namespaces-policy sets comparison") t.Errorf("sets: %v", sets) t.Errorf("expectedSets: %v", expectedSets) } @@ -984,7 +1062,7 @@ func TestTranslatePolicy(t *testing.T) { util.KubeAllNamespacesFlag, } if !reflect.DeepEqual(lists, expectedLists) { - t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy lists comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-FROM-all-namespaces-policy lists comparison") t.Errorf("lists: %v", lists) t.Errorf("expectedLists: %v", expectedLists) } @@ -999,6 +1077,11 @@ func TestTranslatePolicy(t *testing.T) { &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesSrcFlag, util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -1009,13 +1092,14 @@ func TestTranslatePolicy(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-app:frontend", + "ALLOW-ALL-TO-app:frontend-FROM-all-namespaces", }, }, } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { - t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-policy policy comparison") + t.Errorf("translatedPolicy failed @ ALLOW-all-TO-app:frontend-FROM-all-namespaces-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) t.Errorf("iptEntries: %s", marshalledIptEntries) @@ -1064,6 +1148,7 @@ func TestTranslatePolicy(t *testing.T) { expectedIptEntries, getAllowKubeSystemEntries("testnamespace", targetSelector)..., ) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ ALLOW-none-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -1165,6 +1250,7 @@ func TestTranslatePolicy(t *testing.T) { }, } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ ALLOW-ns-testnamespace-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -1225,12 +1311,6 @@ func TestTranslatePolicy(t *testing.T) { getAllowKubeSystemEntries("testnamespace", targetSelector)..., ) - expectedIptEntries = []*iptm.IptEntry{} - expectedIptEntries = append( - expectedIptEntries, - getAllowKubeSystemEntries("testnamespace", targetSelector)..., - ) - nonKubeSystemEntries = []*iptm.IptEntry{ &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, @@ -1272,6 +1352,7 @@ func TestTranslatePolicy(t *testing.T) { }, } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ ALLOW-all-namespaces-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -1404,6 +1485,7 @@ func TestTranslatePolicy(t *testing.T) { } expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) if !reflect.DeepEqual(iptEntries, expectedIptEntries) { t.Errorf("translatedPolicy failed @ ALLOW-ns-namespace:dev-AND-!ns-namespace:test0-AND-!ns-namespace:test1-TO-app:frontend-policy policy comparison") marshalledIptEntries, _ := json.Marshal(iptEntries) @@ -1411,4 +1493,302 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + metav1.LabelSelectorRequirement{ + Key: "k0", + Operator: metav1.LabelSelectorOpDoesNotExist, + Values: []string{}, + }, + metav1.LabelSelectorRequirement{ + Key: "k1", + Operator: metav1.LabelSelectorOpIn, + Values: []string{"v0", "v1"}, + }, + }, + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + allowAllToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "AllOW-ALL-TO-k0-AND-k1:v0-AND-k1:v1-AND-app:frontend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{}, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowAllToFrontendPolicy) + + expectedSets = []string{ + "app:frontend", + "k0", + "k1:v0", + "k1:v1", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ AllOW-ALL-TO-k0-AND-k1:v0-AND-k1:v1-AND-app:frontend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{util.KubeAllNamespacesFlag} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ AllOW-ALL-TO-k0-AND-k1:v0-AND-k1:v1-AND-app:frontend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k0"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k1:v0"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k1:v1"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-AND-!k0-AND-k1:v0-AND-k1:v1-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesNotFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k0"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k1:v0"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("k1:v1"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-all-namespaces-TO-app:frontend-AND-!k0-AND-k1:v0-AND-k1:v1", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ AllOW-all-TO-k0-AND-k1:v0-AND-k1:v1-AND-app:frontend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app":"frontend", + }, + } + allowNsDevAndBackendToFrontendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-ns-ns:dev-AND-app:backend-TO-app:frontend", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app":"backend", + }, + }, + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "ns": "dev", + }, + }, + }, + }, + }, + }, + }, + } + + util.IsNewNwPolicyVerFlag = true + sets, lists, iptEntries = translatePolicy(allowNsDevAndBackendToFrontendPolicy) + + expectedSets = []string{ + "app:frontend", + "app:backend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-ns:dev-AND-app:backend-TO-app:frontend sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + "ns-ns:dev", + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-ns:dev-AND-app:backend-TO-app:frontend lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-ns:dev"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ns-ns:dev-AND-app:backend-TO-app:frontend", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ns-ns:dev-AND-app:backend-TO-app:frontend policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + /* + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "backdoor", + }, + } + allowInternalAndExternalPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-ALL-TO-app:backdoor-policy", + Namespace: "dangerous", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{}, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowInternalAndExternalPolicy) + + expectedSets = []string{ + "app:backdoor", + + } + */ } From 0a36d09fd39c9a264916cba6011865c194cd1f70 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 28 Aug 2019 19:03:22 +0000 Subject: [PATCH 53/64] allow external traffic --- npm/translatePolicy.go | 58 +++++++++++++++++++++++++++---- npm/translatePolicy_test.go | 68 +++++++++++++++++++++++++++++++++++-- 2 files changed, 117 insertions(+), 9 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 5cf7250e84..6cae8034a0 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -106,6 +106,7 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( + allowExternal = false portRuleExists = false fromRuleExists = false protPortPairSlice []*portsInfo @@ -144,7 +145,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if rule.From != nil { if len(rule.From) == 0 { - break + fromRuleExists = true + allowExternal = true } for _, fromRule := range rule.From { @@ -156,7 +158,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } } - if !portRuleExists && !fromRuleExists { + if !portRuleExists && !fromRuleExists && !allowExternal { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, } @@ -186,7 +188,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } // Only Ports rules exist - if !fromRuleExists && portRuleExists { + if portRuleExists && !fromRuleExists && !allowExternal { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, @@ -213,6 +215,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne continue } + // fromRuleExists if portRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ @@ -257,6 +260,26 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne entries = append(entries, entry) } + if allowExternal { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + + targetSelectorComment, + ) + entries = append(entries, entry) + + continue + } + for _, fromRule := range rule.From { // Handle IPBlock field of NetworkPolicyPeer if fromRule.IPBlock != nil { @@ -458,6 +481,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { var ( + allowExternal = false portRuleExists = false toRuleExists = false protPortPairSlice []*portsInfo @@ -494,7 +518,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if rule.To != nil { if len(rule.To) == 0 { - break + toRuleExists = true + allowExternal = true } for _, toRule := range rule.To { @@ -506,7 +531,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } } - if !portRuleExists && !toRuleExists { + if !portRuleExists && !toRuleExists && !allowExternal { entry := &iptm.IptEntry{ Chain: util.IptablesAzureEgressPortChain, Specs: targetSelectorIptEntrySpec, @@ -533,7 +558,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } // Only Ports rules exist - if !toRuleExists && portRuleExists { + if portRuleExists && !toRuleExists && !allowExternal { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ Chain: util.IptablesAzureEgressPortChain, @@ -560,6 +585,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net continue } + // toRuleExists if portRuleExists { for _, protPortPair := range protPortPairSlice { entry := &iptm.IptEntry{ @@ -604,6 +630,26 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entries = append(entries, entry) } + if allowExternal { + entry := &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + } + entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) + entry.Specs = append( + entry.Specs, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-" + + targetSelectorComment, + ) + entries = append(entries, entry) + + continue + } + for _, toRule := range rule.To { // Handle IPBlock field of NetworkPolicyPeer if toRule.IPBlock != nil { diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index ff10bc0574..60f069d1ac 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -1760,7 +1760,7 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } - /* + targetSelector = metav1.LabelSelector{ MatchLabels: map[string]string{ "app": "backdoor", @@ -1788,7 +1788,69 @@ func TestTranslatePolicy(t *testing.T) { expectedSets = []string{ "app:backdoor", - } - */ + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-TO-app:backdoor-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-TO-app:backdoor-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backdoor"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:backdoor-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backdoor"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:backdoor", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("dangerous", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-TO-app:backdoor-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From 1b8dbae3493f815f1046833196c662af1efde984 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 28 Aug 2019 23:13:59 +0000 Subject: [PATCH 54/64] make protocol and port optional --- npm/translatePolicy.go | 116 ++++++++-------- npm/translatePolicy_test.go | 261 ++++++++++++++++++++++++++++++++++-- 2 files changed, 313 insertions(+), 64 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 6cae8034a0..64d5300d3c 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -15,6 +15,48 @@ type portsInfo struct { port string } +func craftPartialIptEntrySpecFromPort(portRule networkingv1.NetworkPolicyPort, sPortOrDPortFlag string) []string { + partialSpec := []string{} + if portRule.Protocol != nil { + partialSpec = append( + partialSpec, + util.IptablesProtFlag, + string(*portRule.Protocol), + ) + } + + if portRule.Port != nil { + partialSpec = append( + partialSpec, + sPortOrDPortFlag, + portRule.Port.String(), + ) + } + + return partialSpec +} + +func craftPartialIptablesCommentFromPort(portRule networkingv1.NetworkPolicyPort, sPortOrDPortFlag string) string { + partialComment := "" + if portRule.Protocol != nil { + partialComment += string(*portRule.Protocol) + if portRule.Port != nil { + partialComment += "-" + } + } + + if portRule.Port != nil { + partialComment += "PORT-" + partialComment += portRule.Port.String() + } + + if portRule.Protocol != nil || portRule.Port != nil { + partialComment += "-OF-" + } + + return partialComment +} + func craftPartialIptEntrySpecFromOpAndLabel(op, label, srcOrDstFlag string, isNamespaceSelector bool) []string { if isNamespaceSelector { label = "ns-" + label @@ -109,7 +151,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne allowExternal = false portRuleExists = false fromRuleExists = false - protPortPairSlice []*portsInfo sets []string // ipsets with type: net:hash lists []string // ipsets with type: list:set entries []*iptm.IptEntry @@ -131,15 +172,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { - // parse Ports field - for _, portRule := range rule.Ports { - protPortPairSlice = append( - protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: portRule.Port.String(), - }, - ) + if len(rule.Ports) > 0 { portRuleExists = true } @@ -189,15 +222,10 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne // Only Ports rules exist if portRuleExists && !fromRuleExists && !allowExternal { - for _, protPortPair := range protPortPairSlice { + for _, portRule := range rule.Ports { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - }, + Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag), } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( @@ -207,7 +235,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + + "ALLOW-ALL-TO-" + + craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + targetSelectorComment, ) entries = append(entries, entry) @@ -217,15 +246,10 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne // fromRuleExists if portRuleExists { - for _, protPortPair := range protPortPairSlice { + for _, portRule := range rule.Ports { entry := &iptm.IptEntry{ Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - }, + Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag), } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( @@ -235,7 +259,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + protPortPair.port + "-PORT-OF-" + + "ALLOW-ALL-TO-" + + craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + targetSelectorComment + "-TO-JUMP-TO-" + util.IptablesAzureIngressFromChain, ) @@ -484,7 +509,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net allowExternal = false portRuleExists = false toRuleExists = false - protPortPairSlice []*portsInfo sets []string // ipsets with type: net:hash lists []string // ipsets with type: list:set entries []*iptm.IptEntry @@ -504,15 +528,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesSrcFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { - // parse Ports field - for _, portRule := range rule.Ports { - protPortPairSlice = append( - protPortPairSlice, - &portsInfo{ - protocol: string(*portRule.Protocol), - port: portRule.Port.String(), - }, - ) + if len(rule.Ports) > 0 { portRuleExists = true } @@ -559,15 +575,10 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net // Only Ports rules exist if portRuleExists && !toRuleExists && !allowExternal { - for _, protPortPair := range protPortPairSlice { + for _, portRule := range rule.Ports { entry := &iptm.IptEntry{ Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - }, + Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag), } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( @@ -577,7 +588,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-FROM-" + protPortPair.port + "-PORT-OF-" + + "ALLOW-ALL-FROM-" + + craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + targetSelectorComment, ) entries = append(entries, entry) @@ -587,15 +599,10 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net // toRuleExists if portRuleExists { - for _, protPortPair := range protPortPairSlice { + for _, portRule := range rule.Ports { entry := &iptm.IptEntry{ Chain: util.IptablesAzureEgressPortChain, - Specs: []string{ - util.IptablesProtFlag, - protPortPair.protocol, - util.IptablesDstPortFlag, - protPortPair.port, - }, + Specs: craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag), } entry.Specs = append(entry.Specs, targetSelectorIptEntrySpec...) entry.Specs = append( @@ -605,7 +612,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-FROM-" + protPortPair.port + "-PORT-OF-" + + "ALLOW-ALL-FROM-" + + craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + targetSelectorComment + "-TO-JUMP-TO-" + util.IptablesAzureEgressToChain, ) @@ -623,7 +631,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + + "ALLOW-ALL-FROM-" + targetSelectorComment + "-TO-JUMP-TO-" + util.IptablesAzureEgressToChain, ) @@ -642,7 +650,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-" + + "ALLOW-ALL-FROM-" + targetSelectorComment, ) entries = append(entries, entry) diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 60f069d1ac..f7f2faf284 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -13,10 +13,131 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) +func TestCraftPartialIptEntrySpecFromPort(t *testing.T) { + portRule := networkingv1.NetworkPolicyPort{} + + iptEntrySpec := craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag) + expectedIptEntrySpec := []string{} + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftPartialIptEntrySpecFromPort failed @ empty iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } + + tcp := v1.ProtocolTCP + portRule = networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + } + + iptEntrySpec = craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag) + expectedIptEntrySpec = []string{ + util.IptablesProtFlag, + "TCP", + } + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftPartialIptEntrySpecFromPort failed @ tcp iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } + + port8000 := intstr.FromInt(8000) + portRule = networkingv1.NetworkPolicyPort{ + Port: &port8000, + } + + iptEntrySpec = craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag) + expectedIptEntrySpec = []string{ + util.IptablesDstPortFlag, + "8000", + } + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftPartialIptEntrySpecFromPort failed @ port 8000 iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } + + portRule = networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port8000, + } + + iptEntrySpec = craftPartialIptEntrySpecFromPort(portRule, util.IptablesDstPortFlag) + expectedIptEntrySpec = []string{ + util.IptablesProtFlag, + "TCP", + util.IptablesDstPortFlag, + "8000", + } + + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftPartialIptEntrySpecFromPort failed @ tcp port 8000 iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) + } +} + +func TestCraftPartialIptablesCommentFromPort(t *testing.T) { + portRule := networkingv1.NetworkPolicyPort{} + + comment := craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + expectedComment := "" + + if !reflect.DeepEqual(comment, expectedComment) { + t.Errorf("TestCraftPartialIptablesCommentFromPort failed @ empty comment comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + + tcp := v1.ProtocolTCP + portRule = networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + } + + comment = craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + expectedComment = "TCP-OF-" + + if !reflect.DeepEqual(comment, expectedComment) { + t.Errorf("TestCraftPartialIptablesCommentFromPort failed @ tcp comment comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedComment:\n%v", expectedComment) + } + + port8000 := intstr.FromInt(8000) + portRule = networkingv1.NetworkPolicyPort{ + Port: &port8000, + } + + comment = craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + expectedComment = "PORT-8000-OF-" + + if !reflect.DeepEqual(comment, expectedComment) { + t.Errorf("TestCraftPartialIptablesCommentFromPort failed @ port 8000 comment comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedIptEntrySpec:\n%v", expectedComment) + } + + portRule = networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port8000, + } + + comment = craftPartialIptablesCommentFromPort(portRule, util.IptablesDstPortFlag) + expectedComment = "TCP-PORT-8000-OF-" + + if !reflect.DeepEqual(comment, expectedComment) { + t.Errorf("TestCraftPartialIptablesCommentFromPort failed @ tcp port 8000 comment comparison") + t.Errorf("comment:\n%v", comment) + t.Errorf("expectedIptEntrySpec:\n%v", expectedComment) + } +} + func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { srcOp, srcLabel := "", "src" - iptEntry := craftPartialIptEntrySpecFromOpAndLabel(srcOp, srcLabel, util.IptablesSrcFlag, false) - expectedIptEntry := []string{ + iptEntrySpec := craftPartialIptEntrySpecFromOpAndLabel(srcOp, srcLabel, util.IptablesSrcFlag, false) + expectedIptEntrySpec := []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesMatchSetFlag, @@ -24,13 +145,15 @@ func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { util.IptablesSrcFlag, } - if !reflect.DeepEqual(iptEntry, expectedIptEntry) { - t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ src iptEntry comparison") + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ src iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) } dstOp, dstLabel := "!", "dst" - iptEntry = craftPartialIptEntrySpecFromOpAndLabel(dstOp, dstLabel, util.IptablesDstFlag, false) - expectedIptEntry = []string{ + iptEntrySpec = craftPartialIptEntrySpecFromOpAndLabel(dstOp, dstLabel, util.IptablesDstFlag, false) + expectedIptEntrySpec = []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, util.IptablesNotFlag, @@ -39,8 +162,10 @@ func TestCraftPartialIptEntrySpecFromOpAndLabel(t *testing.T) { util.IptablesDstFlag, } - if !reflect.DeepEqual(iptEntry, expectedIptEntry) { - t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ dst iptEntry comparison") + if !reflect.DeepEqual(iptEntrySpec, expectedIptEntrySpec) { + t.Errorf("TestCraftIptEntrySpecFromOpAndLabel failed @ dst iptEntrySpec comparison") + t.Errorf("iptEntrySpec:\n%v", iptEntrySpec) + t.Errorf("expectedIptEntrySpec:\n%v", expectedIptEntrySpec) } } @@ -462,7 +587,7 @@ func TestTranslateIngress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-TO-6783-PORT-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + + "ALLOW-ALL-TO-TCP-PORT-6783-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + util.IptablesAzureIngressFromChain, }, }, @@ -732,7 +857,7 @@ func TestTranslateEgress(t *testing.T) { util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, - "ALLOW-ALL-FROM-6783-PORT-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + + "ALLOW-ALL-FROM-TCP-PORT-6783-OF-context:dev-AND-!testNotIn:frontend-TO-JUMP-TO-" + util.IptablesAzureEgressToChain, }, }, @@ -1853,4 +1978,120 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + + port8000 := intstr.FromInt(8000) + allowBackendToFrontendPort8000Policy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-app:backend-TO-app:frontend-port-8000-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Port: &port8000, + }, + }, + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "backend", + }, + }, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowBackendToFrontendPort8000Policy) + + expectedSets = []string{ + "app:frontend", + "app:backend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-app:backend-TO-app:frontend-port-8000-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-app:backend-TO-app:frontend-port-8000-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesDstPortFlag, + "8000", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-PORT-8000-OF-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:backend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-app:backend-TO-app:frontend", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("dangerous", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-TO-app:backdoor-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From 7fbc4f7bd74d1783b770b26380a60d6370fbd0ba Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 28 Aug 2019 23:55:29 +0000 Subject: [PATCH 55/64] need to fix order of sets and lists gen from sel --- npm/parseSelector.go | 2 + npm/translatePolicy.go | 13 +++ npm/translatePolicy_test.go | 167 ++++++++++++++++++++++++++++++++++++ 3 files changed, 182 insertions(+) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 1b0f4cd878..1afa0d449f 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -119,6 +119,8 @@ func sortSelector(selector *metav1.LabelSelector) { } selector.MatchExpressions = sortedReqs + + log.Printf("sortedReqs: %v", sortedReqs) } // HashSelector returns the hash value of the selector. diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 64d5300d3c..79214692fc 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -122,6 +122,8 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe return "none" } + sortSelector(selector) + if len(selector.MatchExpressions) == 0 && len(selector.MatchLabels) == 0 { if isNamespaceSelector { return util.KubeAllNamespacesFlag @@ -158,6 +160,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne log.Printf("started parsing ingress rule") + sortSelector(&targetSelector) labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) if len(ops) == 1 && len(labels) == 1 { @@ -365,6 +368,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { + sortSelector(fromRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) if len(nsLabelsWithoutOps) == 1 { @@ -408,6 +412,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { + sortSelector(fromRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) if len(podLabelsWithoutOps) == 1 { @@ -451,6 +456,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if !util.IsNewNwPolicyVerFlag { continue } + + sortSelector(fromRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) // Add namespaces prefix to distinguish namespace ipsets and pod ipsets @@ -459,6 +466,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } lists = append(lists, nsLabelsWithoutOps...) + sortSelector(fromRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) @@ -516,6 +524,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net log.Printf("started parsing egress rule") + sortSelector(&targetSelector) labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) if len(ops) == 1 && len(labels) == 1 { @@ -718,6 +727,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { + sortSelector(toRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) if len(nsLabelsWithoutOps) == 1 { @@ -761,6 +771,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { + sortSelector(toRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) if len(podLabelsWithoutOps) == 1 { @@ -805,6 +816,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net continue } + sortSelector(toRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) // Add namespaces prefix to distinguish namespace ipsets and pod ipsets @@ -813,6 +825,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } lists = append(lists, nsLabelsWithoutOps...) + sortSelector(toRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index f7f2faf284..f3249337d5 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2094,4 +2094,171 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "k8s", + "team": "aks", + }, + } + allowCniOrCnsToK8sPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-program:cni-AND-team:acn-OR-binary:cns-AND-group:container-TO-app:k8s-AND-team:aks-policy", + Namespace: "acn", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "program": "cni", + "team": "acn", + }, + }, + }, + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "binary": "cns", + "group": "container", + }, + }, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowCniOrCnsToK8sPolicy) + + expectedSets = []string{ + "app:k8s", + "team:aks", + "program:cni", + "team:acn", + "binary:cns", + "group:container", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-program:cni-AND-team:acn-OR-binary:cns-AND-group:container-TO-app:k8s-AND-team:aks-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-program:cni-AND-team:acn-OR-binary:cns-AND-group:container-TO-app:k8s-AND-team:aks-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("acn", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:k8s"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("team:aks"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-app:k8s-AND-team:aks-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("program:cni"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("team:acn"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:k8s"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("team:aks"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-program:cni-AND-team:acn-TO-app:k8s-AND-team:aks", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("binary:cns"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("group:container"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:k8s"), + util.IptablesDstFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("team:aks"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-binary:cns-AND-group:container-TO-app:k8s-AND-team:aks", + }, + }, + } + + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("acn", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-program:cni-AND-team:acn-OR-binary:cns-AND-group:container-TO-app:k8s-AND-team:aks-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From bda22cd6bbd7c14ed8ed8ae757fb9708fe9b9af8 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Aug 2019 17:40:46 +0000 Subject: [PATCH 56/64] access selector through sorted order --- npm/parseSelector.go | 14 +++++++------- npm/translatePolicy.go | 14 ++------------ npm/util/util.go | 10 +++++++--- npm/util/util_test.go | 32 +++++++++++++++++++++++--------- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/npm/parseSelector.go b/npm/parseSelector.go index 1afa0d449f..f762aef3b1 100644 --- a/npm/parseSelector.go +++ b/npm/parseSelector.go @@ -105,7 +105,7 @@ func GetOperatorsAndLabels(labelsWithOps []string) ([]string, []string) { // sortSelector sorts the member fields of the selector in an alphebatical order. func sortSelector(selector *metav1.LabelSelector) { - util.SortMap(&selector.MatchLabels) + _, _ = util.SortMap(&selector.MatchLabels) reqHeap := &ReqHeap{} heap.Init(reqHeap) @@ -119,8 +119,6 @@ func sortSelector(selector *metav1.LabelSelector) { } selector.MatchExpressions = sortedReqs - - log.Printf("sortedReqs: %v", sortedReqs) } // HashSelector returns the hash value of the selector. @@ -149,11 +147,13 @@ func parseSelector(selector *metav1.LabelSelector) ([]string, []string, []string return labels, keys, vals } - for k, v := range selector.MatchLabels { - labels = append(labels, k+":"+v) - keys = append(keys, k) - vals = append(vals, v) + sortedKeys, sortedVals := util.SortMap(&selector.MatchLabels) + + for i := range sortedKeys { + labels = append(labels, sortedKeys[i]+":"+sortedVals[i]) } + keys = append(keys, sortedKeys...) + vals = append(vals, sortedVals...) for _, req := range selector.MatchExpressions { var k string diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 79214692fc..6982cc040a 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -122,8 +122,6 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe return "none" } - sortSelector(selector) - if len(selector.MatchExpressions) == 0 && len(selector.MatchLabels) == 0 { if isNamespaceSelector { return util.KubeAllNamespacesFlag @@ -145,6 +143,8 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe comment += "-AND-" } + log.Printf("%s", comment[:len(comment)-len("-AND-")]) + return comment[:len(comment)-len("-AND-")] } @@ -160,7 +160,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne log.Printf("started parsing ingress rule") - sortSelector(&targetSelector) labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) if len(ops) == 1 && len(labels) == 1 { @@ -368,7 +367,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { - sortSelector(fromRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) if len(nsLabelsWithoutOps) == 1 { @@ -412,7 +410,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } if fromRule.PodSelector != nil && fromRule.NamespaceSelector == nil { - sortSelector(fromRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) if len(podLabelsWithoutOps) == 1 { @@ -457,7 +454,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne continue } - sortSelector(fromRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) // Add namespaces prefix to distinguish namespace ipsets and pod ipsets @@ -466,7 +462,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne } lists = append(lists, nsLabelsWithoutOps...) - sortSelector(fromRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(fromRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) @@ -524,7 +519,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net log.Printf("started parsing egress rule") - sortSelector(&targetSelector) labelsWithOps, _, _ := parseSelector(&targetSelector) ops, labels := GetOperatorsAndLabels(labelsWithOps) if len(ops) == 1 && len(labels) == 1 { @@ -727,7 +721,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { - sortSelector(toRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) if len(nsLabelsWithoutOps) == 1 { @@ -771,7 +764,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } if toRule.PodSelector != nil && toRule.NamespaceSelector == nil { - sortSelector(toRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) if len(podLabelsWithoutOps) == 1 { @@ -816,7 +808,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net continue } - sortSelector(toRule.NamespaceSelector) nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) // Add namespaces prefix to distinguish namespace ipsets and pod ipsets @@ -825,7 +816,6 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net } lists = append(lists, nsLabelsWithoutOps...) - sortSelector(toRule.PodSelector) podLabelsWithOps, _, _ := parseSelector(toRule.PodSelector) _, podLabelsWithoutOps := GetOperatorsAndLabels(podLabelsWithOps) sets = append(sets, podLabelsWithoutOps...) diff --git a/npm/util/util.go b/npm/util/util.go index d8200e3ec1..70c7909ca1 100644 --- a/npm/util/util.go +++ b/npm/util/util.go @@ -46,8 +46,8 @@ func Hash(s string) string { // SortMap sorts the map by key in alphabetical order. // Note: even though the map is sorted, accessing it through range will still result in random order. -func SortMap(m *map[string]string) { - var sortedKeys []string +func SortMap(m *map[string]string) ([]string, []string) { + var sortedKeys, sortedVals []string for k := range *m { sortedKeys = append(sortedKeys, k) } @@ -55,10 +55,14 @@ func SortMap(m *map[string]string) { sortedMap := &map[string]string{} for _, k := range sortedKeys { - (*sortedMap)[k] = (*m)[k] + v := (*m)[k] + (*sortedMap)[k] = v + sortedVals = append(sortedVals, v) } m = sortedMap + + return sortedKeys, sortedVals } // UniqueStrSlice removes duplicate elements from the input string. diff --git a/npm/util/util_test.go b/npm/util/util_test.go index 85ef95c26b..0a7d16d690 100644 --- a/npm/util/util_test.go +++ b/npm/util/util_test.go @@ -14,16 +14,30 @@ func TestSortMap(t *testing.T) { "a": "b", } - SortMap(m) - expectedMap := &map[string]string{ - "a": "b", - "c": "d", - "e": "f", + sortedKeys, sortedVals := SortMap(m) + + expectedKeys := []string{ + "a", + "c", + "e", + } + + expectedVals := []string{ + "b", + "d", + "f", + } + + if !reflect.DeepEqual(sortedKeys, expectedKeys) { + t.Errorf("TestSortMap failed @ key comparison") + t.Errorf("sortedKeys: %v", sortedKeys) + t.Errorf("expectedKeys: %v", expectedKeys) } - if !reflect.DeepEqual(m, expectedMap) { - t.Errorf("TestSortMap failed @ map comparison") - t.Errorf("m: %v", m) - t.Errorf("expectedMap: %v", expectedMap) + + if !reflect.DeepEqual(sortedVals, expectedVals) { + t.Errorf("TestSortMap failed @ val comparison") + t.Errorf("sortedVals: %v", sortedVals) + t.Errorf("expectedVals: %v", expectedVals) } } From 534767c11462db64621ac73e52363d9ab64330c6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Aug 2019 21:06:24 +0000 Subject: [PATCH 57/64] normal networkpolicies unit tests done --- npm/translatePolicy.go | 4 +- npm/translatePolicy_test.go | 240 ++++++++++++++++++++++++++++++++++++ 2 files changed, 241 insertions(+), 3 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 6982cc040a..4971de0529 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -142,9 +142,7 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe comment += prefix + ops[i] + labelsWithoutOps[i] comment += "-AND-" } - - log.Printf("%s", comment[:len(comment)-len("-AND-")]) - + return comment[:len(comment)-len("-AND-")] } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index f3249337d5..3004075f4e 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2261,4 +2261,244 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "backend", + }, + } + denyAllFromBackendPolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-none-FROM-app:backend-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{}, + }, + } + + sets, lists, iptEntries = translatePolicy(denyAllFromBackendPolicy) + + expectedSets = []string{ + "app:backend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-app:backend-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-app:backend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-app:backend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + + targetSelector = metav1.LabelSelector{} + denyAllFromNsUnsafePolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-none-FROM-ns-unsafe-policy", + Namespace: "unsafe", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{}, + }, + } + + sets, lists, iptEntries = translatePolicy(denyAllFromNsUnsafePolicy) + + expectedSets = []string{ + "ns-unsafe", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-ns-unsafe-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + expectedLists = []string{} + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-app:backend-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("unsafe", targetSelector)..., + ) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("unsafe", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-none-FROM-app:backend-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "frontend", + }, + } + + tcp, udp := v1.ProtocolTCP, v1.ProtocolUDP + port53 := intstr.FromInt(53) + allowFrontendToTCPPort80UDPPOrt443Policy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "ALLOW-ALL-FROM-app:frontend-TCP-PORT-53-OR-UDP-PORT-53-policy", + Namespace: "testnamespace", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeEgress, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port53, + }, + networkingv1.NetworkPolicyPort{ + Protocol: &udp, + Port: &port53, + }, + }, + }, + networkingv1.NetworkPolicyEgressRule{ + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{}, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(allowFrontendToTCPPort80UDPPOrt443Policy) + + expectedSets = []string{ + "app:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-FROM-app:frontend-TCP-PORT-53-OR-UDP-PORT-53-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + util.KubeAllNamespacesFlag, + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-FROM-app:frontend-TCP-PORT-53-OR-UDP-PORT-53-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + "TCP", + util.IptablesDstPortFlag, + "53", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-TCP-PORT-53-OF-app:frontend", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + "UDP", + util.IptablesDstPortFlag, + "53", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-UDP-PORT-53-OF-app:frontend", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName(util.KubeAllNamespacesFlag), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-app:frontend-TO-" + + util.KubeAllNamespacesFlag, + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ ALLOW-ALL-FROM-app:frontend-TCP-PORT-53-OR-UDP-PORT-53-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From 17fa5a3087003ffdc02788b852ff5750f7a75c08 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Aug 2019 21:29:59 +0000 Subject: [PATCH 58/64] remove extra ns- --- npm/pod.go | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/npm/pod.go b/npm/pod.go index 5902cbfb0a..427e01d44a 100644 --- a/npm/pod.go +++ b/npm/pod.go @@ -3,8 +3,6 @@ package npm import ( - "strings" - "github.com/Azure/azure-container-networking/log" "github.com/Azure/azure-container-networking/npm/util" @@ -51,11 +49,6 @@ func (npMgr *NetworkPolicyManager) AddPod(podObj *corev1.Pod) error { // Add the pod to its label's ipset. for podLabelKey, podLabelVal := range podLabels { - //Ignore pod-template-hash label. - if strings.Contains(podLabelKey, util.KubePodTemplateHashFlag) { - continue - } - log.Printf("Adding pod %s to ipset %s", podIP, podLabelKey) if err = ipsMgr.AddToSet(podLabelKey, podIP); err != nil { log.Errorf("Error: failed to add pod to label ipset.") @@ -139,17 +132,12 @@ func (npMgr *NetworkPolicyManager) DeletePod(podObj *corev1.Pod) error { // Delete pod from ipset ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Delete the pod from its namespace's ipset. - if err = ipsMgr.DeleteFromSet("ns-" + podNs, podIP); err != nil { + if err = ipsMgr.DeleteFromSet(podNs, podIP); err != nil { log.Errorf("Error: failed to delete pod from namespace ipset.") return err } // Delete the pod from its label's ipset. for podLabelKey, podLabelVal := range podLabels { - //Ignore pod-template-hash label. - if strings.Contains(podLabelKey, "pod-template-hash") { - continue - } - log.Printf("Deleting pod %s from ipset %s", podIP, podLabelKey) if err = ipsMgr.DeleteFromSet(podLabelKey, podIP); err != nil { log.Errorf("Error: failed to delete pod from label ipset.") From eef13638f12b4f1af77a4bb1679a3c78adfbd8a5 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Aug 2019 22:39:59 +0000 Subject: [PATCH 59/64] finished translatePolicy unit tests --- npm/iptm/iptm.go | 2 +- npm/translatePolicy.go | 20 ++- npm/translatePolicy_test.go | 250 ++++++++++++++++++++++++++++++++++++ 3 files changed, 259 insertions(+), 13 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 3bf9b0ca7c..32c0d06a31 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -289,7 +289,7 @@ func (iptMgr *IptablesManager) Add(entry *IptEntry) error { return nil } - iptMgr.OperationFlag = util.IptablesInsertionFlag + iptMgr.OperationFlag = util.IptablesAppendFlag if _, err := iptMgr.Run(entry); err != nil { log.Errorf("Error: failed to create iptables rules.") return err diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 4971de0529..99da3d2849 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -367,14 +367,12 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne if fromRule.PodSelector == nil && fromRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(fromRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) - if len(nsLabelsWithoutOps) == 1 { - if nsLabelsWithoutOps[0] == "" { - // Empty namespaceSelector. This selects all namespaces - nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag - } + if len(nsLabelsWithoutOps) == 1 && nsLabelsWithoutOps[0] == "" { + // Empty namespaceSelector. This selects all namespaces + nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag } else { for i, _ := range nsLabelsWithoutOps { - // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + // Add namespaces prefix to distinguish namespace ipset lists and pod ipsets nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] } } @@ -721,14 +719,12 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net if toRule.PodSelector == nil && toRule.NamespaceSelector != nil { nsLabelsWithOps, _, _ := parseSelector(toRule.NamespaceSelector) _, nsLabelsWithoutOps := GetOperatorsAndLabels(nsLabelsWithOps) - if len(nsLabelsWithoutOps) == 1 { - if nsLabelsWithoutOps[0] == "" { - // Empty namespaceSelector. This selects all namespaces - nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag - } + if len(nsLabelsWithoutOps) == 1 && nsLabelsWithoutOps[0] == "" { + // Empty namespaceSelector. This selects all namespaces + nsLabelsWithoutOps[0] = util.KubeAllNamespacesFlag } else { for i, _ := range nsLabelsWithoutOps { - // Add namespaces prefix to distinguish namespace ipsets and pod ipsets + // Add namespaces prefix to distinguish namespace ipset lists and pod ipsets nsLabelsWithoutOps[i] = "ns-" + nsLabelsWithoutOps[i] } } diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 3004075f4e..735251381b 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2501,4 +2501,254 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("iptEntries: %s", marshalledIptEntries) t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) } + + targetSelector = metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "db", + }, + } + + tcp = v1.ProtocolTCP + port6379, port5978 := intstr.FromInt(6379), intstr.FromInt(5978) + k8sExamplePolicy := &networkingv1.NetworkPolicy{ + ObjectMeta: metav1.ObjectMeta{ + Name: "k8s-example-policy", + Namespace: "default", + }, + Spec: networkingv1.NetworkPolicySpec{ + PodSelector: targetSelector, + PolicyTypes: []networkingv1.PolicyType{ + networkingv1.PolicyTypeIngress, + networkingv1.PolicyTypeEgress, + }, + Ingress: []networkingv1.NetworkPolicyIngressRule{ + networkingv1.NetworkPolicyIngressRule{ + From: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + IPBlock: &networkingv1.IPBlock{ + CIDR: "172.17.0.0/16", + Except: []string{ + "172.17.1.0/24", + }, + }, + }, + networkingv1.NetworkPolicyPeer{ + NamespaceSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "project": "myproject", + }, + }, + }, + networkingv1.NetworkPolicyPeer{ + PodSelector: &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "role": "frontend", + }, + }, + }, + }, + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port6379, + }, + }, + }, + }, + Egress: []networkingv1.NetworkPolicyEgressRule{ + networkingv1.NetworkPolicyEgressRule{ + To: []networkingv1.NetworkPolicyPeer{ + networkingv1.NetworkPolicyPeer{ + IPBlock: &networkingv1.IPBlock{ + CIDR: "10.0.0.0/24", + }, + }, + }, + Ports: []networkingv1.NetworkPolicyPort{ + networkingv1.NetworkPolicyPort{ + Protocol: &tcp, + Port: &port5978, + }, + }, + }, + }, + }, + } + + sets, lists, iptEntries = translatePolicy(k8sExamplePolicy) + + expectedSets = []string{ + "role:db", + "role:frontend", + } + if !reflect.DeepEqual(sets, expectedSets) { + t.Errorf("translatedPolicy failed @ k8s-example-policy sets comparison") + t.Errorf("sets: %v", sets) + t.Errorf("expectedSets: %v", expectedSets) + } + + expectedLists = []string{ + "ns-project:myproject", + } + if !reflect.DeepEqual(lists, expectedLists) { + t.Errorf("translatedPolicy failed @ k8s-example-policy lists comparison") + t.Errorf("lists: %v", lists) + t.Errorf("expectedLists: %v", expectedLists) + } + + expectedIptEntries = []*iptm.IptEntry{} + expectedIptEntries = append( + expectedIptEntries, + getAllowKubeSystemEntries("testnamespace", targetSelector)..., + ) + + nonKubeSystemEntries = []*iptm.IptEntry{ + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressPortChain, + Specs: []string{ + util.IptablesProtFlag, + "TCP", + util.IptablesDstPortFlag, + "6379", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAzureIngressFromChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-TO-TCP-PORT-6379-OF-role:db-TO-JUMP-TO-" + + util.IptablesAzureIngressFromChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesSFlag, + "172.17.0.0/16", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-172.17.0.0/16-TO-role:db", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesSFlag, + "172.17.1.0/24", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesDrop, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "DROP-172.17.1.0/24-TO-role:db", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("ns-project:myproject"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ns-project:myproject-TO-role:db", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureIngressFromChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:frontend"), + util.IptablesSrcFlag, + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesDstFlag, + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-role:frontend-TO-role:db", + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesProtFlag, + "TCP", + util.IptablesDstPortFlag, + "5978", + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-TCP-PORT-5978-OF-role:db-TO-JUMP-TO-" + + util.IptablesAzureEgressToChain, + }, + }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressToChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("role:db"), + util.IptablesSrcFlag, + util.IptablesDFlag, + "10.0.0.0/24", + util.IptablesJumpFlag, + util.IptablesAccept, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-10.0.0.0/24-FROM-role:db", + }, + }, + } + expectedIptEntries = append(expectedIptEntries, nonKubeSystemEntries...) + expectedIptEntries = append(expectedIptEntries, getDefaultDropEntries("testnamespace", targetSelector)...) + if !reflect.DeepEqual(iptEntries, expectedIptEntries) { + t.Errorf("translatedPolicy failed @ k8s-example-policy policy comparison") + marshalledIptEntries, _ := json.Marshal(iptEntries) + marshalledExpectedIptEntries, _ := json.Marshal(expectedIptEntries) + t.Errorf("iptEntries: %s", marshalledIptEntries) + t.Errorf("expectedIptEntries: %s", marshalledExpectedIptEntries) + } } From 65c6ce6073ca8c4030066b02801895cf6078b0f9 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Thu, 29 Aug 2019 23:06:19 +0000 Subject: [PATCH 60/64] address jaeryn's comments --- npm/iptm/iptm.go | 1 + npm/parsePolicy.go | 6 ------ npm/plugin/main.go | 3 +-- npm/translatePolicy.go | 2 ++ 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 32c0d06a31..1c1a938a72 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -269,6 +269,7 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { log.Printf("Chain doesn't exist %s.", entry.Chain) return nil } + log.Errorf("Error: failed to delete iptables chain %s.", entry.Chain) return err } diff --git a/npm/parsePolicy.go b/npm/parsePolicy.go index 0366c1d647..a7444247f1 100644 --- a/npm/parsePolicy.go +++ b/npm/parsePolicy.go @@ -123,12 +123,6 @@ func deductPolicy(old, new *networkingv1.NetworkPolicy) (*networkingv1.NetworkPo } } - /* - if len(deductedIngress) == 0 && len(deductedEgress) == 0 { - return nil, nil - } - */ - deductedPolicy.Spec.Ingress = deductedIngress deductedPolicy.Spec.Egress = deductedEgress diff --git a/npm/plugin/main.go b/npm/plugin/main.go index 1f24059bc7..501b271354 100644 --- a/npm/plugin/main.go +++ b/npm/plugin/main.go @@ -64,8 +64,7 @@ func main() { time.Sleep(time.Second * waitForTelemetryInSeconds) - err = npMgr.Start(wait.NeverStop) - if err != nil { + if err = npMgr.Start(wait.NeverStop); err != nil { log.Logf("npm failed with error %v.", err) panic(err.Error) } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 99da3d2849..0e098c943d 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -187,6 +187,7 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne fromRule.NamespaceSelector != nil || fromRule.IPBlock != nil { fromRuleExists = true + break } } } @@ -542,6 +543,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net toRule.NamespaceSelector != nil || toRule.IPBlock != nil { toRuleExists = true + break } } } From 5a3d5cdea7550a1dcab330fc0b2e620de833d7cf Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 30 Aug 2019 01:20:23 +0000 Subject: [PATCH 61/64] add AZURE-NPM-KUBE-SYSTEM chain --- npm/iptm/iptm.go | 29 ++++++++++++++++++++++++++++- npm/translatePolicy.go | 4 ++-- npm/translatePolicy_test.go | 20 -------------------- npm/util/const.go | 1 + 4 files changed, 31 insertions(+), 23 deletions(-) diff --git a/npm/iptm/iptm.go b/npm/iptm/iptm.go index 1c1a938a72..5d2e0d74a2 100644 --- a/npm/iptm/iptm.go +++ b/npm/iptm/iptm.go @@ -99,6 +99,32 @@ func (iptMgr *IptablesManager) InitNpmChains() error { } } + // Create AZURE-NPM-KUBE-SYSTEM chain. + if err := iptMgr.AddChain(util.IptablesAzureKubeSystemChain); err != nil { + return err + } + + // Append AZURE-NPM-KUBE-SYSTEM chain to AZURE-NPM chain. + entry = &IptEntry{ + Chain: util.IptablesAzureChain, + Specs: []string{ + util.IptablesJumpFlag, + util.IptablesAzureKubeSystemChain, + }, + } + exists, err = iptMgr.Exists(entry) + if err != nil { + return err + } + + if !exists { + iptMgr.OperationFlag = util.IptablesAppendFlag + if _, err = iptMgr.Run(entry); err != nil { + log.Errorf("Error: failed to add AZURE-NPM-KUBE-SYSTEM chain to AZURE-NPM chain.") + return err + } + } + // Create AZURE-NPM-INGRESS-PORT chain. if err := iptMgr.AddChain(util.IptablesAzureIngressPortChain); err != nil { return err @@ -179,6 +205,7 @@ func (iptMgr *IptablesManager) InitNpmChains() error { func (iptMgr *IptablesManager) UninitNpmChains() error { IptablesAzureChainList := []string{ util.IptablesAzureChain, + util.IptablesAzureKubeSystemChain, util.IptablesAzureIngressPortChain, util.IptablesAzureIngressFromChain, util.IptablesAzureEgressPortChain, @@ -269,7 +296,7 @@ func (iptMgr *IptablesManager) DeleteChain(chain string) error { log.Printf("Chain doesn't exist %s.", entry.Chain) return nil } - + log.Errorf("Error: failed to delete iptables chain %s.", entry.Chain) return err } diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 0e098c943d..75f18cfab1 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -913,7 +913,7 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ hashedKubeSystemSet := util.GetHashedName("ns-" + util.KubeSystemFlag) targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) allowKubeSystemIngress := &iptm.IptEntry{ - Chain: util.IptablesAzureChain, + Chain: util.IptablesAzureKubeSystemChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, @@ -932,7 +932,7 @@ func getAllowKubeSystemEntries(ns string, targetSelector metav1.LabelSelector) [ entries = append(entries, allowKubeSystemIngress) allowKubeSystemEgress := &iptm.IptEntry{ - Chain: util.IptablesAzureChain, + Chain: util.IptablesAzureKubeSystemChain, Specs: []string{ util.IptablesModuleFlag, util.IptablesSetModuleFlag, diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index 735251381b..a5fd73d6a6 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -1011,26 +1011,6 @@ func TestTranslatePolicy(t *testing.T) { t.Errorf("expectedLists: %v", expectedLists) } - /* - expectedIptEntries = []*iptm.IptEntry{ - &iptm.IptEntry{ - Chain: util.IptablesAzureIngressPortChain, - Specs: []string{ - util.IptablesModuleFlag, - util.IptablesSetModuleFlag, - util.IptablesMatchSetFlag, - util.GetHashedName("ns-testnamespace"), - util.IptablesSrcFlag, - util.IptablesJumpFlag, - util.IptablesAccept, - util.IptablesModuleFlag, - util.IptablesCommentModuleFlag, - util.IptablesCommentFlag, - "ALLOW-ALL-TO-ns-testnamespace", - }, - }, - } - */ expectedIptEntries := []*iptm.IptEntry{} expectedIptEntries = append( expectedIptEntries, diff --git a/npm/util/const.go b/npm/util/const.go index c05bf9a029..b1910f56ca 100644 --- a/npm/util/const.go +++ b/npm/util/const.go @@ -61,6 +61,7 @@ const ( IptablesCommentFlag string = "--comment" IptablesAddCommentFlag IptablesAzureChain string = "AZURE-NPM" + IptablesAzureKubeSystemChain string = "AZURE-NPM-KUBE-SYSTEM" IptablesAzureIngressPortChain string = "AZURE-NPM-INGRESS-PORT" IptablesAzureIngressFromChain string = "AZURE-NPM-INGRESS-FROM" IptablesAzureEgressPortChain string = "AZURE-NPM-EGRESS-PORT" From 20db12f94314db99927b7c4ef65099a9617ca80d Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 30 Aug 2019 01:31:36 +0000 Subject: [PATCH 62/64] use nsName --- npm/namespace.go | 62 ++++++++++++++++++++++++------------------------ 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/npm/namespace.go b/npm/namespace.go index 135691ed15..28b46623e1 100644 --- a/npm/namespace.go +++ b/npm/namespace.go @@ -93,18 +93,18 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { var err error - nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("NAMESPACE CREATING: [%s/%v]", nsNs, nsLabel) + nsName, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Labels + log.Printf("NAMESPACE CREATING: [%s/%v]", nsName, nsLabel) ipsMgr := npMgr.nsMap[util.KubeAllNamespacesFlag].ipsMgr // Create ipset for the namespace. - if err = ipsMgr.CreateSet(nsNs); err != nil { - log.Errorf("Error: failed to create ipset for namespace %s.", nsNs) + if err = ipsMgr.CreateSet(nsName); err != nil { + log.Errorf("Error: failed to create ipset for namespace %s.", nsName) return err } - if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsNs); err != nil { - log.Errorf("Error: failed to add %s to all-namespace ipset list.", nsNs) + if err = ipsMgr.AddToList(util.KubeAllNamespacesFlag, nsName); err != nil { + log.Errorf("Error: failed to add %s to all-namespace ipset list.", nsName) return err } @@ -112,25 +112,25 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := "ns-" + nsLabelKey - log.Printf("Adding namespace %s to ipset list %s", nsNs, labelKey) - if err = ipsMgr.AddToList(labelKey, nsNs); err != nil { - log.Errorf("Error: failed to add namespace %s to ipset list %s", nsNs, labelKey) + log.Printf("Adding namespace %s to ipset list %s", nsName, labelKey) + if err = ipsMgr.AddToList(labelKey, nsName); err != nil { + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, labelKey) return err } label := "ns-" + nsLabelKey + ":" + nsLabelVal - log.Printf("Adding namespace %s to ipset list %s", nsNs, label) - if err = ipsMgr.AddToList(label, nsNs); err != nil { - log.Errorf("Error: failed to add namespace %s to ipset list %s", nsNs, label) + log.Printf("Adding namespace %s to ipset list %s", nsName, label) + if err = ipsMgr.AddToList(label, nsName); err != nil { + log.Errorf("Error: failed to add namespace %s to ipset list %s", nsName, label) return err } } - ns, err := newNs(nsNs) + ns, err := newNs(nsName) if err != nil { - log.Errorf("Error: failed to create namespace %s", nsNs) + log.Errorf("Error: failed to create namespace %s", nsName) } - npMgr.nsMap[nsNs] = ns + npMgr.nsMap[nsName] = ns return nil } @@ -139,8 +139,8 @@ func (npMgr *NetworkPolicyManager) AddNamespace(nsObj *corev1.Namespace) error { func (npMgr *NetworkPolicyManager) UpdateNamespace(oldNsObj *corev1.Namespace, newNsObj *corev1.Namespace) error { var err error - oldNsNs, oldNsLabel := "ns-" + oldNsObj.ObjectMeta.Namespace, oldNsObj.ObjectMeta.Labels - newNsNs, newNsLabel := "ns-" + newNsObj.ObjectMeta.Namespace, newNsObj.ObjectMeta.Labels + oldNsNs, oldNsLabel := "ns-" + oldNsObj.ObjectMeta.Name, oldNsObj.ObjectMeta.Labels + newNsNs, newNsLabel := "ns-" + newNsObj.ObjectMeta.Name, newNsObj.ObjectMeta.Labels log.Printf( "NAMESPACE UPDATING:\n old namespace: [%s/%v]\n new namespace: [%s/%v]", oldNsNs, oldNsLabel, newNsNs, newNsLabel, @@ -166,10 +166,10 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro var err error - nsNs, nsLabel := "ns-" + nsObj.ObjectMeta.Namespace, nsObj.ObjectMeta.Labels - log.Printf("NAMESPACE DELETING: [%s/%v]", nsNs, nsLabel) + nsName, nsLabel := "ns-" + nsObj.ObjectMeta.Name, nsObj.ObjectMeta.Labels + log.Printf("NAMESPACE DELETING: [%s/%v]", nsName, nsLabel) - _, exists := npMgr.nsMap[nsNs] + _, exists := npMgr.nsMap[nsName] if !exists { return nil } @@ -179,33 +179,33 @@ func (npMgr *NetworkPolicyManager) DeleteNamespace(nsObj *corev1.Namespace) erro nsLabels := nsObj.ObjectMeta.Labels for nsLabelKey, nsLabelVal := range nsLabels { labelKey := "ns-" + nsLabelKey - log.Printf("Deleting namespace %s from ipset list %s", nsNs, labelKey) - if err = ipsMgr.DeleteFromList(labelKey, nsNs); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, labelKey) + log.Printf("Deleting namespace %s from ipset list %s", nsName, labelKey) + if err = ipsMgr.DeleteFromList(labelKey, nsName); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, labelKey) return err } label := "ns-" + nsLabelKey + ":" + nsLabelVal - log.Printf("Deleting namespace %s from ipset list %s", nsNs, label) - if err = ipsMgr.DeleteFromList(label, nsNs); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, label) + log.Printf("Deleting namespace %s from ipset list %s", nsName, label) + if err = ipsMgr.DeleteFromList(label, nsName); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, label) return err } } // Delete the namespace from all-namespace ipset list. - if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsNs); err != nil { - log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsNs, util.KubeAllNamespacesFlag) + if err = ipsMgr.DeleteFromList(util.KubeAllNamespacesFlag, nsName); err != nil { + log.Errorf("Error: failed to delete namespace %s from ipset list %s", nsName, util.KubeAllNamespacesFlag) return err } // Delete ipset for the namespace. - if err = ipsMgr.DeleteSet(nsNs); err != nil { - log.Errorf("Error: failed to delete ipset for namespace %s.", nsNs) + if err = ipsMgr.DeleteSet(nsName); err != nil { + log.Errorf("Error: failed to delete ipset for namespace %s.", nsName) return err } - delete(npMgr.nsMap, nsNs) + delete(npMgr.nsMap, nsName) return nil } From d5ea6a39231f30fc594c1fd52e86753b098ac416 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 30 Aug 2019 03:49:53 +0000 Subject: [PATCH 63/64] process rules separately --- npm/translatePolicy.go | 12 +++++------- npm/translatePolicy_test.go | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index 75f18cfab1..f6c920e14d 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -148,9 +148,6 @@ func craftPartialIptablesCommentFromSelector(ns string, selector *metav1.LabelSe func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyIngressRule) ([]string, []string, []*iptm.IptEntry) { var ( - allowExternal = false - portRuleExists = false - fromRuleExists = false sets []string // ipsets with type: net:hash lists []string // ipsets with type: list:set entries []*iptm.IptEntry @@ -172,6 +169,8 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { + allowExternal, portRuleExists, fromRuleExists := false, false, false + if len(rule.Ports) > 0 { portRuleExists = true } @@ -506,9 +505,6 @@ func translateIngress(ns string, targetSelector metav1.LabelSelector, rules []ne func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []networkingv1.NetworkPolicyEgressRule) ([]string, []string, []*iptm.IptEntry) { var ( - allowExternal = false - portRuleExists = false - toRuleExists = false sets []string // ipsets with type: net:hash lists []string // ipsets with type: list:set entries []*iptm.IptEntry @@ -528,6 +524,8 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net targetSelectorIptEntrySpec := craftPartialIptEntrySpecFromOpsAndLabels(ns, ops, labels, util.IptablesSrcFlag, false) targetSelectorComment := craftPartialIptablesCommentFromSelector(ns, &targetSelector, false) for _, rule := range rules { + allowExternal, portRuleExists, toRuleExists := false, false, false + if len(rule.Ports) > 0 { portRuleExists = true } @@ -628,7 +626,7 @@ func translateEgress(ns string, targetSelector metav1.LabelSelector, rules []net entry.Specs = append( entry.Specs, util.IptablesJumpFlag, - util.IptablesAzureEgressPortChain, + util.IptablesAzureEgressToChain, util.IptablesModuleFlag, util.IptablesCommentModuleFlag, util.IptablesCommentFlag, diff --git a/npm/translatePolicy_test.go b/npm/translatePolicy_test.go index a5fd73d6a6..5951ddc928 100644 --- a/npm/translatePolicy_test.go +++ b/npm/translatePolicy_test.go @@ -2449,6 +2449,23 @@ func TestTranslatePolicy(t *testing.T) { "ALLOW-ALL-FROM-UDP-PORT-53-OF-app:frontend", }, }, + &iptm.IptEntry{ + Chain: util.IptablesAzureEgressPortChain, + Specs: []string{ + util.IptablesModuleFlag, + util.IptablesSetModuleFlag, + util.IptablesMatchSetFlag, + util.GetHashedName("app:frontend"), + util.IptablesSrcFlag, + util.IptablesJumpFlag, + util.IptablesAzureEgressToChain, + util.IptablesModuleFlag, + util.IptablesCommentModuleFlag, + util.IptablesCommentFlag, + "ALLOW-ALL-FROM-app:frontend-TO-JUMP-TO-" + + util.IptablesAzureEgressToChain, + }, + }, &iptm.IptEntry{ Chain: util.IptablesAzureEgressToChain, Specs: []string{ From ae2ccf35d0f7a556b7554f21b055d0081fc445c6 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Fri, 30 Aug 2019 19:03:44 +0000 Subject: [PATCH 64/64] defer translatePolicy result print --- npm/translatePolicy.go | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/npm/translatePolicy.go b/npm/translatePolicy.go index f6c920e14d..fc636ea47f 100644 --- a/npm/translatePolicy.go +++ b/npm/translatePolicy.go @@ -967,6 +967,16 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* log.Printf("Translating network policy:\n %+v", npObj) + defer func() { + log.Printf("Finished translatePolicy") + log.Printf("sets: %v", resultSets) + log.Printf("lists: %v", resultLists) + log.Printf("entries: ") + for _, entry := range entries { + log.Printf("entry: %+v", entry) + } + }() + npNs := npObj.ObjectMeta.Namespace // Allow kube-system pods entries = append(entries, getAllowKubeSystemEntries(npNs, npObj.Spec.PodSelector)...) @@ -1007,13 +1017,5 @@ func translatePolicy(npObj *networkingv1.NetworkPolicy) ([]string, []string, []* resultSets, resultLists = util.UniqueStrSlice(resultSets), util.UniqueStrSlice(resultLists) - log.Printf("Finished translatePolicy") - log.Printf("sets: %v", resultSets) - log.Printf("lists: %v", resultLists) - log.Printf("entries: ") - for _, entry := range entries { - log.Printf("entry: %+v", entry) - } - return resultSets, resultLists, entries }