func translateRule()

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
}