in npm/pkg/controlplane/translation/translatePolicy.go [366:498]
func translateRule(npmNetPol *policies.NPMNetworkPolicy,
netPolName string,
direction policies.Direction,
matchType policies.MatchType,
ruleIndex int,
ports []networkingv1.NetworkPolicyPort,
peers []networkingv1.NetworkPolicyPeer,
npmLiteToggle bool,
) error {
// TODO(jungukcho): need to clean up it.
// Leave allowExternal variable now while the condition is checked before calling this function.
allowExternal, portRuleExists, peerRuleExists := ruleExists(ports, peers)
// #0. TODO(jungukcho): cannot come up when this condition is met.
// The code inside if condition is to handle allowing all internal traffic, but the case is handled in #2.4.
// So, this code may not execute. After confirming this, need to delete it.
if !portRuleExists && !peerRuleExists && !allowExternal {
if npmLiteToggle {
return ErrUnsupportedNonCIDR
}
acl := policies.NewACLPolicy(policies.Allowed, direction)
ruleIPSets, allowAllInternalSetInfo := allowAllInternal(matchType)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, ruleIPSets)
acl.AddSetInfo([]policies.SetInfo{allowAllInternalSetInfo})
npmNetPol.ACLs = append(npmNetPol.ACLs, acl)
return nil
}
err := checkOnlyPortRuleExists(portRuleExists, peerRuleExists, allowExternal, ports, npmLiteToggle, direction, npmNetPol)
if err != nil {
return err
}
// #2. From or To fields exist in rule
for peerIdx, peer := range peers {
// NPM Lite is enabled and peer is non-cidr block
if npmLiteToggle && peer.IPBlock == nil {
return ErrUnsupportedNonCIDR
}
// #2.1 Handle IPBlock and port if exist
if peer.IPBlock != nil {
if len(peer.IPBlock.CIDR) > 0 {
ipBlockIPSet, ipBlockSetInfo, err := ipBlockRule(netPolName, npmNetPol.Namespace, direction, matchType, ruleIndex, peerIdx, peer.IPBlock)
if err != nil {
return err
}
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, ipBlockIPSet)
err = peerAndPortRule(npmNetPol, direction, ports, []policies.SetInfo{ipBlockSetInfo}, npmLiteToggle)
if err != nil {
return err
}
}
// if npm lite is configured, check network policy only consists of CIDR blocks
err := npmLiteValidPolicy(peer, npmLiteToggle)
if err != nil {
return err
}
// Do not need to run below code to translate PodSelector and NamespaceSelector
// since IPBlock field is exclusive in NetworkPolicyPeer (i.e., peer in this code).
continue
}
// if there is no PodSelector or NamespaceSelector in peer, no need to run the rest of codes.
if peer.PodSelector == nil && peer.NamespaceSelector == nil {
continue
}
// #2.2 handle nameSpaceSelector and port if exist
if peer.PodSelector == nil && peer.NamespaceSelector != nil {
// Before translating NamespaceSelector, flattenNameSpaceSelector function call should be called
// to handle multiple values in matchExpressions spec.
flattenNSSelector, err := flattenNameSpaceSelector(peer.NamespaceSelector)
if err != nil {
return err
}
for i := range flattenNSSelector {
nsSelectorIPSets, nsSelectorList := nameSpaceSelector(matchType, &flattenNSSelector[i])
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, nsSelectorIPSets...)
err := peerAndPortRule(npmNetPol, direction, ports, nsSelectorList, npmLiteToggle)
if err != nil {
return err
}
}
continue
}
// #2.3 handle podSelector and port if exist
if peer.PodSelector != nil && peer.NamespaceSelector == nil {
psResult, err := podSelectorWithNS(npmNetPol.PolicyKey, npmNetPol.Namespace, matchType, peer.PodSelector)
if err != nil {
return err
}
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.psSets...)
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, psResult.childPSSets...)
err = peerAndPortRule(npmNetPol, direction, ports, psResult.psList, npmLiteToggle)
if err != nil {
return err
}
continue
}
// #2.4 handle namespaceSelector and podSelector and port if exist
psResult, err := podSelector(npmNetPol.PolicyKey, matchType, peer.PodSelector)
if err != nil {
return err
}
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, err := flattenNameSpaceSelector(peer.NamespaceSelector)
if err != nil {
return err
}
for i := range flattenNSSelector {
nsSelectorIPSets, nsSelectorList := nameSpaceSelector(matchType, &flattenNSSelector[i])
npmNetPol.RuleIPSets = append(npmNetPol.RuleIPSets, nsSelectorIPSets...)
nsSelectorList = append(nsSelectorList, psResult.psList...)
err := peerAndPortRule(npmNetPol, direction, ports, nsSelectorList, npmLiteToggle)
if err != nil {
return err
}
}
}
return nil
}