Exemplo n.º 1
0
def test_list_questions(tmpdir, session):
    dir = tmpdir.mkdir("questions")
    dir.join(TEST_QUESTION_NAME + ".json").write(
        json.dumps(TEST_QUESTION_DICT))
    load_questions(question_dir=dir.strpath, session=session)
    names = [q["name"] for q in list_questions()]
    assert names == [TEST_QUESTION_NAME]
Exemplo n.º 2
0
def test_make_check(question_dir):
    """Make a check out of the first available question."""
    load_questions(question_dir=question_dir)
    q = list_questions()[0]['name']
    qdict = getattr(bfq, q)().make_check().dict()
    assert qdict.get('assertion') == Assertion(AssertionType.COUNT_EQUALS,
                                               0).dict()
Exemplo n.º 3
0
def test_list_questions_default_session(tmpdir):
    dir = tmpdir.mkdir("questions")
    dir.join(TEST_QUESTION_NAME + ".json").write(
        json.dumps(TEST_QUESTION_DICT))
    load_questions(question_dir=dir.strpath)
    names = [q["name"] for q in bf_session.q.list()]
    assert names == [TEST_QUESTION_NAME]
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()
Exemplo n.º 5
0
def initialise_batfish():
    # Load all the questions.
    load_questions()
    # Initialises batfish.
    bf_set_network(NETWORK_NAME)
    bf_init_snapshot(BASE_SNAPSHOT_PATH,
                     name=BASE_SNAPSHOT_NAME,
                     overwrite=True)
Exemplo n.º 6
0
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.reducedReachability().answer(snapshot='candidate', reference_snapshot='failure')
    print_reduced_rechability(rr.get('answerElements')[0])

    

    

    return 0 if not any([cpFailed, dpFailed, csFailed, dpFailedoutage]) else 1
Exemplo n.º 7
0
def resolve(node_spec: str, node_property: str, snapshot: str):
    data = set()
    load_questions()
    result = bfq.nodeProperties(nodes=node_spec,
                                properties=node_property)\
        .answer(snapshot=snapshot).frame()
    for node in result.Node.values:
        data.add(node)
    return data
Exemplo n.º 8
0
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(join(_this_dir, "snapshot"), name="snapshot")
    bf_delete_network(TEST_NETWORK)
Exemplo n.º 9
0
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 generate_code_for_questions(
    question_list: List[Mapping[str, Any]],
    question_class_map: Mapping[str, QuestionMeta],
) -> List[NotebookNode]:
    """Generate notebook cells for all questions in a single question category."""
    load_questions()
    cells: List[NotebookNode] = []
    for question_data in question_list:
        cells.extend(
            generate_code_for_question(question_data, question_class_map))
    return cells
Exemplo n.º 11
0
def main():
    load_questions()
    o = FindBestOrderPerCommand(
        Path("/home/leo/repos/sdn-verifier/configs/default"), [
            Path(
                '/home/leo/repos/sdn-verifier/configs/updates/acls/as1border1.cfg'
            ),
            Path(
                '/home/leo/repos/sdn-verifier/configs/updates/acls/as2border1.cfg'
            )
        ])
    print(o.find())
Exemplo n.º 12
0
    def run(path, adj):
        """
        Generates the Batfish routing table
        :param path: Path to the config files used to generate the routing table
        :param adj: Adjacency information, not used by Batfish
        :return: Triplet of routing table, parse warning and init issues of Batfish
        """
        load_questions()
        bf_set_network('fuzzer')
        bf_init_snapshot(path)

        return bfq.routes().answer().frame(), bfq.parseWarning().answer().frame(), bfq.initIssues().answer().frame()
Exemplo n.º 13
0
 def check_traffic(self, snapshot: str, reference_snapshot: str):
     # bf_set_snapshot(name)
     load_questions()
     header = HeaderConstraints(srcIps="0.0.0.0/0",
                                dstIps="0.0.0.0/0",
                                ipProtocols=["tcp"])
     path = PathConstraints(startLocation="/as2/", endLocation="/as3/")
     # result = bfq.differentialReachability(headers=header) \
     #     .answer(snapshot=snapshot, reference_snapshot=reference_snapshot).frame()
     result = bfq.reachability(headers=header, pathConstraints=path) \
         .answer(snapshot=reference_snapshot).frame()
     result.to_csv('out.csv')
