Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 38 additions & 2 deletions aci-preupgrade-validation-script.py
Original file line number Diff line number Diff line change
Expand Up @@ -6293,7 +6293,42 @@ def multipod_modular_spine_bootscript_check(tversion, fabric_nodes, username, pa
return Result(result=result, headers=headers, data=data, recommended_action=recommended_action, doc_url=doc_url)


# ---- Script Execution ----
@check_wrapper(check_title='BGP Timer Policy Already Existing (F0467 bgpProt-policy-already-existing)')
def bgpProto_timer_policy_already_existing_check(tversion, **kwargs):
result = FAIL_O
headers = ['Fault', 'Tenant', 'L3Out', 'changeSet']
data = []
unformatted_headers = ['Fault', 'Affected', 'changeSet']
unformatted_data = []
recommended_action = 'Remove the fault by keeping Single bgp timer policy per vrf for different l3out.'
doc_url = 'https://datacenter.github.io/ACI-Pre-Upgrade-Validation-Script/validations/#bgpProto-timer-policy-already-existing'

if tversion.newer_than("6.2(1g)") or (
tversion.major1 == "6" and tversion.major2 == "1" and tversion.newer_than("6.1(5e)")):
return Result(result=NA, msg=VER_NOT_AFFECTED)

affected_regex = r'uni/tn-(?P<tenant>[^/]+)/out-(?P<l3out>[^\]]+)'
filter = 'faultDelegate.json?query-target-filter=and(eq(faultDelegate.code,"F0467"),wcard(faultDelegate.changeSet,"bgpProt-policy-already-existing"))'
fault_delegates = icurl('class', filter)

for fault_delegate in fault_delegates:
attributes = fault_delegate['faultDelegate']['attributes']
fault_code = attributes.get('code', '')
affected = attributes.get('affected', '')
change_set = attributes.get('changeSet', '')
affected_array = re.search(affected_regex, affected)
if affected_array:
data.append([fault_code, affected_array.group('tenant'), affected_array.group('l3out'), change_set])
else:
unformatted_data.append([fault_code, affected, change_set])

if not data and not unformatted_data:
result = PASS

return Result(result=result, headers=headers, data=data, unformatted_headers=unformatted_headers, unformatted_data=unformatted_data, recommended_action=recommended_action, doc_url=doc_url)


# ---- Script Execution ----.


def parse_args(args):
Expand Down Expand Up @@ -6461,7 +6496,8 @@ class CheckManager:
configpush_shard_check,
auto_firmware_update_on_switch_check,
rogue_ep_coop_exception_mac_check,
n9k_c9408_model_lem_count_check,
n9k_c9408_model_lem_count_check,
bgpProto_timer_policy_already_existing_check,
]
ssh_checks = [
# General
Expand Down
8 changes: 8 additions & 0 deletions docs/docs/validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ Items | Faults | This Script
[f21]: #vmm-inventory-partially-synced
[f22]: #apic-storage-inode-usage


### Configuration Checks

Items | This Script | APIC built-in
Expand Down Expand Up @@ -198,6 +199,7 @@ Items | Defect | This Script
[Rogue EP Exception List missing on switches][d30] | CSCwp64296 | :white_check_mark: | :no_entry_sign:
[N9K-C9408 with more than 5 N9K-X9400-16W LEMs][d31] | CSCws82819 | :white_check_mark: | :no_entry_sign:
[Multi-Pod Modular Spine Bootscript File][d32] | CSCwr66848 | :white_check_mark: | :no_entry_sign:
[BgpProto timer policy already existing][d33] | CSCwt78235 | :white_check_mark: | :no_entry_sign:

[d1]: #ep-announce-compatibility
[d2]: #eventmgr-db-size-defect-susceptibility
Expand Down Expand Up @@ -231,6 +233,7 @@ Items | Defect | This Script
[d30]: #rogue-ep-exception-list-missing-on-switches
[d31]: #n9k-c9408-with-more-than-5-n9k-x9400-16w-lems
[d32]: #multi-pod-modular-spine-bootscript-file
[d33]: #bgpProto-timer-policy-already-existing

## General Check Details

Expand Down Expand Up @@ -2753,6 +2756,10 @@ This issue happens only when the target version is specifically 6.1(4h).
To avoid this issue, change the target version to another version. Or verify that the `bootscript` file exists in the bootflash of each modular spine switch prior to upgrading to 6.1(4h). If the file is missing, you have to do clean reboot on the impacted spine to ensure that `/bootflash/bootscript` gets created again. In case you already upgraded your spine and you are experiencing the traffic impact due to this issue, clean reboot of the spine will restore the traffic.


### BgpProto Timer Policy Already Existing

This bug [CSCwt78235][67] validates `F0467` faults where `changeSet` contains 'bgpProt-policy-already-existing'. The fault indicates conflicting BGP protocol timer policy under an L3Outs deployed in same vrf under same node. If this fault is not resolved, l3out will not be programmed properly in the leaf after the upgrade.

[0]: https://github.com/datacenter/ACI-Pre-Upgrade-Validation-Script
[1]: https://www.cisco.com/c/dam/en/us/td/docs/Website/datacenter/apicmatrix/index.html
[2]: https://www.cisco.com/c/en/us/support/switches/nexus-9000-series-switches/products-release-notes-list.html
Expand Down Expand Up @@ -2820,3 +2827,4 @@ To avoid this issue, change the target version to another version. Or verify tha
[64]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwp64296
[65]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCws82819
[66]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwr66848
[67]: https://bst.cloudapps.cisco.com/bugsearch/bug/CSCwt78235
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
[
{
"faultDelegate": {
"attributes": {
"affected": "resPolCont/rtdOutCont/rtdOutDef-[uni/tn-common/out-L3outY]/nwissues",
"code": "F0467",
"changeSet": "configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no"
}
}
},
{
"faultDelegate": {
"attributes": {
"affected": "resPolCont/rtdOutCont/rtdOutDef-[uni/tn-prod/out-L3outA]/nwissues",
"code": "F0467",
"changeSet": "configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
[
{
"faultDelegate": {
"attributes": {
"affected": "resPolCont/rtdOutCont/rtdOutDef-[uni/invalid]/nwissues",
"code": "F0467",
"changeSet": "configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no"
}
}
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import os
import pytest
import logging
import importlib
from helpers.utils import read_data

script = importlib.import_module("aci-preupgrade-validation-script")
log = logging.getLogger(__name__)
dir = os.path.dirname(os.path.abspath(__file__))
test_function = "bgpProto_timer_policy_already_existing_check"
# icurl queries
faultDelegates = 'faultDelegate.json?query-target-filter=and(eq(faultDelegate.code,"F0467"),wcard(faultDelegate.changeSet,"bgpProt-policy-already-existing"))'

@pytest.mark.parametrize(
"icurl_outputs, tversion, expected_result, expected_data, expected_unformatted_data",
[
# target release not affected (> 6.2(1g))
(
{faultDelegates: read_data(dir, "faultDelegate_POS.json")},
"6.2(2a)",
script.NA,
[],
[],
),
# target release not affected on 6.1 train (> 6.1(5e))
(
{faultDelegates: read_data(dir, "faultDelegate_POS.json")},
"6.1(5f)",
script.NA,
[],
[],
),
# boundary version is still affected for strict newer_than check
(
{faultDelegates: read_data(dir, "faultDelegate_POS.json")},
"6.2(1g)",
script.FAIL_O,
[
[
"F0467",
"common",
"L3outY",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
[
"F0467",
"prod",
"L3outA",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
],
[],
),
# 6.1 boundary version is still affected for strict newer_than check
(
{faultDelegates: read_data(dir, "faultDelegate_POS.json")},
"6.1(5e)",
script.FAIL_O,
[
[
"F0467",
"common",
"L3outY",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
[
"F0467",
"prod",
"L3outA",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
],
[],
),
# target release affected on 6.1 train (< 6.1(5e))
(
{faultDelegates: read_data(dir, "faultDelegate_POS.json")},
"6.1(5a)",
script.FAIL_O,
[
[
"F0467",
"common",
"L3outY",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
[
"F0467",
"prod",
"L3outA",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
],
[],
),
(
{faultDelegates: read_data(dir, "faultDelegate_UNFORMATTED.json")},
"6.1(5a)",
script.FAIL_O,
[],
[
[
"F0467",
"resPolCont/rtdOutCont/rtdOutDef-[uni/invalid]/nwissues",
"configQual:bgpProt-policy-already-existing, configSt:failed-to-apply, temporaryError:no",
],
],
),
(
{faultDelegates: read_data(dir, "faultDelegate_NEG.json")},
"6.1(5a)",
script.PASS,
[],
[],
),
],
)
def test_logic(run_check, mock_icurl, tversion, expected_result, expected_data, expected_unformatted_data):
result = run_check(tversion=script.AciVersion(tversion))
assert result.result == expected_result
assert result.data == expected_data
assert result.unformatted_data == expected_unformatted_data