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

Semantic diff query optimized #577

Merged
merged 46 commits into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
773fb84
Optimized implementation of EquivalenceQuery.
tanyaveksler Jun 4, 2023
c5bf934
Added VacuityQuery and RedundancyQuery optimized implementation.
tanyaveksler Jun 20, 2023
aab6396
Added VacuityQuery and RedundancyQuery optimized implementation.
tanyaveksler Jun 20, 2023
54d3343
Ignoring 'complex function' lint error.
tanyaveksler Jun 11, 2023
adba6dd
Added VacuityQuery and RedundancyQuery optimized implementation.
tanyaveksler Jun 20, 2023
ab3a82e
Removed redundant method.
tanyaveksler Jun 13, 2023
c9393ee
Added VacuityQuery and RedundancyQuery optimized implementation.
tanyaveksler Jun 20, 2023
da98a3f
Fixed domain updating mechanism per rule (to avoid activating multipl…
tanyaveksler Jun 20, 2023
9cd810e
Fixed lint errors
tanyaveksler Jun 20, 2023
ac4f679
Enabled strongEquivalence optimized implementation.
tanyaveksler Jun 20, 2023
cbe8d1f
Implemented optimized ContainmentQuery.
tanyaveksler Jun 25, 2023
ac38097
Enabled optimized TwoContainmentQuery and PermitsQuery.
tanyaveksler Jun 25, 2023
6e632b5
Fixed small inaccuracy in handling host endpoints in optimized solution.
tanyaveksler Jun 27, 2023
af4c84f
Merge branch 'equivalence-based-queries-optmized' into containment-ba…
tanyaveksler Jun 27, 2023
a6ef67c
Implemented optimized InterferesQuery
tanyaveksler Jul 2, 2023
959d741
Merge with master
tanyaveksler Jul 9, 2023
3cd1578
Small improvement in print differences for two config queries
tanyaveksler Jul 9, 2023
951b40c
Merge branch 'master' into interferes-based-queries-optimized
tanyaveksler Jul 11, 2023
5b21d04
Optimized implementation of intersects and forbids queries.
tanyaveksler Jul 11, 2023
2b6b13b
Fixed bug in creation of optimized istio policy properties.
tanyaveksler Jul 11, 2023
3d840a4
Opened for optimized run those queries that do not call allowed_conne…
tanyaveksler Jul 11, 2023
a68de7e
Merge with master.
tanyaveksler Jul 16, 2023
22b8f2c
Implemented sanity query optimized.
tanyaveksler Jul 16, 2023
35e8a74
Implemented optimized semantic diff query.
tanyaveksler Jul 18, 2023
08b6b10
Change in semantic diff query: in case of optimized_run == 'debug', a…
tanyaveksler Jul 25, 2023
fc643da
Small fix
tanyaveksler Jul 25, 2023
054aaf6
Merge with master
tanyaveksler Jul 25, 2023
bd22ab9
Improving output of comparison between original and optimized runs in…
tanyaveksler Jul 30, 2023
fc6eaba
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Jul 30, 2023
ed791e1
Fixing handling ipv6 blocks in optimized run.
tanyaveksler Jul 30, 2023
4867e95
Fixing lint errors
tanyaveksler Jul 30, 2023
a4e14b0
Update nca/FWRules/ConnectivityGraph.py
tanyaveksler Aug 6, 2023
2fd82da
merge with master
tanyaveksler Aug 6, 2023
8967e2b
Avoid using redundant all_peers (using inactive dimension instead).
tanyaveksler Aug 6, 2023
abb2fbe
Simplified filtering of ipv6 blocks
tanyaveksler Aug 6, 2023
e69b417
Fixed lint warnings.
tanyaveksler Aug 8, 2023
1caf9ce
merge with master
tanyaveksler Aug 8, 2023
6219813
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Aug 8, 2023
9c77ec5
Optimized filtering IpBlocks by mask.
tanyaveksler Aug 8, 2023
22cefcb
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Aug 15, 2023
d321200
Update nca/CoreDS/Peer.py
tanyaveksler Aug 15, 2023
334ba10
Fixed filtering IpBlocks by mask in ConnectivityMapQuery
tanyaveksler Aug 15, 2023
55ddd55
Refined filtering of IPv6 blocks in original and optimized solutions …
tanyaveksler Aug 15, 2023
13cdc5a
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Aug 20, 2023
b24d06d
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Sep 5, 2023
e3cbd0f
Merge branch 'master' into semantic-diff-query-optimized
tanyaveksler Sep 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion nca/CoreDS/ConnectionSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -585,8 +585,9 @@ def get_non_tcp_connections():
# get rid of ConnectionSet and move the code below to ConnectivityProperties.py

@staticmethod
def get_connection_set_and_peers_from_cube(conn_cube, peer_container,
def get_connection_set_and_peers_from_cube(the_cube, peer_container,
relevant_protocols=ProtocolSet(True)):
conn_cube = the_cube.copy()
src_peers = conn_cube["src_peers"] or peer_container.get_all_peers_group(True)
conn_cube.unset_dim("src_peers")
dst_peers = conn_cube["dst_peers"] or peer_container.get_all_peers_group(True)
Expand Down
11 changes: 11 additions & 0 deletions nca/CoreDS/ConnectivityProperties.py
Original file line number Diff line number Diff line change
Expand Up @@ -491,3 +491,14 @@ def are_auto_conns(self):
if cube[src_peers_index] != cube[dst_peers_index] or not cube[src_peers_index].is_single_value():
return False
return True

def props_without_auto_conns(self):
"""
Return the properties after removing all connections from peer to itself
"""
peers = self.project_on_one_dimension("src_peers") | self.project_on_one_dimension("dst_peers")
auto_conns = ConnectivityProperties()
for peer in peers:
auto_conns |= ConnectivityProperties.make_conn_props_from_dict({"src_peers": PeerSet({peer}),
"dst_peers": PeerSet({peer})})
return self - auto_conns
2 changes: 1 addition & 1 deletion nca/CoreDS/Peer.py
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ def get_ip_block_canonical_form(self):
res |= elem
return res

def filter_ipv6_blocks(self, ip_blocks_mask):
def filter_ip_blocks_by_mask(self, ip_blocks_mask):
"""
Update ip blocks in the peer set by keeping only parts overlapping with the given mask.
:param ip_blocks_mask: the mask according to which ip blocks should be updated
tanyaveksler marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
10 changes: 10 additions & 0 deletions nca/FWRules/ConnectivityGraph.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,23 @@ def add_edges_from_cube_dict(self, conn_cube, peer_container):
Add edges to the graph according to the give cube
:param ConnectivityCube conn_cube: the given cube
whereas all other values should be filtered out in the output
:param PeerContainer peer_container: the peer container
"""
conns, src_peers, dst_peers = \
ConnectionSet.get_connection_set_and_peers_from_cube(conn_cube, peer_container)
for src_peer in src_peers:
for dst_peer in dst_peers:
self.connections_to_peers[conns].append((src_peer, dst_peer))

def add_props_to_graph(self, props, peer_container):
"""
Add edges to the graph according to the given connectivity properties
:param props: the given connectivity properties
tanyaveksler marked this conversation as resolved.
Show resolved Hide resolved
:param PeerContainer peer_container: the peer container
"""
for cube in props:
self.add_edges_from_cube_dict(props.get_connectivity_cube(cube), peer_container)

def _get_peer_details(self, peer, format_requirement=False):
"""
Get the name of a peer object for connectivity graph, the type and the namespace
Expand Down
4 changes: 2 additions & 2 deletions nca/NetworkConfig/NetworkConfig.py
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ def get_affected_pods(self, is_ingress, layer_name):

return affected_pods

def _check_for_excluding_ipv6_addresses(self, exclude_ipv6):
def check_for_excluding_ipv6_addresses(self, exclude_ipv6):
"""
checks and returns if to exclude non-referenced IPv6 addresses from the config
Excluding the IPv6 addresses will be enabled if the exclude_ipv6 param is True and
Expand All @@ -202,7 +202,7 @@ def get_referenced_ip_blocks(self, exclude_non_ref_ipv6=False):
if self.referenced_ip_blocks is not None:
return self.referenced_ip_blocks

exclude_non_ref_ipv6_from_policies = self._check_for_excluding_ipv6_addresses(exclude_non_ref_ipv6)
exclude_non_ref_ipv6_from_policies = self.check_for_excluding_ipv6_addresses(exclude_non_ref_ipv6)
self.referenced_ip_blocks = Peer.PeerSet()
for policy in self.policies_container.policies.values():
self.referenced_ip_blocks |= policy.referenced_ip_blocks(exclude_non_ref_ipv6_from_policies)
Expand Down
405 changes: 342 additions & 63 deletions nca/NetworkConfig/NetworkConfigQuery.py

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions nca/Parsers/IstioPolicyYamlParser.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from nca.CoreDS.Peer import IpBlock, PeerSet
from nca.CoreDS.ConnectionSet import ConnectionSet
from nca.CoreDS.PortSet import PortSet
from nca.CoreDS.ProtocolSet import ProtocolSet
from nca.CoreDS.MethodSet import MethodSet
from nca.CoreDS.ConnectivityProperties import ConnectivityProperties
from nca.Resources.IstioNetworkPolicy import IstioNetworkPolicy, IstioPolicyRule
Expand Down Expand Up @@ -489,11 +490,14 @@ def parse_ingress_rule(self, rule, selected_peers):
# currently parsing only ports
# TODO: extend operations parsing to include other attributes
conn_props = ConnectivityProperties.make_empty_props()
tcp_props = ConnectivityProperties.make_conn_props_from_dict(
{"protocols": ProtocolSet.get_protocol_set_with_single_protocol('TCP')})
if to_array is not None:
for operation_dict in to_array:
conn_props |= self.parse_operation(operation_dict)
connections = ConnectionSet()
connections.add_connections('TCP', conn_props)
conn_props &= tcp_props
else: # no 'to' in the rule => all connections allowed
connections = ConnectionSet(True)
conn_props = ConnectivityProperties.get_all_conns_props_per_config_peers(self.peer_container)
Expand All @@ -514,6 +518,7 @@ def parse_ingress_rule(self, rule, selected_peers):
condition_props &= condition_res
condition_conns = ConnectionSet()
condition_conns.add_connections('TCP', condition_props)
condition_props &= tcp_props
if not res_peers:
self.warning('Rule selects no pods', rule)
if not res_peers or not selected_peers:
Expand Down
5 changes: 3 additions & 2 deletions nca/Resources/NetworkPolicy.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ def __str__(self):
return self.full_name()

def __eq__(self, other):
if type(self) == type(other):
if isinstance(self, type(other)):
self.sync_opt_props()
other.sync_opt_props()
return \
Expand Down Expand Up @@ -324,7 +324,8 @@ def referenced_ip_blocks(self, exclude_ipv6=False):
"""
return PeerSet() # default value, can be overridden in derived classes

def _include_ip_block(self, ip_block, exclude_ipv6):
@staticmethod
def _include_ip_block(ip_block, exclude_ipv6):
"""
returns whether to include or not the ipblock in the policy's referenced_ip_blocks
:param IpBlock ip_block: the ip_block to check
Expand Down
3 changes: 2 additions & 1 deletion nca/SchemeRunner.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ class SchemeRunner(GenericYamlParser):
"""

implemented_opt_queries = {'connectivityMap', 'equivalence', 'vacuity', 'redundancy', 'strongEquivalence',
'containment', 'twoWayContainment', 'permits', 'interferes', 'pairwiseInterferes'}
'containment', 'twoWayContainment', 'permits', 'interferes', 'pairwiseInterferes',
'forbids', 'emptiness', 'disjointness', 'allCaptured', 'sanity', 'semanticDiff'}

def __init__(self, scheme_file_name, output_format=None, output_path=None, optimized_run='false'):
GenericYamlParser.__init__(self, scheme_file_name)
Expand Down
3 changes: 2 additions & 1 deletion tests/run_all_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ def run_all_test_flow(self, all_results):
tmp_opt = [i for i in self.test_queries_obj.args_obj.args if '-opt=' in i]
opt = tmp_opt[0].split('=')[1] if tmp_opt else 'false'
if isinstance(self.test_queries_obj, CliQuery) and (opt == 'debug' or opt == 'true'):
implemented_opt_queries = {'--connectivity', '--equiv', '--permits', '--interferes'}
implemented_opt_queries = {'--connectivity', '--equiv', '--permits', '--interferes', '--forbids',
'--sanity', '--semantic_diff'}
# TODO - update/remove the optimization below when all queries are supported in optimized implementation
if not implemented_opt_queries.intersection(set(self.test_queries_obj.args_obj.args)):
print(f'Skipping {self.test_queries_obj.test_name} since it does not have optimized implementation yet')
Expand Down