Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 41 additions & 26 deletions npm/pkg/controlplane/translation/translatePolicy.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ var (
ErrUnsupportedNegativeMatch = errors.New("unsupported NotExist operator translation features used on windows")
)

type podSelectorResult struct {
psSets []*ipsets.TranslatedIPSet
childPSSets []*ipsets.TranslatedIPSet
psList []policies.SetInfo
}

type netpolPortType string

const (
Expand Down Expand Up @@ -214,42 +220,47 @@ func ipBlockRule(policyName, ns string, direction policies.Direction, matchType
return ipBlockIPSet, setInfo
}

// PodSelector translates podSelector of NetworkPolicyPeer field in networkpolicy object to translatedIPSet and SetInfo.
// PodSelector translates podSelector of NetworkPolicyPeer field in networkpolicy object to translatedIPSets, children of translated IPSets, and SetInfo.
// Children are members of a list-type IPSet.
// This function is called only when the NetworkPolicyPeer has namespaceSelector field.
func podSelector(policyKey string, matchType policies.MatchType, selector *metav1.LabelSelector) ([]*ipsets.TranslatedIPSet, []policies.SetInfo, error) {
func podSelector(policyKey string, matchType policies.MatchType, selector *metav1.LabelSelector) (*podSelectorResult, error) {
podSelectors, err := parsePodSelector(policyKey, selector)
if err != nil {
return nil, nil, err
return nil, err
}
lenOfPodSelectors := len(podSelectors)
podSelectorIPSets := []*ipsets.TranslatedIPSet{}
podSelectorList := make([]policies.SetInfo, lenOfPodSelectors)

lenOfPodSelectors := len(podSelectors)
psResult := &podSelectorResult{
psSets: make([]*ipsets.TranslatedIPSet, 0),
childPSSets: make([]*ipsets.TranslatedIPSet, 0),
psList: make([]policies.SetInfo, lenOfPodSelectors),
}
for i := 0; i < lenOfPodSelectors; i++ {
ps := podSelectors[i]
podSelectorIPSets = append(podSelectorIPSets, ipsets.NewTranslatedIPSet(ps.setName, ps.setType, ps.members...))
psResult.psSets = append(psResult.psSets, ipsets.NewTranslatedIPSet(ps.setName, ps.setType, ps.members...))

// if value is nested value, create translatedIPSet with the nested value
for j := 0; j < len(ps.members); j++ {
podSelectorIPSets = append(podSelectorIPSets, ipsets.NewTranslatedIPSet(ps.members[j], ipsets.KeyValueLabelOfPod))
psResult.childPSSets = append(psResult.childPSSets, ipsets.NewTranslatedIPSet(ps.members[j], ipsets.KeyValueLabelOfPod))
}

podSelectorList[i] = policies.NewSetInfo(ps.setName, ps.setType, ps.include, matchType)
psResult.psList[i] = policies.NewSetInfo(ps.setName, ps.setType, ps.include, matchType)
}

return podSelectorIPSets, podSelectorList, nil
return psResult, nil
}

// podSelectorWithNS translates podSelector of spec and NetworkPolicyPeer in networkpolicy object to translatedIPSet and SetInfo.
// podSelectorWithNS translates podSelector of spec and NetworkPolicyPeer in networkpolicy object to translatedIPSets, children of translated IPSets, and SetInfo.
// Children are members of a list-type IPSet.
// This function is called only when the NetworkPolicyPeer does not have namespaceSelector field.
func podSelectorWithNS(policyKey, ns string, matchType policies.MatchType, selector *metav1.LabelSelector) ([]*ipsets.TranslatedIPSet, []policies.SetInfo, error) {
podSelectorIPSets, podSelectorList, err := podSelector(policyKey, matchType, selector)
func podSelectorWithNS(policyKey, ns string, matchType policies.MatchType, selector *metav1.LabelSelector) (*podSelectorResult, error) {
psResult, err := podSelector(policyKey, matchType, selector)
if err != nil {
return nil, nil, err
return nil, err
}
// Add translatedIPSet and SetInfo based on namespace
podSelectorIPSets = append(podSelectorIPSets, ipsets.NewTranslatedIPSet(ns, ipsets.Namespace))
podSelectorList = append(podSelectorList, policies.NewSetInfo(ns, ipsets.Namespace, included, matchType))
return podSelectorIPSets, podSelectorList, nil
psResult.psSets = append(psResult.psSets, ipsets.NewTranslatedIPSet(ns, ipsets.Namespace))
psResult.psList = append(psResult.psList, policies.NewSetInfo(ns, ipsets.Namespace, included, matchType))
return psResult, nil
}

// nameSpaceSelector translates namespaceSelector of NetworkPolicyPeer in networkpolicy object to translatedIPSet and SetInfo.
Expand Down Expand Up @@ -397,12 +408,13 @@ func translateRule(npmNetPol *policies.NPMNetworkPolicy, netPolName string, dire

// #2.3 handle podSelector and port if exist
if peer.PodSelector != nil && peer.NamespaceSelector == nil {
podSelectorIPSets, podSelectorList, err := podSelectorWithNS(npmNetPol.PolicyKey, npmNetPol.Namespace, matchType, peer.PodSelector)
psResult, err := podSelectorWithNS(npmNetPol.PolicyKey, npmNetPol.Namespace, matchType, peer.PodSelector)
if err != nil {
return err
}
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, podSelectorIPSets...)
err = peerAndPortRule(npmNetPol, direction, ports, podSelectorList)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.psSets...)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.childPSSets...)
err = peerAndPortRule(npmNetPol, direction, ports, psResult.psList)
if err != nil {
return err
}
Expand All @@ -418,19 +430,20 @@ func translateRule(npmNetPol *policies.NPMNetworkPolicy, netPolName string, dire
}

// #2.4 handle namespaceSelector and podSelector and port if exist
podSelectorIPSets, podSelectorList, err := podSelector(npmNetPol.PolicyKey, matchType, peer.PodSelector)
psResult, err := podSelector(npmNetPol.PolicyKey, matchType, peer.PodSelector)
if err != nil {
return err
}
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, podSelectorIPSets...)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.psSets...)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.childPSSets...)

