예제 #1
0
def test___restart_peers_found_deployment_id():
    test___restart_peers_found_deployment_id.run_command_counter = 0

    def run_command(cmd):
        output = [
            [
                'vtysh', '-c',
                'clear bgp peer-group BGP_TEST_PEER_GROUP_1 soft in'
            ],
            [
                'vtysh', '-c',
                'clear bgp peer-group BGP_TEST_PEER_GROUP_2 soft in'
            ],
        ]
        desired_value = output[
            test___restart_peers_found_deployment_id.run_command_counter]
        assert cmd == desired_value
        test___restart_peers_found_deployment_id.run_command_counter += 1
        return 0, "", ""

    cfg_mgr = MagicMock()
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }
    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    mocked = MagicMock(
        name='_BGPAllowListMgr__find_peer_group_by_deployment_id')
    mocked.return_value = ["BGP_TEST_PEER_GROUP_1", "BGP_TEST_PEER_GROUP_2"]
    mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked
    app.allow_list.run_command = run_command
    rc = mgr._BGPAllowListMgr__restart_peers(5)
    assert rc
예제 #2
0
def set_del_test(op, args, currect_config, expected_config):
    from app.allow_list import BGPAllowListMgr
    set_del_test.push_list_called = False

    def push_list(args):
        set_del_test.push_list_called = True
        assert args == expected_config
        return True

    #
    app.allow_list.run_command = lambda cmd: (0, "", "")
    #
    cfg_mgr = MagicMock()
    cfg_mgr.update.return_value = None
    cfg_mgr.push_list = push_list
    cfg_mgr.get_text.return_value = currect_config
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }

    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    if op == "SET":
        mgr.set_handler(*args)
    elif op == "DEL":
        mgr.del_handler(*args)
    else:
        assert False, "Wrong operation"
    if expected_config:
        assert set_del_test.push_list_called, "cfg_mgr.push_list wasn't called"
    else:
        assert not set_del_test.push_list_called, "cfg_mgr.push_list was called"
예제 #3
0
def run_tests(test_name, template_fname, tests):
    tf = TemplateFabric(TEMPLATE_PATH)
    template = tf.from_file(template_fname)
    for case_name, param_fname, result_fname in tests:
        params = load_json(param_fname)
        raw_generated_result = str(template.render(params))
        assert "None" not in raw_generated_result, "Test %s.%s" % (test_name,
                                                                   case_name)
        # this is used only for initial generation write_result(result_fname, raw_generated_result)
        canonical_generated_result = ConfigMgr.to_canonical(
            raw_generated_result)
        with open(result_fname) as result_fp:
            raw_saved_result = result_fp.read()
        canonical_saved_result = ConfigMgr.to_canonical(raw_saved_result)
        assert canonical_saved_result == canonical_generated_result, "Test %s.%s" % (
            test_name, case_name)
예제 #4
0
def test_set_handler_no_community_data_is_already_presented():
    from app.allow_list import BGPAllowListMgr
    cfg_mgr = MagicMock()
    cfg_mgr.update.return_value = None
    cfg_mgr.get_text.return_value = [
        'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 10 deny 0.0.0.0/0 le 17',
        'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 20 permit 20.20.30.0/24 ge 25',
        'ip prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4 seq 30 permit 40.50.0.0/16 ge 17',
        'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 10 deny 0::/0 le 59',
        'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 20 deny 0::/0 ge 65',
        'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 30 permit fc01:20::/64 ge 65',
        'ipv6 prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6 seq 40 permit fc01:30::/64 ge 65',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V4 permit 30000',
        ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V4',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_5_V6 permit 30000',
        ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_5_COMMUNITY_empty_V6',
        ""
    ]
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }
    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    mgr.set_handler(
        "DEPLOYMENT_ID|5", {
            "prefixes_v4": "20.20.30.0/24,40.50.0.0/16",
            "prefixes_v6": "fc01:20::/64,fc01:30::/64",
        })
    assert not cfg_mgr.push_list.called, "cfg_mgr.push_list was called, but it shouldn't have been"
