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,
                         "")
Exemple #3
0
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
Exemple #4
0
    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()
Exemple #7
0
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])
Exemple #8
0
 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]
Exemple #9
0
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)
Exemple #11
0
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)
Exemple #13
0
 def init_snapshot(self, snapshot_name, overwrite=True):
     snapshot_dir = "assets/snapshot_holder/"
     bf_init_snapshot(snapshot_dir,
                      name=str(snapshot_name),
                      overwrite=overwrite)