diff --git a/pkg/internal/netpolerrors/netpol_errors.go b/pkg/internal/netpolerrors/netpol_errors.go index 3c4c033d..1981af19 100644 --- a/pkg/internal/netpolerrors/netpol_errors.go +++ b/pkg/internal/netpolerrors/netpol_errors.go @@ -98,7 +98,11 @@ func MissingNamespaceErrStr(peerStr string) string { // NotPeerErrStr returns error string of a peer that is not workload peer func NotPeerErrStr(peerStr string) string { - return "peer: " + peerStr + ",is not a WorkloadPeer" + return "peer: " + peerStr + ", is not a WorkloadPeer" +} + +func NotRepresentativePeerErrStr(peerStr string) string { + return peerStr + ", is not a Representative peer" } // BothSrcAndDstIPsErrStr returns error string that conn from ip to ip is not supported diff --git a/pkg/netpol/connlist/connlist.go b/pkg/netpol/connlist/connlist.go index 98dbdf6c..526f431a 100644 --- a/pkg/netpol/connlist/connlist.go +++ b/pkg/netpol/connlist/connlist.go @@ -366,7 +366,7 @@ func GetConnectionSetFromP2PConnection(c Peer2PeerConnection) *common.Connection ////////////////////////////////////////////////////////////////////////////////////////////// -func (ca *ConnlistAnalyzer) includePairOfWorkloads(src, dst eval.Peer) bool { +func (ca *ConnlistAnalyzer) includePairOfWorkloads(pe *eval.PolicyEngine, src, dst eval.Peer) bool { if src.IsPeerIPType() && dst.IsPeerIPType() { return false } @@ -375,8 +375,8 @@ func (ca *ConnlistAnalyzer) includePairOfWorkloads(src, dst eval.Peer) bool { if src.String() == dst.String() { return false } - // when exposure-analysis, skip conns between fake pods (exposure or ingress-controller) or ip-peer and fake pods - if ca.exposureAnalysis && ca.hasFakePodsAndIPs(src, dst) { + // when exposure-analysis, skip conns between fake pods or ip-peer and fake pods + if ca.exposureAnalysis && ca.hasFakePodsAndIPs(pe, src, dst) { return false } if ca.focusWorkload == "" { @@ -386,21 +386,20 @@ func (ca *ConnlistAnalyzer) includePairOfWorkloads(src, dst eval.Peer) bool { return ca.isPeerFocusWorkload(src) || ca.isPeerFocusWorkload(dst) } -// TODO : enhance this after implementing representative peers -func (ca *ConnlistAnalyzer) hasFakePodsAndIPs(src, dst eval.Peer) bool { - if src.IsPeerIPType() && dst.Name() == common.PodInRepNs { +func (ca *ConnlistAnalyzer) hasFakePodsAndIPs(pe *eval.PolicyEngine, src, dst eval.Peer) bool { + // if both peers are Representative + if pe.IsRepresentativePeer(src) && pe.IsRepresentativePeer(dst) { return true } - if src.Name() == common.PodInRepNs && dst.IsPeerIPType() { + // if one peer is IP and the other is a representative peer + if (src.IsPeerIPType() || dst.IsPeerIPType()) && + (pe.IsRepresentativePeer(src) || pe.IsRepresentativePeer(dst)) { return true } - if src.Name() == common.PodInRepNs && dst.Name() == common.PodInRepNs { - return true - } - if src.Name() == common.PodInRepNs && dst.Name() == common.IngressPodName { - return true - } - if src.Name() == common.IngressPodName && dst.Name() == common.PodInRepNs { + // if one peer is fake ingress-pod and the other is a representative peer + // todo: might check if peer is a fake ingress-controller by checking name and fakePod flag (within new pe func) + if (src.Name() == common.IngressPodName || dst.Name() == common.IngressPodName) && + (pe.IsRepresentativePeer(src) || pe.IsRepresentativePeer(dst)) { return true } return false @@ -435,6 +434,15 @@ func (ca *ConnlistAnalyzer) getConnectionsList(pe *eval.PolicyEngine, ia *ingres peers[i] = p } + // connPeers represents []connlist.Peer to be sent to ca.getConnectionsBetweenPeers + connPeers := peers + if ca.exposureAnalysis { + representativePeers := pe.GetRepresentativePeersList() + for _, p := range representativePeers { + connPeers = append(connPeers, p) + } + } + excludeIngressAnalysis := (ia == nil || ia.IsEmpty()) // if ca.focusWorkload is not empty, check if it exists in the peers before proceeding @@ -447,7 +455,7 @@ func (ca *ConnlistAnalyzer) getConnectionsList(pe *eval.PolicyEngine, ia *ingres // compute connections between peers based on pe analysis of network policies // if exposure-analysis is on, also compute and return the exposures-map - peersAllowedConns, exposuresMap, err := ca.getConnectionsBetweenPeers(pe, peers) + peersAllowedConns, exposuresMap, err := ca.getConnectionsBetweenPeers(pe, connPeers) if err != nil { ca.errors = append(ca.errors, newResourceEvaluationError(err)) return nil, nil, err @@ -511,7 +519,7 @@ func (ca *ConnlistAnalyzer) getConnectionsBetweenPeers(pe *eval.PolicyEngine, pe srcPeer := peers[i] for j := range peers { dstPeer := peers[j] - if !ca.includePairOfWorkloads(srcPeer, dstPeer) { + if !ca.includePairOfWorkloads(pe, srcPeer, dstPeer) { continue } allowedConnections, err := pe.AllAllowedConnectionsBetweenWorkloadPeers(srcPeer, dstPeer) @@ -555,7 +563,7 @@ func (ca *ConnlistAnalyzer) getIngressAllowedConnections(ia *ingressanalyzer.Ing } for peerStr, peerAndConn := range ingressConns { // refines to only relevant connections if ca.focusWorkload is not empty - if !ca.includePairOfWorkloads(ingressControllerPod, peerAndConn.Peer) { + if !ca.includePairOfWorkloads(pe, ingressControllerPod, peerAndConn.Peer) { continue } // compute allowed connections based on pe.policies to the peer, then intersect the conns with @@ -606,21 +614,15 @@ func (ca *ConnlistAnalyzer) checkIfP2PConnOrExposureConn(pe *eval.PolicyEngine, } // else exposure analysis is on - // TODO : enhance this if condition after implementing eval.RepresentativePeer - if src.Name() != common.PodInRepNs && dst.Name() != common.PodInRepNs { + if !pe.IsRepresentativePeer(src) && !pe.IsRepresentativePeer(dst) { // both src and dst are peers are found in the parsed resources return createConnectionObject(allowedConnections, src, dst), nil } - // else: one of the peers is inferred from a netpol-rule , and the other is a peer from the parsed resources + // else: one of the peers is a representative peer (inferred from a netpol-rule) , + // and the other is a peer from the parsed resources // an exposure analysis connection - var err error - if src.Name() != common.PodInRepNs { - // dst is the inferred from netpol peer, we have an exposed egress for the src peer - err = exposuresMap.addConnToExposureMap(pe, allowedConnections, src, dst, false) - } else { - // src is the inferred from netpol peer, we have an exposed ingress to the dst peer - err = exposuresMap.addConnToExposureMap(pe, allowedConnections, src, dst, true) - } + isIngress := pe.IsRepresentativePeer(src) + err := exposuresMap.addConnToExposureMap(pe, allowedConnections, src, dst, isIngress) return nil, err } @@ -646,7 +648,7 @@ func updatePeersGeneralExposureData(pe *eval.PolicyEngine, src, dst Peer, ingres // (e.g. only one peer with one netpol exposing the peer to entire cluster, no netpols) var err error // 1. only on first time : add general exposure data for the src peer (on egress) - if !src.IsPeerIPType() && src.Name() != common.PodInRepNs && !egressSet[src] { + if !src.IsPeerIPType() && !pe.IsRepresentativePeer(src) && !egressSet[src] { err = exMap.addPeerGeneralExposure(pe, src, false) if err != nil { return err @@ -654,7 +656,7 @@ func updatePeersGeneralExposureData(pe *eval.PolicyEngine, src, dst Peer, ingres } egressSet[src] = true // 2. only on first time : add general exposure data for the dst peer (on ingress) - if !dst.IsPeerIPType() && dst.Name() != common.PodInRepNs && !ingressSet[dst] { + if !dst.IsPeerIPType() && !pe.IsRepresentativePeer(dst) && !ingressSet[dst] { err = exMap.addPeerGeneralExposure(pe, dst, true) } ingressSet[dst] = true diff --git a/pkg/netpol/connlist/exposure_map.go b/pkg/netpol/connlist/exposure_map.go index c808a456..d9f1fd39 100644 --- a/pkg/netpol/connlist/exposure_map.go +++ b/pkg/netpol/connlist/exposure_map.go @@ -90,11 +90,11 @@ func (ex exposureMap) addPeerXgressEntireClusterExp(pe *eval.PolicyEngine, peer // finally the map will include refined lists of ingress and egress exposure connections for each workload peer func (ex exposureMap) addConnToExposureMap(pe *eval.PolicyEngine, allowedConnections common.Connection, src, dst Peer, isIngress bool) error { - peer := src // real peer - inferredPeer := dst // inferred from netpol rule + peer := src // real peer + representativePeer := dst // inferred from netpol rule if isIngress { peer = dst - inferredPeer = src + representativePeer = src } // if peer is not protected return protected, err := pe.IsPeerProtected(peer, isIngress) @@ -122,18 +122,19 @@ func (ex exposureMap) addConnToExposureMap(pe *eval.PolicyEngine, allowedConnect if _, ok := ex[peer]; !ok { ex.initiatePeerEntry(peer) } + + nsLabels, err := pe.GetPeerNsLabels(representativePeer) + if err != nil { + return err + } // store connection data expData := &xgressExposure{ exposedToEntireCluster: false, - namespaceLabels: pe.GetPeerNsLabels(inferredPeer), + namespaceLabels: nsLabels, podLabels: map[string]string{}, // will be empty since in this branch rules with namespaceSelectors only supported potentialConn: allowedConnSet, } - if isIngress { - ex.appendPeerXgressExposureData(peer, expData, true) - } else { // egress - ex.appendPeerXgressExposureData(peer, expData, false) - } + ex.appendPeerXgressExposureData(peer, expData, isIngress) return nil } diff --git a/pkg/netpol/eval/check.go b/pkg/netpol/eval/check.go index 6d70c293..0da249b5 100644 --- a/pkg/netpol/eval/check.go +++ b/pkg/netpol/eval/check.go @@ -63,16 +63,33 @@ func (pe *PolicyEngine) CheckIfAllowed(src, dst, protocol, port string) (bool, e return ingressRes, nil } -func (pe *PolicyEngine) convertWorkloadPeerToPodPeer(peer Peer) (*k8s.PodPeer, error) { - if workloadPeer, ok := peer.(*k8s.WorkloadPeer); ok { - podNamespace, ok := pe.namspacesMap[workloadPeer.Pod.Namespace] - if !ok { - return nil, errors.New(netpolerrors.MissingNamespaceErrStr(workloadPeer.String())) - } - podPeer := &k8s.PodPeer{Pod: workloadPeer.Pod, NamespaceObject: podNamespace} - return podPeer, nil +func (pe *PolicyEngine) convertPeerToPodPeer(peer Peer) (*k8s.PodPeer, error) { + var podObj *k8s.Pod + var podNamespace *k8s.Namespace + var err error + switch currPeer := peer.(type) { + case *k8s.WorkloadPeer: + podObj = currPeer.Pod + podNamespace, err = pe.getPeerNamespaceObject(currPeer.Pod.Namespace, currPeer.String()) + case *k8s.RepresentativePeer: + podObj = currPeer.Pod + podNamespace, err = pe.getPeerNamespaceObject(currPeer.Pod.Namespace, currPeer.String()) + default: // should not get here + return nil, errors.New(netpolerrors.InvalidPeerErrStr(peer.String())) + } + if err != nil { + return nil, err + } + podPeer := &k8s.PodPeer{Pod: podObj, NamespaceObject: podNamespace} + return podPeer, nil +} + +func (pe *PolicyEngine) getPeerNamespaceObject(namespaceName, peerStr string) (*k8s.Namespace, error) { + podNamespace, ok := pe.namspacesMap[namespaceName] + if !ok { + return nil, errors.New(netpolerrors.MissingNamespaceErrStr(peerStr)) } - return nil, errors.New(netpolerrors.NotPeerErrStr(peer.String())) + return podNamespace, nil } // for connectivity considerations, when requesting allowed connections between 2 workload peers which are the same, @@ -91,28 +108,28 @@ func (pe *PolicyEngine) changePodPeerToAnotherPodObject(peer *k8s.PodPeer) { // expecting that srcPeer and dstPeer are in level of workloads (WorkloadPeer) func (pe *PolicyEngine) AllAllowedConnectionsBetweenWorkloadPeers(srcPeer, dstPeer Peer) (common.Connection, error) { if srcPeer.IsPeerIPType() && !dstPeer.IsPeerIPType() { - // assuming dstPeer is WorkloadPeer, should be converted to k8s.Peer - dstPodPeer, err := pe.convertWorkloadPeerToPodPeer(dstPeer) + // assuming dstPeer is WorkloadPeer/RepresentativePeer, should be converted to k8s.Peer + dstPodPeer, err := pe.convertPeerToPodPeer(dstPeer) if err != nil { return nil, err } return pe.allAllowedConnectionsBetweenPeers(srcPeer, dstPodPeer) } if dstPeer.IsPeerIPType() && !srcPeer.IsPeerIPType() { - // assuming srcPeer is WorkloadPeer, should be converted to k8s.Peer - srcPodPeer, err := pe.convertWorkloadPeerToPodPeer(srcPeer) + // assuming srcPeer is WorkloadPeer/RepresentativePeer, should be converted to k8s.Peer + srcPodPeer, err := pe.convertPeerToPodPeer(srcPeer) if err != nil { return nil, err } return pe.allAllowedConnectionsBetweenPeers(srcPodPeer, dstPeer) } if !dstPeer.IsPeerIPType() && !srcPeer.IsPeerIPType() { - // assuming srcPeer and dstPeer are WorkloadPeer, should be converted to k8s.Peer - srcPodPeer, err := pe.convertWorkloadPeerToPodPeer(srcPeer) + // assuming srcPeer and dstPeer are WorkloadPeer/RepresentativePeer, should be converted to k8s.Peer + srcPodPeer, err := pe.convertPeerToPodPeer(srcPeer) if err != nil { return nil, err } - dstPodPeer, err := pe.convertWorkloadPeerToPodPeer(dstPeer) + dstPodPeer, err := pe.convertPeerToPodPeer(dstPeer) if err != nil { return nil, err } diff --git a/pkg/netpol/eval/exposure.go b/pkg/netpol/eval/exposure.go index dceba874..370be292 100644 --- a/pkg/netpol/eval/exposure.go +++ b/pkg/netpol/eval/exposure.go @@ -54,6 +54,9 @@ func (pe *PolicyEngine) addPodsForUnmatchedRules(policyName string, policy *k8s. return err } +// any fake namespace added will start with following prefix for ns name and following pod name +const repNsNamePrefix = "representative-namespace-" + // gets a list of policy xgress rules consisted only from namespaceSelector. // adds new pod for each selector that does not have a matching namespace in the resources func (pe *PolicyEngine) addPodsForUnmatchedNamespaceSelectors(nsSelectors []*metav1.LabelSelector, policyName string) error { @@ -64,7 +67,7 @@ func (pe *PolicyEngine) addPodsForUnmatchedNamespaceSelectors(nsSelectors []*met } foundNs := pe.checkNamespaceSelectorsMatch(selectorMap) if !foundNs { - _, err = pe.AddPodByNameAndNamespace(common.PodInRepNs, common.NsNamePrefix+policyName+fmt.Sprint(i), selectorMap) + _, err = pe.AddPodByNameAndNamespace(k8s.RepresentativePodName, repNsNamePrefix+policyName+fmt.Sprint(i), selectorMap) if err != nil { return err } @@ -127,8 +130,20 @@ func (pe *PolicyEngine) GetPeerXgressEntireClusterConn(p Peer, isIngress bool) ( return peer.Pod.EgressExposureData.EntireClusterConnection, nil } -// TODO these functions will be changed in a later PR (when implementing RepresentativePeer) -func (pe *PolicyEngine) GetPeerNsLabels(p Peer) map[string]string { - peer := p.(*k8s.WorkloadPeer) - return peer.Pod.ExposureNsLabels +///////////////////////////////////////////// + +// IsRepresentativePeer returns whether the peer is representative peer (inferred from netpol rule) +func (pe *PolicyEngine) IsRepresentativePeer(peer Peer) bool { + _, ok := peer.(*k8s.RepresentativePeer) + return ok +} + +// GetPeerNsLabels returns namespace labels defining the given representative peer +// relevant only for RepresentativePeer +func (pe *PolicyEngine) GetPeerNsLabels(p Peer) (map[string]string, error) { + peer, ok := p.(*k8s.RepresentativePeer) + if !ok { // should not get here + return nil, errors.New(netpolerrors.NotRepresentativePeerErrStr(p.String())) + } + return peer.PotentialNamespaceLabels, nil } diff --git a/pkg/netpol/eval/internal/k8s/netpol.go b/pkg/netpol/eval/internal/k8s/netpol.go index 7516e5f3..17f6f5e5 100644 --- a/pkg/netpol/eval/internal/k8s/netpol.go +++ b/pkg/netpol/eval/internal/k8s/netpol.go @@ -131,10 +131,10 @@ func (np *NetworkPolicy) ruleConnections(rulePorts []netv1.NetworkPolicyPort, ds if err != nil { return res, err } - if dst == nil && portName != "" { + if (dst == nil || isRepresentativePod(dst)) && portName != "" { // adding namedPort to connectionSet in case of : - // - dst is nil - for general connections; - // - TODO: if dst is a fake pod (representative) + // - dst is nil - for general connections; + // - if dst is a representative pod (its namedPorts are unknown) ports.AddPort(intstr.FromString(portName)) } if !isEmptyPortRange(startPort, endPort) { @@ -146,6 +146,14 @@ func (np *NetworkPolicy) ruleConnections(rulePorts []netv1.NetworkPolicyPort, ds return res, nil } +// isRepresentativePod determines if the peer's source is representativePeer; i.e. its pod fake and has RepresentativePodName +func isRepresentativePod(peer Peer) bool { + if peer.GetPeerPod() == nil { + return false + } + return peer.GetPeerPod().FakePod && peer.GetPeerPod().Name == RepresentativePodName +} + // ruleConnsContain returns true if the given protocol and port are contained in connections allowed by rulePorts func (np *NetworkPolicy) ruleConnsContain(rulePorts []netv1.NetworkPolicyPort, protocol, port string, dst Peer) (bool, error) { if len(rulePorts) == 0 { diff --git a/pkg/netpol/eval/internal/k8s/peer.go b/pkg/netpol/eval/internal/k8s/peer.go index a37ea0ad..d2f83bd9 100644 --- a/pkg/netpol/eval/internal/k8s/peer.go +++ b/pkg/netpol/eval/internal/k8s/peer.go @@ -58,6 +58,22 @@ type WorkloadPeer struct { Pod *Pod } +// RepresentativePeer implements eval.Peer interface +// a representative peer is a peer inferred from a policy rule (selector) not a parsed pod/deployment object +// and is used to represent a potential pod/ns entity in the cluster (that does not exist on the input resources) +// but may have enabled connectivity to input resources (pods/deployments) based on input network policies. +type RepresentativePeer struct { + // Pod is a fake pod originated as following: + // - if inferred from a policy rule, which contains only non-empty namespaceSelector; the pod's namespace is a fake namespace + // with the labels from the selector (those labels also stored in PotentialNamespaceLabels) + // - if inferred from a policy rule, which contains only podSelector; the pod's namespace is same as the policy's namespace; + // and its labels are taken from the selector labels + // - if inferred from selector combining a namespaceSelector and a podSelector: the pod's labels will contain the podSelector labels + // and its namespace is a fake namespace with the namespaceSelector labels (those labels also stored in PotentialNamespaceLabels) + Pod *Pod + PotentialNamespaceLabels map[string]string +} + const podKind = "Pod" // ////////////////////////////////////////////////// @@ -82,11 +98,8 @@ func (p *WorkloadPeer) Kind() string { } func (p *WorkloadPeer) String() string { - if p.Pod.FakePod { - // TODO: revert this after implementing RepresantativePeer - if p.Pod.Name == common.IngressPodName { - return "{" + p.Pod.Name + "}" - } + if p.Pod.FakePod { // ingress-controller + return "{" + p.Pod.Name + "}" } return types.NamespacedName{Name: p.Name(), Namespace: p.Namespace()}.String() + "[" + p.Kind() + "]" } @@ -99,7 +112,37 @@ func (p *WorkloadPeer) IsPeerIPType() bool { return false } -//////////////////////////////////////////////////// +// ////////////////////////////////////////////////// + +const RepresentativePodName = "representative-pod" +const representativePodKind = "RepresentativePod" + +func (p *RepresentativePeer) Name() string { + return RepresentativePodName +} + +func (p *RepresentativePeer) Namespace() string { + return p.Pod.Namespace +} + +func (p *RepresentativePeer) Kind() string { + return representativePodKind +} + +func (p *RepresentativePeer) String() string { + // TODO: to be changed; to be determined in PR of exposure-analysis results' output representation + return types.NamespacedName{Name: p.Name(), Namespace: p.Namespace()}.String() +} + +func (p *RepresentativePeer) IP() string { + return "" +} + +func (p *RepresentativePeer) IsPeerIPType() bool { + return false +} + +// ////////////////////////////////////////////////// func (p *PodPeer) PeerType() PeerType { return PodType diff --git a/pkg/netpol/eval/internal/k8s/pod.go b/pkg/netpol/eval/internal/k8s/pod.go index d1b34991..8769dd60 100644 --- a/pkg/netpol/eval/internal/k8s/pod.go +++ b/pkg/netpol/eval/internal/k8s/pod.go @@ -66,9 +66,6 @@ type Pod struct { // - and the maximal connection-set for which the pod is exposed to all namespaces by network policies // on egress direction EgressExposureData PodExposureInfo - - // TODO in next PR: define new RepresentativePeer and move following fields to be part of it - ExposureNsLabels map[string]string } // Owner encapsulates pod owner workload info @@ -99,7 +96,6 @@ func PodFromCoreObject(p *corev1.Pod) (*Pod, error) { FakePod: false, IngressExposureData: initiatePodExposure(), EgressExposureData: initiatePodExposure(), - ExposureNsLabels: map[string]string{}, } copy(pr.IPs, p.Status.PodIPs) diff --git a/pkg/netpol/eval/resources.go b/pkg/netpol/eval/resources.go index e990784d..b90ecab5 100644 --- a/pkg/netpol/eval/resources.go +++ b/pkg/netpol/eval/resources.go @@ -28,8 +28,9 @@ type ( netpolsMap map[string]map[string]*k8s.NetworkPolicy // map from namespace to map from netpol name to its object podOwnersToRepresentativePodMap map[string]map[string]*k8s.Pod // map from namespace to map from pods' ownerReference name // to its representative pod object - cache *evalCache - exposureAnalysisFlag bool + cache *evalCache + exposureAnalysisFlag bool + representativePeersList []*k8s.RepresentativePeer // list of representative peer objects, used only with exposure analysis } // NotificationTarget defines an interface for updating the state needed for network policy @@ -223,6 +224,9 @@ func (pe *PolicyEngine) ClearResources() { pe.podsMap = make(map[string]*k8s.Pod) pe.netpolsMap = make(map[string]map[string]*k8s.NetworkPolicy) pe.podOwnersToRepresentativePodMap = make(map[string]map[string]*k8s.Pod) + if pe.exposureAnalysisFlag { + pe.representativePeersList = make([]*k8s.RepresentativePeer, 0) + } pe.cache = newEvalCache() } @@ -422,6 +426,7 @@ func (pe *PolicyEngine) GetPodsMap() map[string]*k8s.Pod { return pe.podsMap } +// HasPodPeers returns if there are pods from parsed pod objects in the policy-engine func (pe *PolicyEngine) HasPodPeers() bool { return len(pe.podsMap) > 0 } @@ -466,6 +471,15 @@ func (pe *PolicyEngine) GetPeersList() ([]Peer, error) { return res, nil } +// GetRepresentativePeersList returns a slice of representative peers +func (pe *PolicyEngine) GetRepresentativePeersList() []Peer { + res := make([]Peer, len(pe.representativePeersList)) + for i, p := range pe.representativePeersList { + res[i] = p + } + return res +} + // getDisjointIPBlocks returns a slice of disjoint ip-blocks from all netpols resources func (pe *PolicyEngine) getDisjointIPBlocks() ([]*common.IPBlock, error) { var ipbList []*common.IPBlock @@ -484,6 +498,7 @@ func (pe *PolicyEngine) getDisjointIPBlocks() ([]*common.IPBlock, error) { } // GetSelectedPeers returns list of workload peers in the given namespace which match the given labels selector +// used only for ingress-analyzer : currently not supported with exposure-analysis func (pe *PolicyEngine) GetSelectedPeers(selectors labels.Selector, namespace string) ([]Peer, error) { res := make([]Peer, 0) peers, err := pe.createPodOwnersMap() @@ -514,8 +529,9 @@ func (pe *PolicyEngine) ConvertPeerNamedPort(namedPort string, peer Peer) (int32 } } -// AddPodByNameAndNamespace adds a new fake pod to the pe.podsMap, -// used for adding ingress-controller pods and pods for exposure-analysis use-case +// AddPodByNameAndNamespace adds a new fake pod to: +// the pe.podsMap in case of fake ingress-controller pods +// or the pe.representativePeersList in case of exposure-analysis peers func (pe *PolicyEngine) AddPodByNameAndNamespace(name, ns string, nsLabels map[string]string) (Peer, error) { podStr := types.NamespacedName{Namespace: ns, Name: name}.String() newPod := &k8s.Pod{ @@ -526,10 +542,12 @@ func (pe *PolicyEngine) AddPodByNameAndNamespace(name, ns string, nsLabels map[s if err := pe.resolveSingleMissingNamespace(ns, nsLabels); err != nil { return nil, err } - if pe.exposureAnalysisFlag { - // save the labels in the pod's data - newPod.ExposureNsLabels = nsLabels + if pe.exposureAnalysisFlag && newPod.Name == k8s.RepresentativePodName { // if exposure-analysis and this is not a fake ingress-controller + newRepresentativePeer := &k8s.RepresentativePeer{Pod: newPod, PotentialNamespaceLabels: nsLabels} + pe.representativePeersList = append(pe.representativePeersList, newRepresentativePeer) + return newRepresentativePeer, nil } + // ingress-controller will be treated as a real pod, may be added to podsMap pe.podsMap[podStr] = newPod return &k8s.WorkloadPeer{Pod: newPod}, nil } diff --git a/pkg/netpol/internal/common/exposure_resources_names.go b/pkg/netpol/internal/common/exposure_resources_names.go deleted file mode 100644 index 4f2013b0..00000000 --- a/pkg/netpol/internal/common/exposure_resources_names.go +++ /dev/null @@ -1,7 +0,0 @@ -package common - -const ( - // any fake namespace added will start with following prefix for ns name and following pod name - NsNamePrefix = "representative-namespace-" - PodInRepNs = "representative-pod" -)