def get_cache_of_diff(self, origin: str, reference: str) -> DataFrame: if origin not in self.diff_cache: self.diff_cache[origin] = {} if reference not in self.diff_cache[origin]: self.diff_cache[origin][reference] = \ bfq.differentialReachability().answer(snapshot=origin, reference_snapshot=reference).frame() return self.diff_cache[origin][reference]
def main(): parser = argparse.ArgumentParser(description="Script to test network configs with batfish") parser.add_argument( "--host", help="IP/host of the batfish server", default='localhost', type=str ) parser.add_argument( "--candidate", help='Path to directory containing candidate device configuration folder', default='./candidate', type=str ) parser.add_argument( "--failure", help='Path to directory containing candidate device configuration folder with injected failure conditions', default='./candidate-with-failure', type=str ) parser.add_argument( "--log", help='Path to logging file', type=str ) args = parser.parse_args() bf_session.coordinatorHost = args.host bf_logger.setLevel(logging.WARN) if args.log: logging.basicConfig(filename=args.log, format='%(levelname)s: %(message)s', level=logging.INFO) console = logging.StreamHandler() console.setLevel(logging.ERROR) logging.getLogger('').addHandler(console) load_questions() bf_init_snapshot(args.candidate, name='candidate') bf_init_snapshot(args.failure, name='failure') bf_set_snapshot('candidate') csFailed = test_config_sanity(False) cpFailed = test_controlplane(False) dpFailed = test_dataplane(False, fromNode='leaf-3') logging.info("\nProgress: analysing failure conditions") bf_set_snapshot('failure') dpFailedoutage = test_dataplane(False, fromNode='leaf-3') rr = bfq.differentialReachability().answer(snapshot='candidate', reference_snapshot='failure') print_reduced_rechability(rr.get('answerElements')[0]) return 0 if not any([cpFailed, dpFailed, csFailed, dpFailedoutage]) else 1
def get_affected_node(self, node: str, snapshot: str, generator: Callable[[List[str]], List[str]]) -> Set[str]: affected_node = set() self.name_idx += 1 results = bfq.differentialReachability(pathConstraints=PathConstraints(startLocation="/(host[0-9]+|pc[0-9]+)/")) \ .answer(snapshot=snapshot, reference_snapshot="exp").frame() for idx, result in results.iterrows(): if result.Flow.ingressNode is not None and result.Flow.ingressNode != node: affected_node.add(result.Flow.ingressNode) return set(generator(list(affected_node)))
def compute_issue_reachable_nodes(s1: str, s2: str): bf_init_snapshot(s1, "s1", overwrite=True) bf_init_snapshot(s2, "s2", overwrite=True) # results = bfq.differentialReachability(pathConstraints=PathConstraints(startLocation="/(host[0-9]+|pc[0-9]+)/")) \ # .answer(snapshot="s1", reference_snapshot="s2").frame() results = bfq.differentialReachability(pathConstraints=PathConstraints(startLocation="/(host[0-9]+|pc[0-9]+)/")) \ .answer(snapshot="s1", reference_snapshot="s2").frame() affected_node = set() for idx, result in results.iterrows(): if result.Flow.ingressNode: affected_node.add(result.Flow.ingressNode) nodes = nodes_from_snapshot(s1) out = open(os.path.join(s2, "reach.json"), "w") reachable = get_reachable_nodes("s2", affected_node).union(affected_node) print(reachable) print(nodes.difference(reachable)) json.dump({ "reachable": list(reachable), "protected": list(nodes.difference(reachable)) }, out, indent=2) reset()
def get_differential_reachability(bf_snapshot_base, bf_snapshot_fail): answer = (bfq.differentialReachability(headers=HeaderConstraints( dstIps=DST_IP_REACHABILITY)).answer( snapshot=bf_snapshot_fail, reference_snapshot=bf_snapshot_base).frame()) return answer
def eval(self, ori_snapshot: str, new_snapshot: str) -> bool: result = bfq.differentialReachability( header=self.header_constraint.build(), pathConstraints=self.path_constraint.build()) \ .answer(snapshot=ori_snapshot, reference_snapshot=new_snapshot).frame() return result.size > 0
def check_traffic(self, snapshot: str, reference_snapshot: str): # bf_set_snapshot(name) load_questions() result = bfq.differentialReachability(headers=self.header, pathConstraints=self.path) \ .answer(snapshot=snapshot, reference_snapshot=reference_snapshot).frame() result.to_csv('diff.csv')