Skip to content

Commit

Permalink
remove external exposure from the exposure-analysis structs (#490)
Browse files Browse the repository at this point in the history
  • Loading branch information
shireenf-ibm authored Jan 27, 2025
1 parent 1d93856 commit 1f69f44
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 107 deletions.
34 changes: 15 additions & 19 deletions pkg/netpol/eval/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -486,10 +486,10 @@ func (pe *PolicyEngine) getAllAllowedXgressConnsFromNetpols(src, dst k8s.Peer,
// (either allowed by rule or implicitly denied because of the rule's absence)
exposureConns.isCaptured = true
// update the cluster wide exposure result from the relevant netpol's data
if isIngress && !policy.IngressPolicyExposure.ClusterWideExposure.IsEmpty() {
exposureConns.layerConns.AllowedConns.Union(policy.IngressPolicyExposure.ClusterWideExposure.AllowedConns)
} else if !isIngress && !policy.EgressPolicyExposure.ClusterWideExposure.IsEmpty() {
exposureConns.layerConns.AllowedConns.Union(policy.EgressPolicyExposure.ClusterWideExposure.AllowedConns)
if isIngress && !policy.IngressPolicyClusterWideExposure.IsEmpty() {
exposureConns.layerConns.AllowedConns.Union(policy.IngressPolicyClusterWideExposure.AllowedConns)
} else if !isIngress && !policy.EgressPolicyClusterWideExposure.IsEmpty() {
exposureConns.layerConns.AllowedConns.Union(policy.EgressPolicyClusterWideExposure.AllowedConns)
}
}
allowedConns.Union(policyAllowedConnectionsPerDirection)
Expand All @@ -507,20 +507,16 @@ func (pe *PolicyEngine) determineAllowedConnsPerDirection(policy *k8s.NetworkPol
if isIngress {
// get ingress allowed conns between src and dst
switch {
case policy.IngressPolicyExposure.ExternalExposure.AllowedConns.AllowAll:
return policy.IngressPolicyExposure.ExternalExposure.AllowedConns, nil
case policy.IngressPolicyExposure.ClusterWideExposure.AllowedConns.AllowAll && src.PeerType() == k8s.PodType:
return policy.IngressPolicyExposure.ClusterWideExposure.AllowedConns, nil
case policy.IngressPolicyClusterWideExposure.AllowedConns.AllowAll && src.PeerType() == k8s.PodType:
return policy.IngressPolicyClusterWideExposure.AllowedConns, nil
default:
return policy.GetIngressAllowedConns(src, dst)
}
}
// else get egress allowed conns between src and dst
switch {
case policy.EgressPolicyExposure.ExternalExposure.AllowedConns.AllowAll:
return policy.EgressPolicyExposure.ExternalExposure.AllowedConns, nil
case policy.EgressPolicyExposure.ClusterWideExposure.AllowedConns.AllowAll && dst.PeerType() == k8s.PodType:
return policy.EgressPolicyExposure.ClusterWideExposure.AllowedConns, nil
case policy.EgressPolicyClusterWideExposure.AllowedConns.AllowAll && dst.PeerType() == k8s.PodType:
return policy.EgressPolicyClusterWideExposure.AllowedConns, nil
default:
return policy.GetEgressAllowedConns(dst)
}
Expand Down Expand Up @@ -563,7 +559,7 @@ func (pe *PolicyEngine) getAllAllowedXgressConnectionsFromANPs(src, dst k8s.Peer
// if it is captured by current policy
if pe.exposureAnalysisFlag {
src.GetPeerPod().UpdatePodXgressProtectedFlag(false) // mark the pod is protected
updateClusterWideExposureResultFromANP(exposureConns, anp.EgressPolicyExposure)
updateClusterWideExposureResultFromANP(exposureConns, anp.EgressPolicyClusterWideExposure)
}
}
} else { // ingress
Expand All @@ -581,7 +577,7 @@ func (pe *PolicyEngine) getAllAllowedXgressConnectionsFromANPs(src, dst k8s.Peer
// if it is captured by current policy
if pe.exposureAnalysisFlag {
dst.GetPeerPod().UpdatePodXgressProtectedFlag(true)
updateClusterWideExposureResultFromANP(exposureConns, anp.IngressPolicyExposure)
updateClusterWideExposureResultFromANP(exposureConns, anp.IngressPolicyClusterWideExposure)
}
}
}
Expand All @@ -601,10 +597,10 @@ func (pe *PolicyEngine) getAllAllowedXgressConnectionsFromANPs(src, dst k8s.Peer

// updateClusterWideExposureResultFromANP updates the cluster-wide exposure result of a pod from given (B)ANP exposure info
func updateClusterWideExposureResultFromANP(exposureResult *policiesLayerXgressConns,
xgressPolicyExposure k8s.PolicyExposureWithoutSelectors) {
if !xgressPolicyExposure.ClusterWideExposure.IsEmpty() {
xgressPolicyClusterWideExposure *k8s.PolicyConnections) {
if !xgressPolicyClusterWideExposure.IsEmpty() {
exposureResult.isCaptured = true
exposureResult.layerConns.CollectANPConns(xgressPolicyExposure.ClusterWideExposure)
exposureResult.layerConns.CollectANPConns(xgressPolicyClusterWideExposure)
}
}

Expand Down Expand Up @@ -645,7 +641,7 @@ func (pe *PolicyEngine) getXgressDefaultConns(src, dst k8s.Peer, isIngress bool)
// if exposure-analysis is on, update also the exposure of the dst from all namespaces on ingress
// if it is captured by current policy
dst.GetPeerPod().UpdatePodXgressProtectedFlag(true)
updateClusterWideExposureResultFromANP(exposureConns, pe.baselineAdminNetpol.IngressPolicyExposure)
updateClusterWideExposureResultFromANP(exposureConns, pe.baselineAdminNetpol.IngressPolicyClusterWideExposure)
}
}
} else { // egress (!isIngress)
Expand All @@ -663,7 +659,7 @@ func (pe *PolicyEngine) getXgressDefaultConns(src, dst k8s.Peer, isIngress bool)
// if it is captured by current policy
if pe.exposureAnalysisFlag {
src.GetPeerPod().UpdatePodXgressProtectedFlag(false)
updateClusterWideExposureResultFromANP(exposureConns, pe.baselineAdminNetpol.EgressPolicyExposure)
updateClusterWideExposureResultFromANP(exposureConns, pe.baselineAdminNetpol.EgressPolicyClusterWideExposure)
}
}
}
Expand Down
45 changes: 19 additions & 26 deletions pkg/netpol/eval/internal/k8s/adminnetpol.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,21 +32,14 @@ type AdminNetworkPolicy struct {
*apisv1a.AdminNetworkPolicy // embedding k8s admin-network-policy object
warnings common.Warnings // set of warnings which are raised by the anp
// following data stored in preprocessing when exposure-analysis is on;

// 1. Note that : since (Baseline)AdminNetworkPolicy's rules are read as-is and the peers must be explicitly declared in a rulePeer,
// only the `ClusterWideExposure` (when a rule selects all the namespaces) field of
// IngressPolicyExposure and EgressPolicyExposure attributes is relevant for AdminNetworkPolicy (and BaselineAdminNetworkPolicy).
// example : while an Ingress NetworkPolicy with empty Ingress section - means that the connection is
// allowed to whole world (external and internal);
// it is not legal to have an empty (no rules) Ingress/Egress section in an (Baseline)AdminNetworkPolicy (there is no strict definition for
// allowing connection to whole world in ANPs)

// IngressPolicyExposure contains:
// - the maximal connection-set which the admin-policy's rules allow/deny/pass from all namespaces in the cluster on ingress direction
IngressPolicyExposure PolicyExposureWithoutSelectors
// EgressPolicyExposure contains:
// - the maximal connection-set which the admin-policy's rules allow/deny/pass to all namespaces in the cluster on egress direction
EgressPolicyExposure PolicyExposureWithoutSelectors
// IngressPolicyClusterWideExposure contains:
// - the maximal connection-sets which the admin-policy's rules allow/deny/pass from all namespaces in the cluster on ingress direction
// those conns are inferred rules with empty selectors
IngressPolicyClusterWideExposure *PolicyConnections
// EgressPolicyClusterWideExposure contains:
// - the maximal connection-sets which the admin-policy's rules allow/deny/pass to all namespaces in the cluster on egress direction
// those conns are inferred rules with empty selectors
EgressPolicyClusterWideExposure *PolicyConnections
}