예제 #5
0
def test___set_handler_validate():
    from app.allow_list import BGPAllowListMgr
    cfg_mgr = MagicMock()
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }
    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    data = {
        "prefixes_v4": "20.20.30.0/24,40.50.0.0/16",
        "prefixes_v6": "fc01:20::/64,fc01:30::/64",
    }
    assert not mgr._BGPAllowListMgr__set_handler_validate(
        "DEPLOYMENT_ID|5|1010:2020", None)
    assert not mgr._BGPAllowListMgr__set_handler_validate(
        "DEPLOYMENT_ID1|5|1010:2020", data)
    assert not mgr._BGPAllowListMgr__set_handler_validate(
        "DEPLOYMENT_ID|z|1010:2020", data)
    assert not mgr._BGPAllowListMgr__set_handler_validate(
        "DEPLOYMENT_ID|5|1010:2020", {
            "prefixes_v4": "20.20.30.0/24,40.50.0.0/16",
            "prefixes_v6": "20.20.30.0/24,40.50.0.0/16",
        })
    assert not mgr._BGPAllowListMgr__set_handler_validate(
        "DEPLOYMENT_ID|5|1010:2020", {
            "prefixes_v4": "fc01:20::/64,fc01:30::/64",
            "prefixes_v6": "fc01:20::/64,fc01:30::/64",
        })
예제 #6
0
def test_pfx_filter_wrong_ip(caplog):
    src = {
        ('Loopback0', 'wrong_ip'): {},
    }
    res = TemplateFabric.pfx_filter(src)
    assert "'wrong_ip' is invalid ip address" in caplog.text
    assert isinstance(res, OrderedDict) and len(res) == 0
예제 #7
0
def parse_instance_conf(filename):
    activate_re = re.compile(r'^neighbor\s+(\S+)\s+activate$')
    with open(filename) as fp:
        lines = [
            line.strip() for line in fp
            if not line.strip().startswith('!') and line.strip() != ''
        ]
    # Search all v6 neighbors
    neighbors = {}
    for line in lines:
        if activate_re.match(line):
            neighbor = activate_re.match(line).group(1)
            if TemplateFabric.is_ipv6(neighbor):
                neighbors[neighbor] = {}
    # Extract peer-groups and route-maps
    for neighbor, neighbor_data in neighbors.iteritems():
        route_map_in_re = re.compile(
            r'^neighbor\s+%s\s+route-map\s+(\S+) in$' % neighbor)
        peer_group_re = re.compile(r'^neighbor\s+%s\s+peer-group\s+(\S+)$' %
                                   neighbor)
        for line in lines:
            if route_map_in_re.match(line):
                assert "route-map" not in neighbor_data
                neighbor_data["route-map"] = route_map_in_re.match(line).group(
                    1)
            if peer_group_re.match(line):
                assert "peer-group" not in neighbor_data
                neighbor_data["peer-group"] = peer_group_re.match(line).group(
                    1)
    # Ensure that every ivp6 neighbor has either route-map or peer-group
    for neighbor, neighbor_data in neighbors.iteritems():
        assert "route-map" in neighbor_data or "peer-group" in neighbor_data,\
            "IPv6 neighbor '%s' must have either route-map in or peer-group %s" % (neighbor, neighbor_data)
    return neighbors
예제 #8
0
def test_pfx_filter_strings():
    src = {
        'Loopback0': {},
        'Loopback1': {},
    }
    expected = OrderedDict([])
    res = TemplateFabric.pfx_filter(src)
    assert res == expected
예제 #9
0
 def __set_handler_validate(self, key, data):
     """
     Validate parameters of a "Set" message
     :param key: ket of the 'SET' message
     :param data: data of the 'SET' message
     :return: True if parameters are valid, False if parameters are invalid
     """
     if data is None:
         log_err(
             "BGPAllowListMgr::Received BGP ALLOWED 'SET' message without data"
         )
         return False
     if not self.key_re.match(key):
         log_err(
             "BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid key: '%s'"
             % key)
         return False
     prefixes_v4 = []
     prefixes_v6 = []
     if "prefixes_v4" in data:
         prefixes_v4 = str(data["prefixes_v4"]).split(",")
         if not all(
                 TemplateFabric.is_ipv4(prefix) for prefix in prefixes_v4):
             arguments = "prefixes_v4", str(data["prefixes_v4"])
             log_err(
                 "BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'"
                 % arguments)
             return False
     if "prefixes_v6" in data:
         prefixes_v6 = str(data["prefixes_v6"]).split(",")
         if not all(
                 TemplateFabric.is_ipv6(prefix) for prefix in prefixes_v6):
             arguments = "prefixes_v6", str(data["prefixes_v6"])
             log_err(
                 "BGPAllowListMgr::Received BGP ALLOWED 'SET' message with invalid input[%s]:'%s'"
                 % arguments)
             return False
     if not prefixes_v4 and not prefixes_v6:
         log_err(
             "BGPAllowListMgr::Received BGP ALLOWED 'SET' message with no prefixes specified: %s"
             % str(data))
         return False
     return True