// Before translating NamespaceSelector, flattenNameSpaceSelector function call should be called
// to handle multiple values in matchExpressions spec.
flattenNSSelector := flattenNameSpaceSelector(peer.NamespaceSelector)
for i := range flattenNSSelector {
nsSelectorIPSets, nsSelectorList := nameSpaceSelector(matchType, &flattenNSSelector[i])
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, nsSelectorIPSets...)
nsSelectorList = append(nsSelectorList, podSelectorList...)
nsSelectorList = append(nsSelectorList, psResult.psList...)
err := peerAndPortRule(npmNetPol, direction, ports, nsSelectorList)
if err != nil {
return err
Expand Down Expand Up @@ -541,11 +554,13 @@ func TranslatePolicy(npObj *networkingv1.NetworkPolicy) (*policies.NPMNetworkPol

// podSelector in spec.PodSelector is common for ingress and egress.
// Process this podSelector first.
var err error
npmNetPol.PodSelectorIPSets, npmNetPol.PodSelectorList, err = podSelectorWithNS(npmNetPol.PolicyKey, npmNetPol.Namespace, policies.EitherMatch, &npObj.Spec.PodSelector)
psResult, err := podSelectorWithNS(npmNetPol.PolicyKey, npmNetPol.Namespace, policies.EitherMatch, &npObj.Spec.PodSelector)
if err != nil {
return nil, err
}
npmNetPol.PodSelectorIPSets = psResult.psSets
npmNetPol.ChildPodSelectorIPSets = psResult.childPSSets
npmNetPol.PodSelectorList = psResult.psList

// Each NetworkPolicy includes a policyTypes list which may include either Ingress, Egress, or both.
// If no policyTypes are specified on a NetworkPolicy then by default Ingress will always be set
Expand Down
Loading