// Selects returns true if the admin network policy's Spec.Subject selects the peer and if the required direction is in the policy spec
Expand Down Expand Up @@ -712,7 +705,7 @@ func (anp *AdminNetworkPolicy) scanIngressRules() ([]SingleRuleSelectors, error)
rulePeers := rule.From
rulePorts := rule.Ports
selectors, err := getIngressSelectorsAndUpdateExposureClusterWideConns(rulePeers, rulePorts, string(rule.Action),
&anp.IngressPolicyExposure)
anp.IngressPolicyClusterWideExposure)
if err != nil {
return nil, err
}
Expand All @@ -728,7 +721,7 @@ func (anp *AdminNetworkPolicy) scanEgressRules() ([]SingleRuleSelectors, error)
rulePeers := rule.To
rulePorts := rule.Ports
selectors, err := getEgressSelectorsAndUpdateExposureClusterWideConns(rulePeers, rulePorts, string(rule.Action),
&anp.EgressPolicyExposure)
anp.EgressPolicyClusterWideExposure)
if err != nil {
return nil, err
}
Expand All @@ -750,7 +743,7 @@ func (anp *AdminNetworkPolicy) scanEgressRules() ([]SingleRuleSelectors, error)
// this func assumes rules are legal (rules correctness check occurs later)
func getEgressSelectorsAndUpdateExposureClusterWideConns(rules []apisv1a.AdminNetworkPolicyEgressPeer,
rulePorts *[]apisv1a.AdminNetworkPolicyPort, action string,
egressPolicyExposure *PolicyExposureWithoutSelectors) (rulesSelectors []SingleRuleSelectors, err error) {
egressPolicyClusterWideExposure *PolicyConnections) (rulesSelectors []SingleRuleSelectors, err error) {
if len(rules) == 0 { // not valid case
return nil, nil
}
Expand All @@ -759,7 +752,7 @@ func getEgressSelectorsAndUpdateExposureClusterWideConns(rules []apisv1a.AdminNe
continue // not relevant to check wide-cluster exposure or get selectors from those fields
} // else rules[i].Namespaces != nil || rules[i].Pods != nil
ruleSel, err := getSelectorsFromNamespacesOrPodsFieldsAndUpdateExposureClusterWideConns(rules[i].Namespaces, rules[i].Pods,
egressPolicyExposure, rulePorts, action)
egressPolicyClusterWideExposure, rulePorts, action)
if err != nil {
return nil, err
}
Expand All @@ -778,14 +771,14 @@ func getEgressSelectorsAndUpdateExposureClusterWideConns(rules []apisv1a.AdminNe
// this func assumes rules are legal (rules correctness check occurs later)
func getIngressSelectorsAndUpdateExposureClusterWideConns(rules []apisv1a.AdminNetworkPolicyIngressPeer,
rulePorts *[]apisv1a.AdminNetworkPolicyPort, action string,
ingressPolicyExposure *PolicyExposureWithoutSelectors) (rulesSelectors []SingleRuleSelectors, err error) {
ingressPolicyClusterWideExposure *PolicyConnections) (rulesSelectors []SingleRuleSelectors, err error) {
if len(rules) == 0 {
return nil, nil
}
for i := range rules {
var ruleSel SingleRuleSelectors
ruleSel, err := getSelectorsFromNamespacesOrPodsFieldsAndUpdateExposureClusterWideConns(rules[i].Namespaces, rules[i].Pods,
ingressPolicyExposure, rulePorts, action)
ingressPolicyClusterWideExposure, rulePorts, action)
if err != nil {
return nil, err
}
Expand All @@ -801,12 +794,12 @@ func getIngressSelectorsAndUpdateExposureClusterWideConns(rules []apisv1a.AdminN
// checks if the rule's field selects entire-cluster, then updates the policy xgress cluster-wide exposure;
// otherwise, returns the rule's field selectors to be returned later for generating representative-peer
func getSelectorsFromNamespacesOrPodsFieldsAndUpdateExposureClusterWideConns(namespaces *metav1.LabelSelector,
pods *apisv1a.NamespacedPod, xgressPolicyExposure *PolicyExposureWithoutSelectors,
pods *apisv1a.NamespacedPod, xgressPolicyClusterWideExposure *PolicyConnections,
rulePorts *[]apisv1a.AdminNetworkPolicyPort, action string) (ruleSel SingleRuleSelectors, err error) {
if namespaces != nil {
if namespaces.Size() == 0 {
// empty Namespaces field = all cluster
err = updateAdminNetworkPolicyExposureClusterWideConns(rulePorts, xgressPolicyExposure, action)
err = updateAdminNetworkPolicyExposureClusterWideConns(rulePorts, xgressPolicyClusterWideExposure, action)
return SingleRuleSelectors{}, err
}
// else, the namespaces field specifies namespaces by labels
Expand All @@ -818,7 +811,7 @@ func getSelectorsFromNamespacesOrPodsFieldsAndUpdateExposureClusterWideConns(nam
return SingleRuleSelectors{}, nil
}
if doesRuleSelectAllNamespaces(&pods.NamespaceSelector, &pods.PodSelector) {
err = updateAdminNetworkPolicyExposureClusterWideConns(rulePorts, xgressPolicyExposure, action)
err = updateAdminNetworkPolicyExposureClusterWideConns(rulePorts, xgressPolicyClusterWideExposure, action)
return SingleRuleSelectors{}, err
}
// else selectors' combination specifies workloads by labels (at least one label is not nil and not empty)
Expand All @@ -829,11 +822,11 @@ func getSelectorsFromNamespacesOrPodsFieldsAndUpdateExposureClusterWideConns(nam

// updateAdminNetworkPolicyExposureClusterWideConns updates the cluster-wide exposure connections of the (b)anp
func updateAdminNetworkPolicyExposureClusterWideConns(rulePorts *[]apisv1a.AdminNetworkPolicyPort,
xgressPolicyExposure *PolicyExposureWithoutSelectors, ruleAction string) error {
xgressPolicyClusterWideExposure *PolicyConnections, ruleAction string) error {
ruleConns, err := ruleConnections(rulePorts, nil)
if err != nil {
return err
}
return xgressPolicyExposure.ClusterWideExposure.UpdateWithRuleConns(ruleConns, ruleAction, false)
return xgressPolicyClusterWideExposure.UpdateWithRuleConns(ruleConns, ruleAction, false)
// note that : the last parameter sent to UpdateWithRuleConns is false, since the pre-process func assumes rules are legal
}
18 changes: 10 additions & 8 deletions pkg/netpol/eval/internal/k8s/baseline_admin_netpol.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,14 @@ type BaselineAdminNetworkPolicy struct {
*apisv1a.BaselineAdminNetworkPolicy // embedding k8s BaselineAdminNetworkPolicy object
warnings common.Warnings // set of warnings which are raised by the banp
// following data stored in preprocessing when exposure-analysis is on;
// IngressPolicyExposure contains:
// - the maximal connection-set which the baseline-admin-policy's rules allow/deny from all namespaces in the cluster on ingress direction
IngressPolicyExposure PolicyExposureWithoutSelectors
// EgressPolicyExposure contains:
// - the maximal connection-set which the baseline-admin-policy's rules allow/deny to all namespaces in the cluster on egress direction
EgressPolicyExposure PolicyExposureWithoutSelectors
// IngressPolicyClusterWideExposure contains:
// - the maximal connection-sets which the baseline-admin-policy's rules allow/deny from all namespaces in the cluster on ingress direction
// those conns are inferred rules with empty selectors
IngressPolicyClusterWideExposure *PolicyConnections
// EgressPolicyClusterWideExposure contains:
// - the maximal connection-sets which the baseline-admin-policy's rules allow/deny to all namespaces in the cluster on egress direction
// those conns are inferred rules with empty selectors
EgressPolicyClusterWideExposure *PolicyConnections
}

// Selects returns true if the baseline admin network policy's Spec.Subject selects the peer and if
Expand Down Expand Up @@ -220,7 +222,7 @@ func (banp *BaselineAdminNetworkPolicy) scanIngressRules() ([]SingleRuleSelector
rulePeers := rule.From
rulePorts := rule.Ports
selectors, err := getIngressSelectorsAndUpdateExposureClusterWideConns(rulePeers, rulePorts, string(rule.Action),
&banp.IngressPolicyExposure)
banp.IngressPolicyClusterWideExposure)
if err != nil {
return nil, err
}
Expand All @@ -237,7 +239,7 @@ func (banp *BaselineAdminNetworkPolicy) scanEgressRules() ([]SingleRuleSelectors
rulePeers := rule.To
rulePorts := rule.Ports
selectors, err := getEgressSelectorsAndUpdateExposureClusterWideConns(rulePeers, rulePorts, string(rule.Action),
&banp.EgressPolicyExposure)
banp.EgressPolicyClusterWideExposure)
if err != nil {
return nil, err
}
Expand Down
Loading

0 comments on commit 1f69f44

Please sign in to comment.