예제 #10
0
def test_pfx_filter_pfx_v4_no_mask():
    src = {
        ('Loopback0', '11.11.11.11'): {},
        ('Loopback1', '55.55.55.55'): {},
    }
    expected = OrderedDict([
        (('Loopback1', '55.55.55.55/32'), {}),
        (('Loopback0', '11.11.11.11/32'), {}),
    ])
    res = TemplateFabric.pfx_filter(src)
    assert res == expected
예제 #11
0
def test_pfx_filter_pfx_v6_no_mask():
    src = {
        ('Loopback0', 'fc00::'): {},
        ('Loopback1', 'fc00::1'): {},
    }
    expected = OrderedDict([
        (('Loopback0', 'fc00::/128'), {}),
        (('Loopback1', 'fc00::1/128'), {}),
    ])
    res = TemplateFabric.pfx_filter(src)
    assert res == expected
예제 #12
0
def test_pfx_filter_mixed_keys():
    src = {
        'Loopback0': {},
        ('Loopback0', '11.11.11.11/32'): {},
        'Loopback1': {},
        ('Loopback1', '55.55.55.55/32'): {},
    }
    expected = OrderedDict([
        (('Loopback1', '55.55.55.55/32'), {}),
        (('Loopback0', '11.11.11.11/32'), {}),
    ])
    res = TemplateFabric.pfx_filter(src)
    assert res == expected
예제 #13
0
def test___restart_peers_not_found_deployment_id():
    def run_command(cmd):
        assert cmd == ['vtysh', '-c', 'clear bgp * soft in']
        return 0, "", ""

    cfg_mgr = MagicMock()
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }
    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    mocked = MagicMock(
        name='_BGPAllowListMgr__find_peer_group_by_deployment_id')
    mocked.return_value = []
    mgr._BGPAllowListMgr__find_peer_group_by_deployment_id = mocked
    app.allow_list.run_command = run_command
    rc = mgr._BGPAllowListMgr__restart_peers(5)
    assert rc
예제 #14
0
def test_pfx_filter_pfx_comprehensive():
    src = {
        'Loopback0': {},
        ('Loopback0', 'fc00::'): {},
        'Loopback1': {},
        ('Loopback1', 'fc00::1/128'): {},
        ('Loopback2', '11.11.11.11/32'): {},
        ('Loopback3', '55.55.55.55'): {},
        'Loopback2': {},
        'Loopback3': {},
        ('Loopback5', '22.22.22.1/24'): {},
        ('Loopback6', 'fc00::55/64'): {},
    }
    expected = OrderedDict([
        (('Loopback1', 'fc00::1/128'), {}),
        (('Loopback3', '55.55.55.55/32'), {}),
        (('Loopback6', 'fc00::55/64'), {}),
        (('Loopback2', '11.11.11.11/32'), {}),
        (('Loopback0', 'fc00::/128'), {}),
        (('Loopback5', '22.22.22.1/24'), {}),
    ])
    res = TemplateFabric.pfx_filter(src)
    assert res == expected