Exemplo n.º 14
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
Exemplo n.º 15
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()
Exemplo n.º 16
0
def main():
    parser = argparse.ArgumentParser(
        description="Script to test network configs with batfish")
    parser.add_argument("--batfish_server",
                        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("--log",
                        help='Path to logging file',
                        default='batfish.log',
                        type=str)
    OPTIONS = parser.parse_args()

    logging.info('=> Batfish server is running on: %s',
                 str(OPTIONS.batfish_server))
    bf_session.host = OPTIONS.batfish_server

    # Configure logging for log file if defined.
    if OPTIONS.log:
        logging.basicConfig(filename=OPTIONS.log,
                            format='%(levelname)s: %(message)s',
                            level=logging.INFO)
        console = logging.StreamHandler()
        console.setLevel(logging.ERROR)
        logging.getLogger('').addHandler(console)

    # Initialize BATFISH session
    # Batfish server must be running on a container
    # docker run -p 8888:8888 -p 9997:9997 -p 9996:9996 batfish/allinone
    load_questions()
    bf_init_snapshot(OPTIONS.candidate, name='candidate')

    bf_set_snapshot('candidate')
    csFailed = test_config_sanity(False)
    logging.info('=> csFailed status: %s', str(csFailed))
    cpFailed = test_controlplane(False)
    logging.info('=> cpFailed status: %s', str(cpFailed))

    if csFailed or cpFailed:
        return 1
    else:
        return 0
  def run(self, tmp=None, task_vars=None):
    del tmp

    # モジュールを実行する
    # ただし、このモジュールは何もしない
    result = super(ActionModule, self).run(task_vars=task_vars)

    #
    # モジュール実行後の後工程処理
    #

    src = self._task.args.get('src')
    dest = self._task.args.get('dest')
    snapshot_name = self._task.args.get('snapshot_name')
    snapshot_path = self._task.args.get('snapshot_path')
    network_name = self._task.args.get('network_name')
    application = self._task.args.get('application')
    condition = self._task.args.get('condition')
    node = self._task.args.get('node')
    acl_name = self._task.args.get('acl_name')

    src_list = self.create_src_list(src)
    dest_list = self.create_dest_list(dest)
    application_list = self.create_application_list(application)
    condition_list = self.create_condition_list(condition)
    node_list = self.create_node_list(node)
    acl_list = self.create_acl_list(acl_name)


    load_questions()
    bf_set_network(network_name)
    bf_init_snapshot(snapshot_path, name=snapshot_name, overwrite=True)
    #init_snapshot(self, snapshot_name, snapshot_path)
    msg = self.answer_testfilters_question(src_list, node_list, acl_list, dest_list, application_list)
    #msg = self.answer_testfilters_question(src, node, acl_name, dest, application)
    answer = msg
    msg1 = self.judge_condition(condition, answer)

    result['batfish_result'] = json.loads(msg)
    #result['judge'] = json.loads(msg1)

    if msg1 == 'PASS':
      result['msg'] = 'PASS'
      return result
    else:
      result['failed'] = True
      return result
Exemplo n.º 18
0
def test_list_questions():
    current_path = os.path.abspath(os.path.dirname(__file__))
    question_directory = os.path.join(current_path, "../../questions")
    load_questions(question_dir=question_directory)
    assert list_questions() != []
Exemplo n.º 19
0
    def run(self, tmp=None, task_vars=None):
        del tmp

        # モジュールを実行する
        # ただし、このモジュールは何もしない
        result = super(ActionModule, self).run(task_vars=task_vars)

        #
        # モジュール実行後の後工程処理
        #

        snapshot_name = self._task.args.get('snapshot_name')
        snapshot_path = self._task.args.get('snapshot_path')
        network_name = self._task.args.get('network_name')

        csv_file_path = self._task.args.get('csv_file_path')

        PASS = "******"
        FAIL = "FAIL"

        result = {}
        result_list = []

        with open(csv_file_path, mode='r') as f:
            csv_file_list = [x for x in csv.DictReader(f)]

        answer_list = []

        # Batfishの質問、スナップショット及びノードを読見込む
        load_questions()

        if network_name and snapshot_name:
            bf_set_network(network_name)
            bf_init_snapshot(snapshot_path, name=snapshot_name, overwrite=True)
        else:
            bf_set_network()
            bf_init_snapshot(snapshot_path, overwrite=True)

        for c in csv_file_list:
            expect_condition = c.get('expect_condition')
            test_id = c.get('test_id')
            src = c.get('src')
            dest = c.get('dest')
            acl = c.get('acl_name')
            node = c.get('node')
            application = c.get('application')
            src_int = c.get('src_int')
            dest_int = c.get('dest_int')

            if expect_condition == '' or expect_condition == None:
                result['failed'] = True
                result['msg'] = 'expect_condition parameter is required.'
                return result

            if expect_condition != 'deny' and expect_condition != 'permit':
                result['failed'] = True
                result[
                    'msg'] = 'expect_condition parameter should be permit or deny. '
                return result

            if test_id == '' or test_id == None:
                result['failed'] = True
                result['msg'] = 'test_id parameter is required.'
                return result

            #srcは必ず必要なパラメータ
            if src == '':
                result['failed'] = True
                result['msg'] = 'src parameter is required.'
                return result

            if node == '':
                result['failed'] = True
                result['msg'] = 'node parameter is required.'
                return result

            if src_int != '' and node == '':
                result['failed'] = True
                result[
                    'msg'] = 'node must be specified if you want to test src_int.'
                return result

            if acl == '' or acl == None:
                ip_flow = HeaderConstraints(srcIps=src)

                answer = bfq.testFilters(headers=ip_flow, nodes=node).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["expect_condition"] = expect_condition
                answer_list.append(json_answer)

            if dest != '' and application != '':

                ip_flow = HeaderConstraints(srcIps=src,
                                            dstIps=dest,
                                            applications=application)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["expect_condition"] = expect_condition
                answer_list.append(json_answer)

            # 一つ上の条件が一致した場合は以下セクションを読み込む必要がないのでelifを使う
            elif dest != '' and application == '':
                ip_flow = HeaderConstraints(srcIps=src, dstIps=dest)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["expect_condition"] = expect_condition
                answer_list.append(json_answer)

            elif dest == '' and application != '':
                ip_flow = HeaderConstraints(srcIps=src,
                                            applications=application)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["expect_condition"] = expect_condition
                answer_list.append(json_answer)

            # あるノードのintに着信したパケットが出力intとして指定したintで
            # どのように処理されるかテストする
            # nodeの指定がない場合はエラーになるよう上で実装済
            #
            # ある着信がdeny or permitをテストしたい時のセクション

            #ノードとintを正確に指定しても動作しないので保留

            #if src_int != '' and dest_int == '' and application == '' and dest == '':
            #    flow = HeaderConstraints(srcIps=src)
            #    answer = bfq.testFilters(headers=flow,
            #             startLocation="@enter(" + node + "[" + src_int + "])",
            #             filters="@out(" + dest_int + ")").answer()
#
#    show = answer.frame()
#    answer = show.to_json()
#    json_answer = json.loads(answer)
#    json_answer["Test_id"] = test_id
#    json_answer["expect_condition"] = expect_condition
#    answer_list.append(json_answer)

#if src_int != '' and dest_int != '' and application != '' and dest != '' and application != '':
#    flow = HeaderConstraints(srcIps=src,
#                  dstIps=dest,
#                  applications=application)
#    answer = bfq.testFilters(headers=flow,
#             startLocation="@enter(" + node + "[" + src_int + "])",
#             filters="@out(" + dest_int + ")").answer()
#
#    show = answer.frame()
#    answer = show.to_json()
#    json_answer = json.loads(answer)
#    json_answer["Test_id"] = test_id
#    json_answer["expect_condition"] = expect_condition
#   answer_list.append(json_answer)

        result['batfish_result'] = answer_list

        for answer in answer_list:
            action = answer['Action']
            action_num = action["0"]
            condition = answer["expect_condition"]
            test_id = answer["Test_id"]

            # Batfishが出す結果(DENY or PERMIT)とexpect_conditionがマッチしなければFAIL
            if action_num != condition.upper():
                result['failed'] = True
                result_list.append('test_id {0} is {1}.'.format(test_id, FAIL))
            else:
                result_list.append('test_id {0} is {1}.'.format(test_id, PASS))

        result['msg'] = result_list
        return result
Exemplo n.º 20
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')
Exemplo n.º 21
0
from pybatfish.question.question import load_questions
from pybatfish.datamodel.flow import HeaderConstraints, PathConstraints
from pybatfish.question import bfq
import random
import sys
import argparse

parser = argparse.ArgumentParser(description="Batfish Shell")
parser.add_argument("-p",
                    "--snapshot_path",
                    help="SNAPSHOT_PATH",
                    required=True)
parser.add_argument("-s",
                    "--snapshot_name",
                    help="SNAPSHOT_NAME",
                    required=True)
parser.add_argument("-n", "--network_name", help="NETWORK_NAME", required=True)

BATFISH_SERVICE_IP = "172.29.236.139"
args = vars(parser.parse_args())
bf_session.host = BATFISH_SERVICE_IP
load_questions()

print("[*] Initializing BASE_SNAPSHOT")
bf_set_network(args["network_name"])
bf_init_snapshot(args["snapshot_path"],
                 name=args["snapshot_name"],
                 overwrite=True)

print("[OK] Success - Batfish imports ready...")
Exemplo n.º 22
0
 def __init__(self, snapshot):
     bf_logger.setLevel(logging.ERROR)
     load_questions()
     bf_init_snapshot(snapshot)
Exemplo n.º 23
0
    def run(self, tmp=None, task_vars=None):
        del tmp

        # モジュールを実行する
        # ただし、このモジュールは何もしない
        result = super(ActionModule, self).run(task_vars=task_vars)

        import csv
        #
        # モジュール実行後の後工程処理
        #

        snapshot_name = self._task.args.get('snapshot_name')
        snapshot_path = self._task.args.get('snapshot_path')
        network_name = self._task.args.get('network_name')

        csv_file_path = self._task.args.get('csv_file_path')

        csv_file_list = []
        PASS = "******"
        FAIL = "FAIL"

        result = {}
        result_list = []
        with open(csv_file_path) as f:

            csv_file_list = [x for x in csv.DictReader(f)]

        answer_list = []
        load_questions()
        bf_set_network(network_name)
        bf_init_snapshot(snapshot_path, name=snapshot_name, overwrite=True)
        result = {}
        for csv in csv_file_list:
            intend_condition = csv.get('intend_condition')
            test_id = csv.get('test_id')
            src = csv.get('src')
            dest = csv.get('dest')
            acl = csv.get('acl_name')
            node = csv.get('node')
            application = csv.get('application')

            if intend_condition == '' or intend_condition == None:
                result['failed'] = True
                result['msg'] = 'intend_condition parameter is required.'
                return result

            if test_id == '' or test_id == None:
                result['failed'] = True
                result['msg'] = 'test_id parameter is required.'
                return result

            #srcは必ず必要なパラメータ
            if src == '':
                result['failed'] = True
                result['msg'] = 'src parameter is required.'
                return result

            if node == '':
                result['failed'] = True
                result['msg'] = 'node parameter is required.'
                return result

            if acl == '':
                result['failed'] = True
                result['msg'] = 'acl parameter is required.'
                return result

            if dest != '' and application != '':

                ip_flow = HeaderConstraints(srcIps=src,
                                            dstIps=dest,
                                            applications=application)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["Intend_condition"] = intend_condition
                answer_list.append(json_answer)

            elif dest != '' and application == '':
                ip_flow = HeaderConstraints(srcIps=src, dstIps=dest)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["Intend_condition"] = intend_condition
                answer_list.append(json_answer)

            elif application != '' and dest == '':
                ip_flow = HeaderConstraints(srcIps=src,
                                            applications=application)
                answer = bfq.testFilters(headers=ip_flow,
                                         nodes=node,
                                         filters=acl).answer()
                show = answer.frame()
                answer = show.to_json()
                json_answer = json.loads(answer)
                json_answer["Test_id"] = test_id
                json_answer["Intend_condition"] = intend_condition
                answer_list.append(json_answer)

        result['batfish_result'] = answer_list

        for answer in answer_list:
            action = answer['Action']
            action_num = action["0"]
            condition = answer["Intend_condition"]
            test_id = answer["Test_id"]

            if action_num != condition.upper():
                result['failed'] = True
                result_list.append('{0}. test_id {1} test is failed.'.format(
                    FAIL, test_id))
            else:
                result_list.append(PASS)
                result_list.append('{0}. {1} test is passed.'.format(
                    PASS, test_id))

        result['msg'] = result_list
        return result
Exemplo n.º 24
0
def test_list_questions(question_dir):
    load_questions(question_dir=question_dir)
    assert list_questions() != []
Exemplo n.º 25
0
 def get_traffic(self, snapshot: str):
     load_questions()
     result = bfq.reachability(headers=self.header, pathConstraints=self.path) \
         .answer(snapshot=snapshot).frame()
     print(result.to_csv("path.csv"))