Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pre proccessing policy for general conns #306

Merged
merged 7 commits into from
Feb 12, 2024

Conversation

shireenf-ibm
Copy link
Contributor

issue : #236
sub-task:

    • optimize policy pre-processing : store data on policy's general conns (to whole world/ entire cluster)more info

@shireenf-ibm
Copy link
Contributor Author

Some notes:

1. main changes:

- step1 : while upserting a new network-policy, scan its ingress and egress rules and store :

- all destinations (whole world) connections
- entire cluster connections

notes on step1:

  • can not do the pre-process only for exposure analysis; since policy-engine's exposure analysis flag is updated only after upserting the objects (the pe.exposureAnalysisFlag is updated after pe.NewPolicyEngineWithObjects which calls UpsertObject funcs)

  • currently, I stored both entire world and entire cluster conns (entire cluster contains also entire world) although I use only entire cluster;

    in the mean while kept the entire-world connection cause we may use it in next optimizations; if we don't will eliminate it.

  • a rule may contain namedPort; in pre-process we can not convert the namedPort into portNum (we don't have all peers yet, neither know what peers are selected); so :

    1. on pre-process; I store the new connection with the namedPort (however; here I found a bug in PortSet(detailed below))
    2. while computing allowed connections between peers (scanning the policy rules for finding selected peers;), each time a namedPort was converted, saved it in the policy struct; (a policy object has a map from protocol to map from namedPorts to port numbers)

- step2: while scaning the policies selecting a pod for allowed connections computations; updated the pod's general exposure data from the policy's stored data.

(when updating the pod's data, checked and replaced namedPort in the poliy's entire cluster conns using the map; (worked with local test with namedPort))

2. notes on PortSet :

  • although PortSet has a
NamedPorts         map[string]bool
ExcludedNamedPorts map[string]bool

they were never used before and never initialized;
so while running a test with a namedPort I got : panic: assignment to entry in nil map error;
I updated the MakePortSet with initialized empty maps; but still got the error;
since almost always a new PortSet is initialized by PortSet{};
so currently in the PortSet funcs that are used for storing the namedPort; I check and initialize the maps if are nil

@shireenf-ibm
Copy link
Contributor Author

** TODO:** (for next commit?)
if new data of the Policy is accepted :

  • we can benefit from it for computing allowed conns;
    I suggest that the netpol func ruleSelectsPeer checks only if there is a specified rule selecting the specific peer; (specified podSelector/ NamespaceSelector ...)
    and then for-example :
    the allowed conns between peers is the entireCluster.Union(this-rules-conn)
    for IPblock the policy's entireWorldConn.Union(specific IPBlock rule conn)

@shireenf-ibm shireenf-ibm requested a review from adisos February 5, 2024 15:53
@shireenf-ibm shireenf-ibm marked this pull request as draft February 5, 2024 15:53
@shireenf-ibm shireenf-ibm mentioned this pull request Feb 5, 2024
@adisos
Copy link
Collaborator

adisos commented Feb 6, 2024

some questions/comments:

can not do the pre-process only for exposure analysis; since policy-engine's exposure analysis flag is updated only after upserting the objects

I think we can find solutions for this, such as adding more api funcs to generate policy engine as desired.

while computing allowed connections between peers (scanning the policy rules for finding selected peers;), each time a namedPort was converted, saved it in the policy struct

why does it need to be stored in the policy?

what if the connection from actual pod to a "fake" (representative) pod depends on a named port? how will this be handled by exposure analysis?

I suggest that the netpol func ruleSelectsPeer checks only ...

not sure I understand the entire sentence, though I think ruleSelectsPeer could avoid iterating all rules in case we already know from pre-processing (when available, from exposure analysis activation) that at least one of the rules is matching all namespaces or any pod/ip-block .. (for this case we do need the "all destinations (whole world) connections").

// - the maximal connection-set which the policy's rules allow to all namespaces in the cluster on egress direction
EgressGeneralConns PolicyGeneralRulesConns

namedPortsToPortNum map[v1.Protocol]map[string]int32 // internal map; map from protocol to map from namedPort which
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the matching of named port to its number is per pod, so why is it stored here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed the handling of named-ports

adding some examples - locally tested :

  1. an ingress policy; exposes the workload on ingress to entire-cluster on named ports; since the dst is the workload itself - converts the ports to numbers

ing_spec_result

  1. an egress policy - which exposes the workload to entire cluster ; on named ports : we will see these potential named ports on the result.

egress_res

  1. an example combining named ports and port numbers:

example_spec_res

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, the example seem to make sense

@shireenf-ibm
Copy link
Contributor Author

shireenf-ibm commented Feb 6, 2024

some questions/comments:

can not do the pre-process only for exposure analysis; since policy-engine's exposure analysis flag is updated only after upserting the objects

I think we can find solutions for this, such as adding more api funcs to generate policy engine as desired.

True, so do you suggest performing this pre-process only for exposure analysis ?

while computing allowed connections between peers (scanning the policy rules for finding selected peers;), each time a namedPort was converted, saved it in the policy struct

why does it need to be stored in the policy?

True, actually I was very unsure when and how to store these;
additionally, if we want to benefit from the general conns in ruleSelectsPeer ; we might not get the converted named port for the general rules.

I think also that I don't fully understand when a named port should be converted..

but if it is a "src" (egress conn); should we convert? or keep it as it? (a named port)
(I would like to discuss this with you)

what if the connection from actual pod to a "fake" (representative) pod depends on a named port? how will this be handled by exposure analysis?

in this PR; focused on "general" (entire cluster) connections;
my plan for optimizing PR: is that if the "dst" is representative and there is a conn with named port is to store the named port in the connection data (portSet.NamedPorts)
I can also save potential namedPorts in the RepresentativePeer struct so we can use it in the output if we want

I suggest that the netpol func ruleSelectsPeer checks only ...

not sure I understand the entire sentence, though I think ruleSelectsPeer could avoid iterating all rules in case we already know from pre-processing (when available, from exposure analysis activation) that at least one of the rules is matching all namespaces or any pod/ip-block .. (for this case we do need the "all destinations (whole world) connections").

yes that is what I meant

@shireenf-ibm
Copy link
Contributor Author

shireenf-ibm commented Feb 8, 2024

next tasks to be done are:

  • adding new api func to the policy-engine; so all pre-process (and storing general conns for pods) will be computed only for exposure-analysis.
  • in case of exposure-analysis; updating some computation that can benefit from the stored data of the policy

since this PR is already labeled L ; I think should commit these to a new PR ?
(sub-task : * - [ ] adding new api func for policy-engine for running exposure-analysis individually)

@adisos
Copy link
Collaborator

adisos commented Feb 8, 2024

next tasks to be done are:

* adding new api func to the policy-engine; so all pre-process (and storing general conns for pods) will be computed only for exposure-analysis.

* in case of exposure-analysis; updating some computation that can benefit from the stored data of the policy

since this PR is already labeled L ; I think should commit these to a new PR ? (sub-task : * - [ ] adding new api func for policy-engine for running exposure-analysis individually)

ok, let's have these in a new PR

pkg/netpol/internal/common/portset.go Outdated Show resolved Hide resolved
pkg/netpol/internal/common/portset.go Outdated Show resolved Hide resolved
pkg/netpol/eval/resources.go Outdated Show resolved Hide resolved
pkg/netpol/eval/internal/k8s/pod.go Outdated Show resolved Hide resolved
pkg/netpol/eval/resources.go Outdated Show resolved Hide resolved
pkg/netpol/eval/internal/k8s/netpol.go Outdated Show resolved Hide resolved
pkg/netpol/eval/internal/k8s/netpol.go Show resolved Hide resolved
@shireenf-ibm shireenf-ibm requested a review from adisos February 12, 2024 08:18
@shireenf-ibm shireenf-ibm marked this pull request as ready for review February 12, 2024 09:32
@shireenf-ibm shireenf-ibm merged commit db2c484 into new_exposure_analysis_first_branch Feb 12, 2024
2 checks passed
@shireenf-ibm shireenf-ibm deleted the policy_pre_process branch February 12, 2024 09:32
shireenf-ibm added a commit that referenced this pull request Aug 8, 2024
* exposure-analysis flag

* initial support of exposure from only namespaceSelectors

* lint gofmt

* wip - defining an interface for exposure-analysis results (#295)

* wip - define an interface for the new returned value (new API)

* Update pkg/netpol/connlist/exposed_pods.go

Co-authored-by: Adi Sosnovich <[email protected]>

* wip- some updates to the interfaces (only)

* Update pkg/netpol/connlist/exposed_pods.go

Co-authored-by: Adi Sosnovich <[email protected]>

* interface doc update

* fixes

* Update pkg/netpol/connlist/exposed_peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* connlist implementing exposure analysis (#296)

* connlist implementing exposure analysis

* Update pkg/netpol/connlist/connlist.go

Co-authored-by: Adi Sosnovich <[email protected]>

* fix rep. pod name

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposed_peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposed_peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis.go

Co-authored-by: Adi Sosnovich <[email protected]>

* add func that updates the protected flag of a pod

* return error values

* avoid fields dups among types

* update func doc

* getConnectionsBetweenPeers update doc + returns the exposureMap

* move connection interface, avoid code dup, and compare conns using ConnectionSet

* make the func an exposureMap func

* fixing issue of same string in podsOwnerMap

* Update pkg/netpol/connlist/exposure_analysis.go

Co-authored-by: Adi Sosnovich <[email protected]>

* renaming Connection interface + move PortRange

* struct embedding

* using connectionSet internally + move the refinement to one iter at the end

* Update pkg/netpol/connection/connection.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis.go

Co-authored-by: Adi Sosnovich <[email protected]>

* rename AllConnections

* verify conversion

* storing the maximum entire cluster connection

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* Revert api changes (#298)

* revert Connection, diff AllowedConnectivity, PortRange , ConnectionSet

* revert connlist API changes

* revert eval API changes

* Update pkg/netpol/connlist/connlist.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/connlist.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* renaming funcs

* exposing common.Connection as connlist.AllowedSet

* revert exposing common.Connection as connlist.AllowedSet

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* Exposure analysis unit tests (#299)

* unit tests for the functionality of connlist/exposure_analysis.go

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* adding getallTCPconnections

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* Entire cluster exposure opt (#304)

* optimizing entire cluster exposure

* optimizing performance - compute entire cluster exposure only once

* Update pkg/netpol/eval/internal/k8s/pod.go

Co-authored-by: Adi Sosnovich <[email protected]>

* multiple fixes

* Update pkg/netpol/eval/internal/k8s/pod.go

Co-authored-by: Adi Sosnovich <[email protected]>

* using empty connswt instead of nil

* add pod exposure data struct

* exporting podExposureInfo

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* pre proccessing policy for general conns (#306)

* first commit: pre proccessing policy for general conns

* func doc

* fixing to PortSet; instead of PortSet{}, call MakePortSet(false) to ensure initializing empty maps for named ports

* fixing handling connections with namedPort

* fixing lint issued by github - not relevant to PR

* tiny fix

* fixes

* Policy engine with new api func for exposure analysis  (#307)

* task1 add new api func to policy-engine; so pre-process runs only for exposure-analysis

* task2 on exposure analysis benefit from the stored data

* eliminate isRuleGeneral; skip general rules in ruleSelectsPeer

* missing func doc

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* todo comment

* revert initiating conns between two peers

* avoid iterating policy if its general conns are all conns

* todo comment

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* adding representativePeer struct (#309)

* adding representativePeer struct

* Update pkg/netpol/eval/internal/k8s/peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* gofmt

* connlist if-else fix

* fixes to exposure_map.go

* fixing connlist includePairOfWorkloads

* fix GetPeerList() - separate GetRepresentativePeersList

* comment how Pod of representative peer is originated

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* Optimize representative peers generation  (#314)

* add representative peers for all non-empty rules while policies upsert

* refine pods that has a match in the resources - first commit

* handling returned err from convertPeerToPodPeer

* handle case of namespaceSelector containing name key

* generate unizue rep peers and refine while upsering objects

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* fixes

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* go fmt

* lint fix

* exposure analysis test (#316)

* exposure analysis test

* exposure data comparison and new test

* using ca calls to compute exposed peers

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/connlist/exposure_analysis_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* lint fix

* flattening tests dir

* exposure map fixes

* 3 values of protected data

* splitting exposure map into two maps

* fixes

* required changes

* code fixes

* typo fix

* a new test for increasing coverage

* new test

* comment update

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* delete unused file

* textual output with exposure analysis (#331)

* textual output with exposure analysis

* tiny code enhancement

* readme update

* output change + code modify

* fixes

* dot output with exposure results (#333)

* dot output with exposure results

* tiny fix

* new tests

* fixing golangci-lint 1.58.0 errors

* exposure analysis with pod selectors (#343)

* code changes + new tests with pod selectors

* fixes and new test

* running onlineboutique_workloads with exposure

* running k8s_ingress_test_new with exposure

* linter fix - headers

* exposure analysis with focus-workload (#349)

* exposure analysis with focus-workload

* focus-workload fixes

* textual output enhancement (adding [] to strings with multiple words)

* fix

* enhancing dot view (#353)

* don't remove representative peers in any-namespace (#352)

* always keep representative peers which match all-namespaces

* update test output after merge

* examples with rules exposing pod to an existing ns

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* don't refine rep. peers matching any pod in a namespace + changing some tests to keep initial purpose+updating results of existing tests

* adding same test with nil podSelector instead of empty one

* adding test with inaccurate output

* fixing comment syntax

* Update pkg/netpol/connlist/connlist_test.go

Co-authored-by: Adi Sosnovich <[email protected]>

* gofmt

* updating comments in yaml

* tiny fix

---------

Co-authored-by: Adi Sosnovich <[email protected]>

* supporting csv, md and json formats (#360)

* supporting csv, md and json formats

* fixing after merge with base branch

* consider real exposure flag

* csv, md, json are consistent with txt - two sections

* dot graphs with exposure edges dashed and with different colors

* merging with master branch

* empty_commit

* handling selectors with matchexpressions (fixed) (#377)

* support match expression operators for generating and selecting representative peers + first examples

* more tests

* more tests

* updating code with label selectors

* merge fixes

* duplicated tests with matching pods

* fixing code + tests with multiple policies

* update comments in exposure.go

* renaming function and updating comments and doc of representative_selectors.go

* move `RepresentativeNsLabelSelector` field from namespace.go to pod.go

* 1. reverting changes to AddPodByNameAndNamespace and resolveSingleMissingNamespace (to original version from main branch)
2. creating a new func for adding representative pods to the policy-engine, without representative namespaces. a representative pod which should not be in a real namespace, will have no namespace

* avoid duplicating code of generating the default namespace name map; and some updates to netpol.go

* eliminate representativePeer.PotentialNamespaceLabelSelector as it duplicates Pod.RepresentativeNsLabelSelector

* renaming the func in representative_selectors.go again

* a new test with handling a special case of equiv rules written in a different way

* unit test for representative_selectors.go

* removing redundant code

* updating documentation of new fields in pod.go

* fixes in resources.go

* fix in check.go

* update few comments

Signed-off-by: adisos <[email protected]>

* renaming AddObjects + updating its documentation

* renaming netpol funcs

* renaming connPeers

* fixing representative pods naming and updating relevant funcs

* renaming "GeneralConns" to "ExposedGeneralConns"

* removing PolicyNsFlag

* no need to split namespaces with policies at first

* Revert "no need to split namespaces with policies at first"

This reverts commit 03e384e.

* rename  extractLabelsAndRefineRepresentativePeers and refineRepresentativePeersMatchingLabels

* renaming checkIfP2PConnOrExposureConn

* lint fix

* func allAllowedConnectionsBetweenPeers: remove ingressSet, egressSet

* using new terms for general conns : ClusterWideExposure and ExternalExposure

* an example why should split namespaces at the beginning with the policies

* eliminate RepresentativePeer struct

* fixing some typos and adding some very used words to a cspell file

* more typos fixes

* updating some comments

* updating readme (all formats supported)

* getting netpols before pods for live cluster - so it works well for both exposure-analysis on/off

* Update pkg/netpol/eval/check.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/check.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/exposure.go

Co-authored-by: Adi Sosnovich <[email protected]>

* rename getSelectorsAndUpdateExposedGeneralConns

* rename ScanPolicyRulesAndUpdateExposedWideConns

* rename updateNetworkPolicyWideExposureConns

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/peer.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/pod.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/pod.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/resources.go

Co-authored-by: Adi Sosnovich <[email protected]>

* fixing lint

* Update pkg/netpol/eval/internal/k8s/representative_selectors.go

Co-authored-by: Adi Sosnovich <[email protected]>

* lint fix

* Update pkg/netpol/eval/internal/k8s/representative_selectors.go

Co-authored-by: Adi Sosnovich <[email protected]>

* fixing the last commit

* fixing the SelectorsFullMatch doc

* removing unnecessaryDeepCopy calls

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* Update pkg/netpol/eval/internal/k8s/netpol.go

Co-authored-by: Adi Sosnovich <[email protected]>

* lint fix

* some renamings in representative_selectors + document why returning full match for rep selector in case of empty rule

* adding line to comment

* split funcs in check.go for readability

* rename hasRepresentativePod

* updating comment

* updating comment of storing the named port

* updating String() func of workloadpeer

* comment update

* updating comment

* new func of selectors match in `netpol.go` to avoid duplicates

* updating comment in pod.go (what do the combinations of rep selectors imply for)

* renaming str vars

* eliminating addIfMissingNamespace func

* new tests - rep peers when there is real ns but no real pods matching

* add comment on String() func

* rename handleRequirementWithInOpAndSingleValue

* renaming test dirs and expected output of exposure-analysis tests

* new fixes

---------

Signed-off-by: adisos <[email protected]>
Co-authored-by: adisos <[email protected]>
Co-authored-by: Adi Sosnovich <[email protected]>

---------

Signed-off-by: adisos <[email protected]>
Co-authored-by: Adi Sosnovich <[email protected]>
Co-authored-by: Tanya <[email protected]>
Co-authored-by: adisos <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants