def main(): random.seed(80) logging.disable(sys.maxsize) parser = argparse.ArgumentParser(description="Batfish Impact Analysis") parser.add_argument("-p", "--snapshot_path", help="BF_SNAPSHOT_PATH", required=True) parser.add_argument("-s", "--snapshot_name", help="SNAPSHOT_NAME", required=True) parser.add_argument("-n", "--network_name", help="BF_NETWORK", required=True) parser.add_argument("-i", "--service_ip", help="SERVICE_IP", default="172.29.236.139") args = vars(parser.parse_args()) BF_NETWORK = args["network_name"] BF_SNAPSHOT_BASE = args["snapshot_name"] BF_SNAPSHOT_PATH = args["snapshot_path"] BF_SNAPSHOT_FAIL = "fail_snapshot" # BATFISH_SERVICE_IP = "172.29.236.139" BATFISH_SERVICE_IP = args["service_ip"] bf_session.host = BATFISH_SERVICE_IP load_questions() bf_set_network(BF_NETWORK) bf_init_snapshot(BF_SNAPSHOT_PATH, name=BF_SNAPSHOT_BASE, overwrite=True) # Print Batfish settings/parameters print_bf_params( DST_IP_REACHABILITY=DST_IP_REACHABILITY, PORT_CHANNEL_MEMBER_SCOPE=PORT_CHANNEL_MEMBER_SCOPE, L3_INTERFACE_SCOPE=L3_INTERFACE_SCOPE, NODE_SCOPE=NODE_SCOPE, ) # Run Batfish tests print("\n[bold]== Deactivating Interfaces ==[/bold]") deactivate_po_members(BF_SNAPSHOT_BASE, BF_SNAPSHOT_FAIL) deactivate_l3_interfaces(BF_SNAPSHOT_BASE, BF_SNAPSHOT_FAIL) print("\n[bold]== Deactivating Nodes ==[/bold]") deactivate_nodes(BF_SNAPSHOT_BASE, BF_SNAPSHOT_FAIL) print( "\n[bold green][SUCCESS] No reachability differences found[/bold green]" ) # Clean up Snapshots/Networks delete_bf_data()
def build_specification(base: Path, affected_nodes: List[str], sensitive_nodes: List[str], allowed_command: Commands, invariants: Connector) -> Specification: bf_init_snapshot(str(base), "base") affected_nodes = resolve_list(affected_nodes, "base") sensitive_nodes = resolve_list(sensitive_nodes, "base") topology = build_topology("base", base, affected_nodes, sensitive_nodes) commands = allowed_command.compute() return Specification(base, sensitive_nodes, topology, commands, invariants, "")
def check_invalid_policies(path_to_csv: str, snapshot: str) -> bool: global initialized if not initialized: initialized = True # bf_session.host = "10.81.1.21" load_questions() policies = build_policies_from_csv(path_to_csv) bf_init_snapshot(snapshot, "check") for policy in policies: if not policy.eval("", "check"): print(policy) # return False return True
def init_batfish(self): bf_session.host = self.host bf_session.coordinatorHost = self.host bf_set_network(self.NETWORK_NAME) # Initialize Batfish Snapshot bf_init_snapshot(self.snapshot_folder, name=self.NETWORK_NAME, overwrite=True) # Generate Dataplane bf_generate_dataplane() # Load Batfish Questions load_questions()
def network(): load_questions(_stable_question_dir) load_questions(_experimental_question_dir) try: bf_delete_network(TEST_NETWORK) except Exception: pass bf_set_network(TEST_NETWORK) yield bf_init_snapshot(_test_rig_dir + "/example", name="example") bf_delete_network(TEST_NETWORK)
def Batfish_parses_config_files(intermediate_scenario_directory, DEBUG, NETWORK_NAME, SNAPSHOT_NAME): print( "NETWORK_NAME", NETWORK_NAME, "SNAPSHOT_NAME", SNAPSHOT_NAME, "intermediate_scenario_directory", intermediate_scenario_directory, ) bf_set_network(NETWORK_NAME) bf_init_snapshot(intermediate_scenario_directory, name=SNAPSHOT_NAME, overwrite=True) load_questions() pd.options.display.max_columns = 6 if DEBUG: print_debugging_info()
def interfaces_from_snapshot(snapshot: str, nodes: str = None) -> Set[str]: cache_path = os.path.join(snapshot, "interface_from_snapshot.json") found = False if os.path.exists(cache_path): found = True caches = json.load(open(cache_path)) else: bf_init_snapshot(snapshot, "interface_from_snapshot", overwrite=True) caches = {} if len(caches) == 0: results = bfq.interfaceProperties().answer( snapshot="interface_from_snapshot").frame() for _, result in results.iterrows(): if result.Interface.hostname not in caches: caches[result.Interface.hostname] = [] caches[result.Interface.hostname].append( interface_to_str(result.Interface)) json.dump(caches, open(cache_path, "w")) if not found: bf_delete_snapshot("interface_from_snapshot") if nodes: return set(caches[nodes]) else: return set([y for x in caches.values() for y in x])
def get_snapshot(self, path: Path) -> str: if path not in self.snapshots: self.current_idx += 1 bf_init_snapshot(str(path), str(self.current_idx)) self.snapshots[path] = str(self.current_idx) return self.snapshots[path]
def test_snapshot_validation(): bf_session.network = 'testnet' with pytest.raises(ValueError): bf_init_snapshot("x", name="foo/bar")
def __init__(self, snapshot): bf_logger.setLevel(logging.ERROR) load_questions() bf_init_snapshot(snapshot)
def test_snapshot_validation(): with pytest.raises(ValueError): bf_init_snapshot("x", name="foo/bar")
def run_module(): # define the available arguments/parameters that a user can pass to # the module module_args = dict(base_name=dict(type='str', required=False, default=None), host=dict(type='str', required=False, default='localhost'), name=dict(type='str', required=True), network=dict(type='str', required=True), path=dict(type='str', required=True)) # seed the result dict in the object # we primarily care about changed and state # change is if this module effectively modified the target # state will include any data that you want your module to pass back # for consumption, for example, in a subsequent task result = dict( changed=False, name='', network='', result='', ) # the AnsibleModule object will be our abstraction working with Ansible # this includes instantiation, a couple of common attr would be the # args/params passed to the execution, as well as if the module # supports check mode module = AnsibleModule(argument_spec=module_args, supports_check_mode=True) if not pybatfish_found: module.fail_json(msg='Python module Pybatfish is required') if module.check_mode: return result base_name = module.params['base_name'] name = module.params['name'] path = module.params['path'] try: bf_session.coordinatorHost = module.params['host'] network = bf_set_network(module.params['network']) except Exception as e: module.fail_json(msg='Failed to set network: {}'.format(e), **result) result['network'] = network try: if base_name is not None: name = bf_fork_snapshot(add_files=path, base_name=base_name, name=name, overwrite=True) result[ 'result'] = "Forked snapshot '{}' from '{}' adding files at '{}'".format( name, base_name, path) else: name = bf_init_snapshot(path, name, overwrite=True) result[ 'result'] = "Created snapshot '{}' from files at '{}'".format( name, path) except Exception as e: module.fail_json(msg='Failed to init snapshot: {}'.format(e), **result) result['name'] = name # manipulate or modify the state as needed (this is going to be the # part where your module will do what it needs to do) result['changed'] = True module.exit_json(**result)
def init_snapshot(self, snapshot_name, overwrite=True): snapshot_dir = "assets/snapshot_holder/" bf_init_snapshot(snapshot_dir, name=str(snapshot_name), overwrite=overwrite)