예제 #15
0
def test___find_peer_group_by_deployment_id():
    from app.allow_list import BGPAllowListMgr
    cfg_mgr = MagicMock()
    cfg_mgr.update.return_value = None
    cfg_mgr.get_text.return_value = [
        'router bgp 64601',
        ' neighbor BGPSLBPassive peer-group',
        ' neighbor BGPSLBPassive remote-as 65432',
        ' neighbor BGPSLBPassive passive',
        ' neighbor BGPSLBPassive ebgp-multihop 255',
        ' neighbor BGPSLBPassive update-source 10.1.0.32',
        ' neighbor PEER_V4 peer-group',
        ' neighbor PEER_V4_INT peer-group',
        ' neighbor PEER_V6 peer-group',
        ' neighbor PEER_V6_INT peer-group',
        ' neighbor 10.0.0.1 remote-as 64802',
        ' neighbor 10.0.0.1 peer-group PEER_V4',
        ' neighbor 10.0.0.1 description ARISTA01T1',
        ' neighbor 10.0.0.1 timers 3 10',
        ' neighbor fc00::2 remote-as 64802',
        ' neighbor fc00::2 peer-group PEER_V6',
        ' neighbor fc00::2 description ARISTA01T1',
        ' neighbor fc00::2 timers 3 10',
        ' address-family ipv4 unicast',
        '  neighbor BGPSLBPassive activate',
        '  neighbor BGPSLBPassive soft-reconfiguration inbound',
        '  neighbor BGPSLBPassive route-map FROM_BGP_SPEAKER in',
        '  neighbor BGPSLBPassive route-map TO_BGP_SPEAKER out',
        '  neighbor PEER_V4 soft-reconfiguration inbound',
        '  neighbor PEER_V4 allowas-in 1',
        '  neighbor PEER_V4 route-map FROM_BGP_PEER_V4 in',
        '  neighbor PEER_V4 route-map TO_BGP_PEER_V4 out',
        '  neighbor PEER_V4_INT soft-reconfiguration inbound',
        '  neighbor PEER_V4_INT allowas-in 1',
        '  neighbor PEER_V4_INT route-map FROM_BGP_PEER_V4 in',
        '  neighbor PEER_V4_INT route-map TO_BGP_PEER_V4 out',
        '  neighbor 10.0.0.1 activate',
        ' exit-address-family',
        ' address-family ipv6 unicast',
        '  neighbor BGPSLBPassive activate',
        '  neighbor PEER_V6 soft-reconfiguration inbound',
        '  neighbor PEER_V6 allowas-in 1',
        '  neighbor PEER_V6 route-map FROM_BGP_PEER_V6 in',
        '  neighbor PEER_V6 route-map TO_BGP_PEER_V6 out',
        '  neighbor PEER_V6_INT soft-reconfiguration inbound',
        '  neighbor PEER_V6_INT allowas-in 1',
        '  neighbor PEER_V6_INT route-map FROM_BGP_PEER_V6 in',
        '  neighbor PEER_V6_INT route-map TO_BGP_PEER_V6 out',
        '  neighbor fc00::2 activate',
        ' exit-address-family',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 10',
        ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010',
        ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V4',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 30000',
        ' match ip address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V4',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V4 permit 65535',
        ' set community 5060:12345 additive',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 10',
        ' match community COMMUNITY_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010',
        ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_1010:1010_V6',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 30000',
        ' match ipv6 address prefix-list PL_ALLOW_LIST_DEPLOYMENT_ID_0_COMMUNITY_empty_V6',
        'route-map ALLOW_LIST_DEPLOYMENT_ID_0_V6 permit 65535',
        ' set community 5060:12345 additive',
        'route-map FROM_BGP_PEER_V4 permit 100',
        'route-map FROM_BGP_PEER_V4 permit 2',
        ' call ALLOW_LIST_DEPLOYMENT_ID_0_V4',
        ' on-match next',
        'route-map FROM_BGP_PEER_V6 permit 1',
        ' set ipv6 next-hop prefer-global ',
        'route-map FROM_BGP_PEER_V6 permit 100',
        'route-map FROM_BGP_PEER_V6 permit 2',
        ' call ALLOW_LIST_DEPLOYMENT_ID_0_V6',
        ' on-match next',
        'route-map FROM_BGP_SPEAKER permit 10',
        'route-map RM_SET_SRC permit 10',
        ' set src 10.1.0.32',
        'route-map RM_SET_SRC6 permit 10',
        ' set src FC00:1::32',
        'route-map TO_BGP_PEER_V4 permit 100',
        'route-map TO_BGP_PEER_V6 permit 100',
        'route-map TO_BGP_SPEAKER deny 1',
    ]
    common_objs = {
        'directory': Directory(),
        'cfg_mgr': cfg_mgr,
        'tf': TemplateFabric(),
        'constants': global_constants,
    }
    mgr = BGPAllowListMgr(common_objs, "CONFIG_DB", "BGP_ALLOWED_PREFIXES")
    values = mgr._BGPAllowListMgr__find_peer_group_by_deployment_id(0)
    assert values == ['PEER_V4_INT', 'PEER_V6_INT', 'PEER_V6', 'PEER_V4']
예제 #16
0
def test_pfx_filter_empty_dict():
    res = TemplateFabric.pfx_filter({})
    assert isinstance(res, OrderedDict) and len(res) == 0
예제 #17
0
def test_pfx_filter_none():
    res = TemplateFabric.pfx_filter(None)
    assert isinstance(res, OrderedDict) and len(res) == 0