diff --git a/cmake/CliFboss2.cmake b/cmake/CliFboss2.cmake index 1c7b1346f9387..6e79d50bb6cef 100644 --- a/cmake/CliFboss2.cmake +++ b/cmake/CliFboss2.cmake @@ -867,122 +867,31 @@ add_library(fboss2_config_lib fboss/cli/fboss2/commands/config/mac/aging_time/CmdConfigMacAgingTime.h fboss/cli/fboss2/commands/config/protocol/CmdConfigProtocol.cpp fboss/cli/fboss2/commands/config/protocol/CmdConfigProtocol.h + fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h + fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h + fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.cpp fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.cpp fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h + fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.cpp - fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h + fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp + fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h fboss/cli/fboss2/commands/config/ptp/CmdConfigPtp.cpp fboss/cli/fboss2/commands/config/ptp/CmdConfigPtp.h fboss/cli/fboss2/commands/config/ptp/transparent_clock/CmdConfigPtpTransparentClock.cpp @@ -1075,6 +984,18 @@ add_library(fboss2_config_lib fboss/cli/fboss2/commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.cpp fboss/cli/fboss2/commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.h fboss/cli/fboss2/commands/delete/protocol/CmdDeleteProtocol.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h + fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h + fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp + fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h fboss/cli/fboss2/commands/delete/protocol/CmdDeleteProtocol.h fboss/cli/fboss2/commands/delete/protocol/static/CmdDeleteProtocolStatic.cpp fboss/cli/fboss2/commands/delete/protocol/static/CmdDeleteProtocolStatic.h diff --git a/cmake/CliFboss2TestConfig.cmake b/cmake/CliFboss2TestConfig.cmake index ef750533b3817..c75a9f9e54c10 100644 --- a/cmake/CliFboss2TestConfig.cmake +++ b/cmake/CliFboss2TestConfig.cmake @@ -9,6 +9,10 @@ add_executable(fboss2_cmd_config_test fboss/cli/fboss2/test/config/CmdConfigAclRuleTest.cpp fboss/cli/fboss2/test/config/CmdConfigArpTest.cpp fboss/cli/fboss2/test/config/CmdConfigIcmpV4UnavailableSrcAddrTest.cpp + fboss/cli/fboss2/test/config/CmdConfigBgpNeighborTest.cpp + fboss/cli/fboss2/test/config/CmdConfigBgpPeerGroupTest.cpp + fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListTest.cpp + fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListTest.cpp fboss/cli/fboss2/test/config/CmdConfigCoppTest.cpp fboss/cli/fboss2/test/config/CmdConfigDhcpTest.cpp fboss/cli/fboss2/test/config/CmdConfigHostnameTest.cpp @@ -38,6 +42,10 @@ add_executable(fboss2_cmd_config_test fboss/cli/fboss2/test/config/CmdConfigVlanStaticMacTest.cpp fboss/cli/fboss2/test/config/CmdDeleteAclRuleTest.cpp fboss/cli/fboss2/test/config/CmdDeleteArpTest.cpp + fboss/cli/fboss2/test/config/CmdDeleteBgpNeighborTest.cpp + fboss/cli/fboss2/test/config/CmdDeleteBgpPeerGroupTest.cpp + fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyAsPathListTest.cpp + fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyCommunityListTest.cpp fboss/cli/fboss2/test/config/CmdDeleteConfigInterfaceTest.cpp fboss/cli/fboss2/test/config/CmdDeleteDhcpTest.cpp fboss/cli/fboss2/test/config/CmdDeleteInterfaceIpv6NdpTest.cpp diff --git a/cmake/CliFboss2TestIntegrationTest.cmake b/cmake/CliFboss2TestIntegrationTest.cmake index 1873293ac8710..7f7c609e11118 100644 --- a/cmake/CliFboss2TestIntegrationTest.cmake +++ b/cmake/CliFboss2TestIntegrationTest.cmake @@ -11,6 +11,11 @@ add_executable(fboss2_integration_test fboss/cli/fboss2/test/integration_test/ConfigAdminDistanceTest.cpp fboss/cli/fboss2/test/integration_test/ConfigAclRuleTest.cpp fboss/cli/fboss2/test/integration_test/ConfigArpTest.cpp + fboss/cli/fboss2/test/integration_test/ConfigBgpGlobalTest.cpp + fboss/cli/fboss2/test/integration_test/ConfigBgpNeighborTest.cpp + fboss/cli/fboss2/test/integration_test/ConfigBgpPeerGroupTest.cpp + fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListTest.cpp + fboss/cli/fboss2/test/integration_test/ConfigBgpSessionTest.cpp fboss/cli/fboss2/test/integration_test/ConfigConcurrentSessionsTest.cpp fboss/cli/fboss2/test/integration_test/ConfigHostnameTest.cpp fboss/cli/fboss2/test/integration_test/ConfigIcmpV4UnavailableSrcAddrTest.cpp diff --git a/fboss/cli/fboss2/BUCK b/fboss/cli/fboss2/BUCK index d6a3f85f4b94c..8a76e7765f62d 100644 --- a/fboss/cli/fboss2/BUCK +++ b/fboss/cli/fboss2/BUCK @@ -1098,61 +1098,13 @@ cpp_library( "commands/config/protocol/bgp/BgpConfigSession.cpp", "commands/config/protocol/bgp/CmdConfigProtocolBgp.cpp", "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.cpp", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.cpp", + "commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp", "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.cpp", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.cpp", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.cpp", + "commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp", + "commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp", + "commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp", + "commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp", + "commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp", "commands/config/protocol/static/CmdConfigProtocolStatic.cpp", "commands/config/protocol/static/route/add/CmdConfigProtocolStaticRouteAdd.cpp", "commands/config/ptp/CmdConfigPtp.cpp", @@ -1199,6 +1151,12 @@ cpp_library( "commands/delete/interface/ipv6/CmdDeleteInterfaceIpv6.cpp", "commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.cpp", "commands/delete/protocol/CmdDeleteProtocol.cpp", + "commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp", + "commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp", + "commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp", + "commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp", + "commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp", + "commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp", "commands/delete/protocol/static/CmdDeleteProtocolStatic.cpp", "commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.cpp", "commands/delete/qos/CmdDeleteQos.cpp", @@ -1249,47 +1207,21 @@ cpp_library( "commands/config/mac/CmdConfigMac.h", "commands/config/mac/aging_time/CmdConfigMacAgingTime.h", "commands/config/protocol/CmdConfigProtocol.h", + "commands/config/protocol/bgp/BgpCliAttrHandlers.h", + "commands/config/protocol/bgp/BgpCliValueParsers.h", + "commands/config/protocol/bgp/BgpPeerAddr.h", "commands/config/protocol/bgp/BgpConfigSession.h", "commands/config/protocol/bgp/CmdConfigProtocolBgp.h", "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h", - "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h", + "commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h", "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h", - "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h", - "commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h", + "commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h", + "commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h", + "commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h", + "commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h", + "commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h", + "commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h", + "commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h", "commands/config/protocol/static/CmdConfigProtocolStatic.h", "commands/config/protocol/static/route/StaticRouteUtils.h", "commands/config/protocol/static/route/add/CmdConfigProtocolStaticRouteAdd.h", @@ -1337,6 +1269,12 @@ cpp_library( "commands/delete/interface/ipv6/CmdDeleteInterfaceIpv6.h", "commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.h", "commands/delete/protocol/CmdDeleteProtocol.h", + "commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h", + "commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h", + "commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h", + "commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h", + "commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h", + "commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h", "commands/delete/protocol/static/CmdDeleteProtocolStatic.h", "commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.h", "commands/delete/qos/CmdDeleteQos.h", diff --git a/fboss/cli/fboss2/BUILD.bazel b/fboss/cli/fboss2/BUILD.bazel new file mode 100644 index 0000000000000..f8860d382b7a0 --- /dev/null +++ b/fboss/cli/fboss2/BUILD.bazel @@ -0,0 +1,1115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") +load(":fboss2_config_impl.bzl", "fboss2_config_impl") + +cc_binary( + name = "fboss2", + srcs = ["Main.cpp"], + deps = [ + ":cmd-init-utils", + ":cmd-list-header", + ":fboss2-lib", + "@CLI11//:CLI11", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_binary( + name = "fboss2-dev", + srcs = ["Main.cpp"], + deps = [ + "//fboss/cli/fboss2:cmd-list-config-impl-oss", + ":cmd-init-utils", + ":cmd-list-header", + ":fboss2-config-lib", + ":fboss2-lib", + "@CLI11//:CLI11", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +fboss_thrift_library( + name = "cli", + thrift_srcs = ["cli.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +fboss_thrift_library( + name = "cli_metadata", + thrift_srcs = ["cli_metadata.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-list-header", + hdrs = [ + "CmdList.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + ":cmd-common-utils", + ":cmd-global-options", + "@CLI11//:CLI11", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-global-options", + srcs = ["CmdGlobalOptions.cpp"], + hdrs = [ + "CmdGlobalOptions.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + ":cli", + ":ops-utils", + ":options", + "@CLI11//:CLI11", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-local-options", + srcs = ["CmdLocalOptions.cpp"], + hdrs = [ + "CmdLocalOptions.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + ":cmd-common-utils", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-subcommands", + srcs = [ + "CmdArgsLists.cpp", + "CmdSubcommands.cpp", + ], + hdrs = [ + "CliAppInit.h", + "CmdArgsLists.h", + "CmdSubcommands.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + ], + deps = [ + ":cli-parser-utils", + ":cmd-common-utils", + ":cmd-list-header", + ":cmd-local-options", + "@CLI11//:CLI11", + "@fmt//:fmt", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-init-utils", + srcs = [ + "utils/CmdInitUtils.cpp", + "utils/oss/CmdInitUtils.cpp", + ], + hdrs = [ + "utils/CmdInitUtils.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/InterfaceList.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = [ + ":cmd-global-options", + ":cmd-list-header", + ":cmd-subcommands", + "@CLI11//:CLI11", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-handler", + hdrs = [ + "CmdHandler.cpp", + "CmdHandler.h", + "CmdStreamHandler.cpp", + "CmdStreamHandler.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdSubcommands.h", + ], + deps = [ + ":cli", + ":cmd-common-utils", + ":cmd-global-options", + ":cmd-subcommands", + ":ops-utils", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "options", + hdrs = [ + "options/OutputFormat.h", + "options/SSLPolicy.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + "@CLI11//:CLI11", + "@fmt//:fmt", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "ops-utils", + hdrs = [ + "utils/AggregateOp.h", + "utils/FilterOp.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = ["@folly//:folly"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cli-parser-utils", + srcs = ["utils/CLIParserUtils.cpp"], + hdrs = [ + "utils/CLIParserUtils.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdInitUtils.h", + "utils/CmdUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/InterfaceList.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = ["@CLI11//:CLI11"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-common-utils", + srcs = ["utils/CmdUtilsCommon.cpp"], + hdrs = [ + "commands/clear/CmdClearUtils.h", + "utils/AggregateUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdUtilsCommon.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdInitUtils.h", + "utils/CmdUtils.h", + "utils/FilterOp.h", + "utils/InterfaceList.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = [ + "//fboss/agent/if:ctrl", + ":cmd-global-options", + "@CLI11//:CLI11", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "safety-prompt-utils", + srcs = ["utils/SafetyPromptUtils.cpp"], + hdrs = [ + "utils/SafetyPromptUtils.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdInitUtils.h", + "utils/CmdUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/InterfaceList.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = [ + ":cmd-local-options", + "@fmt//:fmt", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "table-utils", + srcs = ["utils/Table.cpp"], + hdrs = [ + "utils/Table.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdInitUtils.h", + "utils/CmdUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/InterfaceList.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/TeFlowUtils.h", + ], + deps = [ + ":cmd-global-options", + "@tabulate//:tabulate", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd-show-utils", + hdrs = [ + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + ":cmd-common-utils", + ":cmd-handler", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "commands-show-bgp", + hdrs = [ + "commands/show/bgp/CanonicalRibResolver.h", + "commands/show/bgp/CmdShowBgpInitializationEvents.h", + "commands/show/bgp/CmdShowBgpOriginatedRoutes.h", + "commands/show/bgp/CmdShowUtils.h", + "commands/show/bgp/CmdShowVersionBgp.h", + "commands/show/bgp/changelist/CmdShowBgpChangelist.h", + "commands/show/bgp/config/CmdShowConfigRunningBgp.h", + "commands/show/bgp/config/CmdShowConfigTraits.h", + "commands/show/bgp/health/CmdShowBgpHealth.h", + "commands/show/bgp/holdtimers/CmdShowBgpHoldTimers.h", + "commands/show/bgp/neighbors/CmdShowBgpNeighbors.h", + "commands/show/bgp/neighbors/advertised/BgpNeighborsAdvertisedDryRun.h", + "commands/show/bgp/neighbors/advertised/BgpNeighborsAdvertisedPostPolicy.h", + "commands/show/bgp/neighbors/advertised/BgpNeighborsAdvertisedPrePolicy.h", + "commands/show/bgp/neighbors/advertised/BgpNeighborsAdvertisedRejected.h", + "commands/show/bgp/neighbors/received/BgpNeighborsReceivedPostPolicy.h", + "commands/show/bgp/neighbors/received/BgpNeighborsReceivedPrePolicy.h", + "commands/show/bgp/neighbors/received/BgpNeighborsReceivedRejected.h", + "commands/show/bgp/neighbors/session_id/CmdBgpNeighborsSessionId.h", + "commands/show/bgp/neighbors_by_name/CmdShowBgpNeighborsByName.h", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejected.h", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejectedCrf.h", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejected.h", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejectedCrf.h", + "commands/show/bgp/nexthopinfo/CmdShowBgpNexthopInfo.h", + "commands/show/bgp/profiler/CmdShowBgpProfiler.h", + "commands/show/bgp/shadowrib/CmdShowBgpShadowRib.h", + "commands/show/bgp/stats/CmdShowBgpStatsAttrs.h", + "commands/show/bgp/stats/CmdShowBgpStatsEntries.h", + "commands/show/bgp/stats/CmdShowBgpStatsPolicy.h", + "commands/show/bgp/stream/CmdShowBgpStreamSubscriber.h", + "commands/show/bgp/stream/CmdShowBgpStreamSummary.h", + "commands/show/bgp/stream/subscriber/CmdShowBgpStreamSubscriberPostPolicy.h", + "commands/show/bgp/stream/subscriber/CmdShowBgpStreamSubscriberPrePolicy.h", + "oss/NetTools.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + ], + deps = [ + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/table:bgp_table_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//neteng/fboss/bgp/if:bgp_thrift", + ":cmd-common-utils", + ":cmd-handler", + ":table-utils", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "fboss2-lib", + srcs = [ + "CmdHandlerImplBgp.cpp", + "CmdList.cpp", + "CmdStreamHandlerImpl.cpp", + "commands/bounce/interface/CmdBounceInterface.cpp", + "commands/clear/CmdClearArp.cpp", + "commands/clear/CmdClearInterfaceCounters.cpp", + "commands/clear/CmdClearNdp.cpp", + "commands/clear/interface/CmdClearInterface.cpp", + "commands/clear/interface/counters/phy/CmdClearInterfaceCountersPhy.cpp", + "commands/clear/interface/prbs/CmdClearInterfacePrbs.cpp", + "commands/clear/interface/prbs/stats/CmdClearInterfacePrbsStats.cpp", + "commands/delete/config/CmdDeleteConfig.cpp", + "commands/get/pcap/CmdGetPcap.cpp", + "commands/set/fanhold/CmdSetFanHold.cpp", + "commands/set/interface/CmdSetInterface.cpp", + "commands/set/interface/prbs/CmdSetInterfacePrbs.cpp", + "commands/set/interface/prbs/state/CmdSetInterfacePrbsState.cpp", + "commands/set/port/CmdSetPort.cpp", + "commands/set/port/state/CmdSetPortState.cpp", + "commands/set/sdk/CmdSetSdk.cpp", + "commands/set/sdk/reg_dump/CmdSetSdkRegDump.cpp", + "commands/set/transceiver/CmdSetTransceiver.cpp", + "commands/set/transceiver/loopback/CmdSetTransceiverLoopback.cpp", + "commands/show/bgp/CanonicalRibResolver.cpp", + "commands/show/bgp/CmdShowBgpInitializationEvents.cpp", + "commands/show/bgp/CmdShowBgpOriginatedRoutes.cpp", + "commands/show/bgp/CmdShowUtils.cpp", + "commands/show/bgp/CmdShowVersionBgp.cpp", + "commands/show/bgp/changelist/CmdShowBgpChangelist.cpp", + "commands/show/bgp/health/CmdShowBgpHealth.cpp", + "commands/show/bgp/holdtimers/CmdShowBgpHoldTimers.cpp", + "commands/show/bgp/neighbors_by_name/CmdShowBgpNeighborsByName.cpp", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejected.cpp", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejectedCrf.cpp", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejected.cpp", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejectedCrf.cpp", + "commands/show/bgp/nexthopinfo/CmdShowBgpNexthopInfo.cpp", + "commands/show/bgp/shadowrib/CmdShowBgpShadowRib.cpp", + "commands/show/bgp/stats/CmdShowBgpStatsEntries.cpp", + "commands/show/bgp/stats/CmdShowBgpStatsPolicy.cpp", + "commands/show/config/CmdShowConfigHistoryAgent.cpp", + "commands/show/config/CmdShowConfigRunningAgent.cpp", + "commands/show/config/CmdShowConfigUtils.cpp", + "commands/show/dsf/CmdShowDsf.cpp", + "commands/show/environment/fan/CmdShowEnvironmentFan.cpp", + "commands/show/fsdb/CmdShowFsdbDataCommon.cpp", + "commands/show/fsdb/CmdShowFsdbPublishers.cpp", + "commands/show/fsdb/CmdShowFsdbSubscribers.cpp", + "commands/show/fsdb/CmdShowFsdbUtils.cpp", + "commands/show/hwobject/CmdShowHwObject.cpp", + "commands/show/hwobject/uncached/CmdShowHwObjectUncached.cpp", + "commands/show/l2/CmdShowL2.cpp", + "commands/show/sdk/dump/CmdShowSdkDump.cpp", + "commands/start/pcap/CmdStartPcap.cpp", + "commands/start/port/CmdStartPort.cpp", + "commands/start/port/cable_length_measurement/CmdStartPortCableLengthMeasurement.cpp", + "commands/stop/pcap/CmdStopPcap.cpp", + "utils/CmdClientUtils.cpp", + "utils/CmdUtils.cpp", + "utils/LoopbackUtils.cpp", + "utils/PortMap.cpp", + "utils/PrbsUtils.cpp", + "commands/show/bgp/profiler/CmdShowBgpProfiler.cpp", + "commands/show/bgp/policy/CmdShowBgpPolicy.cpp", + "utils/oss/CmdUtils.cpp", + "utils/oss/CmdClientUtils.cpp", + "oss/CmdShowUtils.cpp", + "oss/CmdListImpl.cpp", + "oss/CmdList.cpp", + "oss/CmdGlobalOptions.cpp", + "commands/show/bgp/config/CmdShowConfigRunningBgp.cpp", + ], + hdrs = [ + "commands/bounce/interface/CmdBounceInterface.h", + "commands/clear/CmdClearArp.h", + "commands/clear/CmdClearInterfaceCounters.h", + "commands/clear/CmdClearNdp.h", + "commands/clear/interface/CmdClearInterface.h", + "commands/clear/interface/counters/phy/CmdClearInterfaceCountersPhy.h", + "commands/clear/interface/prbs/CmdClearInterfacePrbs.h", + "commands/clear/interface/prbs/stats/CmdClearInterfacePrbsStats.h", + "commands/delete/config/CmdDeleteConfig.h", + "commands/get/pcap/CmdGetPcap.h", + "commands/help/CmdHelp.h", + "commands/set/fanhold/CmdSetFanHold.h", + "commands/set/interface/CmdSetInterface.h", + "commands/set/interface/prbs/CmdSetInterfacePrbs.h", + "commands/set/interface/prbs/state/CmdSetInterfacePrbsState.h", + "commands/set/port/CmdSetPort.h", + "commands/set/port/state/CmdSetPortState.h", + "commands/set/sdk/CmdSetSdk.h", + "commands/set/sdk/reg_dump/CmdSetSdkRegDump.h", + "commands/set/transceiver/CmdSetTransceiver.h", + "commands/set/transceiver/loopback/CmdSetTransceiverLoopback.h", + "commands/show/config/CmdShowConfigHistoryAgent.h", + "commands/show/config/CmdShowConfigRunningAgent.h", + "commands/show/config/CmdShowConfigTraits.h", + "commands/show/config/CmdShowConfigUtils.h", + "commands/show/dsf/CmdShowDsf.h", + "commands/show/environment/fan/CmdShowEnvironmentFan.h", + "commands/show/fsdb/CmdShowFsdbDataCommon.h", + "commands/show/fsdb/CmdShowFsdbOperState.h", + "commands/show/fsdb/CmdShowFsdbOperStats.h", + "commands/show/fsdb/CmdShowFsdbPublishers.h", + "commands/show/fsdb/CmdShowFsdbSubscribers.h", + "commands/show/fsdb/CmdShowFsdbUtils.h", + "commands/show/hwobject/CmdShowHwObject.h", + "commands/show/hwobject/uncached/CmdShowHwObjectUncached.h", + "commands/show/l2/CmdShowL2.h", + "commands/show/sdk/dump/CmdShowSdkDump.h", + "commands/start/pcap/CmdStartPcap.h", + "commands/start/port/CmdStartPort.h", + "commands/start/port/cable_length_measurement/CmdStartPortCableLengthMeasurement.h", + "commands/stop/pcap/CmdStopPcap.h", + "commands/stream/fsdb/CmdStreamSubFsdbOperState.h", + "commands/stream/fsdb/CmdStreamSubFsdbOperStats.h", + "utils/CmdUtils.h", + "utils/LoopbackUtils.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "commands/clear/CmdClearUtils.h", + "commands/show/bgp/CanonicalRibResolver.h", + "commands/show/bgp/CmdShowBgpInitializationEvents.h", + "commands/show/bgp/CmdShowBgpOriginatedRoutes.h", + "commands/show/bgp/CmdShowUtils.h", + "commands/show/bgp/CmdShowVersionBgp.h", + "commands/show/bgp/changelist/CmdShowBgpChangelist.h", + "commands/show/bgp/config/CmdShowConfigRunningBgp.h", + "commands/show/bgp/config/CmdShowConfigTraits.h", + "commands/show/bgp/health/CmdShowBgpHealth.h", + "commands/show/bgp/holdtimers/CmdShowBgpHoldTimers.h", + "commands/show/bgp/neighbors_by_name/CmdShowBgpNeighborsByName.h", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejected.h", + "commands/show/bgp/neighbors_by_name/advertised/BgpNeighborsByNameAdvertisedRejectedCrf.h", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejected.h", + "commands/show/bgp/neighbors_by_name/received/BgpNeighborsByNameReceivedRejectedCrf.h", + "commands/show/bgp/nexthopinfo/CmdShowBgpNexthopInfo.h", + "commands/show/bgp/policy/CmdShowBgpPolicy.h", + "commands/show/bgp/profiler/CmdShowBgpProfiler.h", + "commands/show/bgp/shadowrib/CmdShowBgpShadowRib.h", + "commands/show/bgp/stats/CmdShowBgpStatsAttrs.h", + "commands/show/bgp/stats/CmdShowBgpStatsEntries.h", + "commands/show/bgp/stats/CmdShowBgpStatsPolicy.h", + "oss/NetTools.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdInitUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/InterfaceList.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = [ + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + ":cli", + ":cmd-common-utils", + ":cmd-global-options", + ":cmd-handler", + ":cmd-local-options", + ":cmd-subcommands", + ":commands-show-bgp", + ":safety-prompt-utils", + ":table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + "//fboss/cli/fboss2/commands/show/acl:_impl", + "//fboss/cli/fboss2/commands/show/agent:_impl", + "//fboss/cli/fboss2/commands/show/aggregateport:_impl", + "//fboss/cli/fboss2/commands/show/arp:_impl", + "//fboss/cli/fboss2/commands/show/bgp/summary:_impl", + "//fboss/cli/fboss2/commands/show/bgp/table:_impl", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:_impl", + "//fboss/cli/fboss2/commands/show/cpuport:_impl", + "//fboss/cli/fboss2/commands/show/dsf/subscription:_impl", + "//fboss/cli/fboss2/commands/show/dsfnodes:_impl", + "//fboss/cli/fboss2/commands/show/example:_impl", + "//fboss/cli/fboss2/commands/show/fabric:_impl", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:_impl", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:_impl", + "//fboss/cli/fboss2/commands/show/fabric/reachability:_impl", + "//fboss/cli/fboss2/commands/show/fabric/topology:_impl", + "//fboss/cli/fboss2/commands/show/flowlet:_impl", + "//fboss/cli/fboss2/commands/show/hardware:_impl", + "//fboss/cli/fboss2/commands/show/host:_impl", + "//fboss/cli/fboss2/commands/show/hwagent:_impl", + "//fboss/cli/fboss2/commands/show/interface:_impl", + "//fboss/cli/fboss2/commands/show/interface/capabilities:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:_impl", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:_impl", + "//fboss/cli/fboss2/commands/show/interface/errors:_impl", + "//fboss/cli/fboss2/commands/show/interface/flaps:_impl", + "//fboss/cli/fboss2/commands/show/interface/phy:_impl", + "//fboss/cli/fboss2/commands/show/interface/phymap:_impl", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:_impl", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:_impl", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:_impl", + "//fboss/cli/fboss2/commands/show/interface/status:_impl", + "//fboss/cli/fboss2/commands/show/interface/traffic:_impl", + "//fboss/cli/fboss2/commands/show/lldp:_impl", + "//fboss/cli/fboss2/commands/show/mac:_impl", + "//fboss/cli/fboss2/commands/show/mirror:_impl", + "//fboss/cli/fboss2/commands/show/mpls:_impl", + "//fboss/cli/fboss2/commands/show/mysid:_impl", + "//fboss/cli/fboss2/commands/show/ndp:_impl", + "//fboss/cli/fboss2/commands/show/nexthopgroups:_impl", + "//fboss/cli/fboss2/commands/show/port:_impl", + "//fboss/cli/fboss2/commands/show/product:_impl", + "//fboss/cli/fboss2/commands/show/rif:_impl", + "//fboss/cli/fboss2/commands/show/route:_impl", + "//fboss/cli/fboss2/commands/show/systemport:_impl", + "//fboss/cli/fboss2/commands/show/teflow:_impl", + "//fboss/cli/fboss2/commands/show/transceiver:_impl", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "fboss2-config-lib", + srcs = [ + "CmdListConfig.cpp", + "commands/config/CmdConfigAppliedInfo.cpp", + "commands/config/CmdConfigReload.cpp", + "commands/config/acl/CmdConfigAcl.cpp", + "commands/config/acl/rule/AclRuleAttrs.cpp", + "commands/config/acl/rule/CmdConfigAclRule.cpp", + "commands/config/arp/CmdConfigArp.cpp", + "commands/config/copp/CmdConfigCopp.cpp", + "commands/config/dhcp/CmdConfigDhcp.cpp", + "commands/config/dhcp/relay_source_override/CmdConfigDhcpRelaySourceOverride.cpp", + "commands/config/dhcp/reply_source_override/CmdConfigDhcpReplySourceOverride.cpp", + "commands/config/history/CmdConfigHistory.cpp", + "commands/config/interface/CmdConfigInterface.cpp", + "commands/config/interface/CmdConfigInterfaceQueuingPolicy.cpp", + "commands/config/interface/ProfileValidation.cpp", + "commands/config/interface/ipv6/CmdConfigInterfaceIpv6.cpp", + "commands/config/interface/ipv6/ndp/CmdConfigInterfaceIpv6Ndp.cpp", + "commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.cpp", + "commands/config/interface/switchport/CmdConfigInterfaceSwitchport.cpp", + "commands/config/interface/switchport/access/CmdConfigInterfaceSwitchportAccess.cpp", + "commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.cpp", + "commands/config/interface/switchport/trunk/CmdConfigInterfaceSwitchportTrunk.cpp", + "commands/config/interface/switchport/trunk/allowed/CmdConfigInterfaceSwitchportTrunkAllowed.cpp", + "commands/config/interface/switchport/trunk/allowed/vlan/CmdConfigInterfaceSwitchportTrunkAllowedVlan.cpp", + "commands/config/l2/CmdConfigL2.cpp", + "commands/config/l2/learning_mode/CmdConfigL2LearningMode.cpp", + "commands/config/load_balancing/CmdConfigLoadBalancing.cpp", + "commands/config/mac/CmdConfigMac.cpp", + "commands/config/mac/aging_time/CmdConfigMacAgingTime.cpp", + "commands/config/protocol/CmdConfigProtocol.cpp", + "commands/config/protocol/bgp/BgpConfigSession.cpp", + "commands/config/protocol/bgp/CmdConfigProtocolBgp.cpp", + "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp", + "commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp", + "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp", + "commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp", + "commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp", + "commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp", + "commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp", + "commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp", + "commands/config/protocol/bgp/policy/prefix-list/CmdConfigProtocolBgpPolicyPrefixList.cpp", + "commands/config/protocol/bgp/policy/prefix-list/entry/CmdConfigProtocolBgpPolicyPrefixListEntry.cpp", + "commands/config/protocol/bgp/policy/routing-policy/CmdConfigProtocolBgpPolicyRoutingPolicy.cpp", + "commands/config/protocol/static/CmdConfigProtocolStatic.cpp", + "commands/config/protocol/static/route/add/CmdConfigProtocolStaticRouteAdd.cpp", + "commands/config/ptp/CmdConfigPtp.cpp", + "commands/config/ptp/transparent_clock/CmdConfigPtpTransparentClock.cpp", + "commands/config/qos/CmdConfigQos.cpp", + "commands/config/qos/buffer_pool/CmdConfigQosBufferPool.cpp", + "commands/config/qos/PortQueueConfigUtils.cpp", + "commands/config/qos/default_queue_config/CmdConfigQosDefaultQueueConfig.cpp", + "commands/config/qos/policy/CmdConfigQosPolicy.cpp", + "commands/config/qos/policy/CmdConfigQosPolicyMap.cpp", + "commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicy.cpp", + "commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.cpp", + "commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicy.cpp", + "commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.cpp", + "commands/config/rollback/CmdConfigRollback.cpp", + "commands/config/session/CmdConfigSessionClear.cpp", + "commands/config/session/CmdConfigSessionCommit.cpp", + "commands/config/session/CmdConfigSessionDiff.cpp", + "commands/config/session/CmdConfigSessionRebase.cpp", + "commands/config/switch/CmdConfigSwitch.cpp", + "commands/config/switch/admin_distance/CmdConfigAdminDistance.cpp", + "commands/config/switch/hostname/CmdConfigHostname.cpp", + "commands/config/switch/icmpv4_unavailable_src_addr/CmdConfigIcmpV4UnavailableSrcAddr.cpp", + "commands/config/tunnel/CmdConfigTunnel.cpp", + "commands/config/tunnel/ip_in_ip/CmdConfigTunnelIpInIp.cpp", + "commands/config/tunnel/ip_in_ip/TunnelIpInIpConfigUtils.cpp", + "commands/config/tunnel/ip_in_ip/decap/CmdConfigTunnelIpInIpDecap.cpp", + "commands/config/tunnel/ip_in_ip/encap/CmdConfigTunnelIpInIpEncap.cpp", + "commands/config/vlan/CmdConfigVlan.cpp", + "commands/config/vlan/CmdConfigVlanDefault.cpp", + "commands/config/vlan/VlanManager.cpp", + "commands/config/vlan/port/CmdConfigVlanPort.cpp", + "commands/config/vlan/port/tagging_mode/CmdConfigVlanPortTaggingMode.cpp", + "commands/config/vlan/static_mac/CmdConfigVlanStaticMac.cpp", + "commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.cpp", + "commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.cpp", + "commands/delete/acl/CmdDeleteAcl.cpp", + "commands/delete/acl/rule/CmdDeleteAclRule.cpp", + "commands/delete/arp/CmdDeleteArp.cpp", + "commands/delete/copp/CmdDeleteCopp.cpp", + "commands/delete/copp/cpu_traffic_policy/CmdDeleteCoppCpuTrafficPolicy.cpp", + "commands/delete/copp/cpu_traffic_policy/match/CmdDeleteCoppCpuTrafficPolicyMatch.cpp", + "commands/delete/copp/cpu_traffic_policy/match/action/CmdDeleteCoppCpuTrafficPolicyMatchAction.cpp", + "commands/delete/dhcp/CmdDeleteDhcp.cpp", + "commands/delete/dhcp/relay_source_override/CmdDeleteDhcpRelaySourceOverride.cpp", + "commands/delete/dhcp/reply_source_override/CmdDeleteDhcpReplySourceOverride.cpp", + "commands/delete/interface/CmdDeleteInterface.cpp", + "commands/delete/interface/ipv6/CmdDeleteInterfaceIpv6.cpp", + "commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.cpp", + "commands/delete/protocol/CmdDeleteProtocol.cpp", + "commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp", + "commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp", + "commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp", + "commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp", + "commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp", + "commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp", + "commands/delete/protocol/bgp/policy/prefix-list/CmdDeleteProtocolBgpPolicyPrefixList.cpp", + "commands/delete/protocol/bgp/policy/routing-policy/CmdDeleteProtocolBgpPolicyRoutingPolicy.cpp", + "commands/delete/protocol/static/CmdDeleteProtocolStatic.cpp", + "commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.cpp", + "commands/delete/qos/CmdDeleteQos.cpp", + "commands/delete/qos/default_queue_config/CmdDeleteQosDefaultQueueConfig.cpp", + "commands/delete/tunnel/CmdDeleteTunnel.cpp", + "commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.cpp", + "commands/delete/tunnel/ip_in_ip/TunnelIpInIpDeleteUtils.cpp", + "commands/delete/tunnel/ip_in_ip/decap/CmdDeleteTunnelIpInIpDecap.cpp", + "commands/delete/tunnel/ip_in_ip/encap/CmdDeleteTunnelIpInIpEncap.cpp", + "commands/delete/vlan/CmdDeleteVlan.cpp", + "session/ConfigSession.cpp", + "session/FbossServiceUtil.cpp", + "session/Git.cpp", + "session/SystemdInterface.cpp", + "utils/InterfaceList.cpp", + ], + hdrs = [ + "commands/config/CmdConfigAppliedInfo.h", + "commands/config/CmdConfigReload.h", + "commands/config/acl/CmdConfigAcl.h", + "commands/config/acl/rule/AclRuleAttrs.h", + "commands/config/acl/rule/CmdConfigAclRule.h", + "commands/config/arp/CmdConfigArp.h", + "commands/config/copp/CmdConfigCopp.h", + "commands/config/dhcp/CmdConfigDhcp.h", + "commands/config/dhcp/relay_source_override/CmdConfigDhcpRelaySourceOverride.h", + "commands/config/dhcp/reply_source_override/CmdConfigDhcpReplySourceOverride.h", + "commands/config/history/CmdConfigHistory.h", + "commands/config/interface/CmdConfigInterface.h", + "commands/config/interface/CmdConfigInterfaceQueuingPolicy.h", + "commands/config/interface/InterfaceAttrArgsBase.h", + "commands/config/interface/InterfaceIpUtils.h", + "commands/config/interface/ProfileValidation.h", + "commands/config/interface/ipv6/CmdConfigInterfaceIpv6.h", + "commands/config/interface/ipv6/ndp/CmdConfigInterfaceIpv6Ndp.h", + "commands/config/interface/pfc_config/CmdConfigInterfacePfcConfig.h", + "commands/config/interface/pfc_config/PfcConfigUtils.h", + "commands/config/interface/switchport/CmdConfigInterfaceSwitchport.h", + "commands/config/interface/switchport/access/CmdConfigInterfaceSwitchportAccess.h", + "commands/config/interface/switchport/access/vlan/CmdConfigInterfaceSwitchportAccessVlan.h", + "commands/config/interface/switchport/trunk/CmdConfigInterfaceSwitchportTrunk.h", + "commands/config/interface/switchport/trunk/allowed/CmdConfigInterfaceSwitchportTrunkAllowed.h", + "commands/config/interface/switchport/trunk/allowed/vlan/CmdConfigInterfaceSwitchportTrunkAllowedVlan.h", + "commands/config/l2/CmdConfigL2.h", + "commands/config/l2/learning_mode/CmdConfigL2LearningMode.h", + "commands/config/load_balancing/CmdConfigLoadBalancing.h", + "commands/config/mac/CmdConfigMac.h", + "commands/config/mac/aging_time/CmdConfigMacAgingTime.h", + "commands/config/protocol/CmdConfigProtocol.h", + "commands/config/protocol/bgp/BgpCliAttrHandlers.h", + "commands/config/protocol/bgp/BgpCliValueParsers.h", + "commands/config/protocol/bgp/BgpPeerAddr.h", + "commands/config/protocol/bgp/BgpConfigSession.h", + "commands/config/protocol/bgp/CmdConfigProtocolBgp.h", + "commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h", + "commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h", + "commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h", + "commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h", + "commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h", + "commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h", + "commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h", + "commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h", + "commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h", + "commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h", + "commands/config/protocol/bgp/policy/prefix-list/BgpPrefixListCliUtils.h", + "commands/config/protocol/bgp/policy/prefix-list/CmdConfigProtocolBgpPolicyPrefixList.h", + "commands/config/protocol/bgp/policy/prefix-list/entry/CmdConfigProtocolBgpPolicyPrefixListEntry.h", + "commands/config/protocol/bgp/policy/routing-policy/CmdConfigProtocolBgpPolicyRoutingPolicy.h", + "commands/config/protocol/static/CmdConfigProtocolStatic.h", + "commands/config/protocol/static/route/StaticRouteUtils.h", + "commands/config/protocol/static/route/add/CmdConfigProtocolStaticRouteAdd.h", + "commands/config/ptp/CmdConfigPtp.h", + "commands/config/ptp/transparent_clock/CmdConfigPtpTransparentClock.h", + "commands/config/qos/CmdConfigQos.h", + "commands/config/qos/buffer_pool/CmdConfigQosBufferPool.h", + "commands/config/qos/PortQueueConfigUtils.h", + "commands/config/qos/default_queue_config/CmdConfigQosDefaultQueueConfig.h", + "commands/config/qos/policy/CmdConfigQosPolicy.h", + "commands/config/qos/policy/CmdConfigQosPolicyMap.h", + "commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicy.h", + "commands/config/qos/priority_group_policy/CmdConfigQosPriorityGroupPolicyGroupId.h", + "commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicy.h", + "commands/config/qos/queuing_policy/CmdConfigQosQueuingPolicyQueueId.h", + "commands/config/rollback/CmdConfigRollback.h", + "commands/config/session/CmdConfigSessionClear.h", + "commands/config/session/CmdConfigSessionCommit.h", + "commands/config/session/CmdConfigSessionDiff.h", + "commands/config/session/CmdConfigSessionRebase.h", + "commands/config/switch/CmdConfigSwitch.h", + "commands/config/switch/admin_distance/CmdConfigAdminDistance.h", + "commands/config/switch/hostname/CmdConfigHostname.h", + "commands/config/switch/icmpv4_unavailable_src_addr/CmdConfigIcmpV4UnavailableSrcAddr.h", + "commands/config/tunnel/CmdConfigTunnel.h", + "commands/config/tunnel/ip_in_ip/CmdConfigTunnelIpInIp.h", + "commands/config/tunnel/ip_in_ip/TunnelIpInIpConfigUtils.h", + "commands/config/tunnel/ip_in_ip/decap/CmdConfigTunnelIpInIpDecap.h", + "commands/config/tunnel/ip_in_ip/encap/CmdConfigTunnelIpInIpEncap.h", + "commands/config/vlan/CmdConfigVlan.h", + "commands/config/vlan/CmdConfigVlanDefault.h", + "commands/config/vlan/VlanManager.h", + "commands/config/vlan/port/CmdConfigVlanPort.h", + "commands/config/vlan/port/tagging_mode/CmdConfigVlanPortTaggingMode.h", + "commands/config/vlan/static_mac/CmdConfigVlanStaticMac.h", + "commands/config/vlan/static_mac/add/CmdConfigVlanStaticMacAdd.h", + "commands/config/vlan/static_mac/delete/CmdConfigVlanStaticMacDelete.h", + "commands/delete/acl/CmdDeleteAcl.h", + "commands/delete/acl/rule/CmdDeleteAclRule.h", + "commands/delete/arp/CmdDeleteArp.h", + "commands/delete/copp/CmdDeleteCopp.h", + "commands/delete/copp/cpu_traffic_policy/CmdDeleteCoppCpuTrafficPolicy.h", + "commands/delete/copp/cpu_traffic_policy/match/CmdDeleteCoppCpuTrafficPolicyMatch.h", + "commands/delete/copp/cpu_traffic_policy/match/action/CmdDeleteCoppCpuTrafficPolicyMatchAction.h", + "commands/delete/dhcp/CmdDeleteDhcp.h", + "commands/delete/dhcp/relay_source_override/CmdDeleteDhcpRelaySourceOverride.h", + "commands/delete/dhcp/reply_source_override/CmdDeleteDhcpReplySourceOverride.h", + "commands/delete/interface/CmdDeleteInterface.h", + "commands/delete/interface/ipv6/CmdDeleteInterfaceIpv6.h", + "commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.h", + "commands/delete/protocol/CmdDeleteProtocol.h", + "commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h", + "commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h", + "commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h", + "commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h", + "commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h", + "commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h", + "commands/delete/protocol/bgp/policy/prefix-list/CmdDeleteProtocolBgpPolicyPrefixList.h", + "commands/delete/protocol/bgp/policy/routing-policy/CmdDeleteProtocolBgpPolicyRoutingPolicy.h", + "commands/delete/protocol/static/CmdDeleteProtocolStatic.h", + "commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.h", + "commands/delete/qos/CmdDeleteQos.h", + "commands/delete/qos/default_queue_config/CmdDeleteQosDefaultQueueConfig.h", + "commands/delete/tunnel/CmdDeleteTunnel.h", + "commands/delete/tunnel/ip_in_ip/CmdDeleteTunnelIpInIp.h", + "commands/delete/tunnel/ip_in_ip/TunnelIpInIpDeleteUtils.h", + "commands/delete/tunnel/ip_in_ip/decap/CmdDeleteTunnelIpInIpDecap.h", + "commands/delete/tunnel/ip_in_ip/encap/CmdDeleteTunnelIpInIpEncap.h", + "commands/delete/vlan/CmdDeleteVlan.h", + "session/ConfigSession.h", + "session/FbossServiceUtil.h", + "session/Git.h", + "session/SystemdInterface.h", + "utils/InterfaceList.h", + "CliAppInit.h", + "CmdArgsLists.h", + "CmdGlobalOptions.h", + "CmdHandler.h", + "CmdList.h", + "CmdLocalOptions.h", + "CmdStreamHandler.h", + "CmdSubcommands.h", + "utils/AggregateOp.h", + "utils/AggregateUtils.h", + "utils/CLIParserUtils.h", + "utils/CmdClientUtils.h", + "utils/CmdClientUtilsCommon.h", + "utils/CmdInitUtils.h", + "utils/CmdUtils.h", + "utils/CmdUtilsCommon.h", + "utils/FilterOp.h", + "utils/FilterUtils.h", + "utils/HostInfo.h", + "utils/LoopbackUtils.h", + "utils/NetwhoamiUtils.h", + "utils/PortMap.h", + "utils/PrbsUtils.h", + "utils/SafetyPromptUtils.h", + "utils/Table.h", + "utils/TeFlowUtils.h", + ], + deps = [ + "//common/network/if:if", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/packet:ipproto", + "//fboss/agent/platforms/common:platform_mapping", + "//fboss/agent:agent_config", + "//fboss/agent:agent_dir_util", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:platform_config", + "//fboss/agent:switch_config", + "//fboss/agent:switchinfo_utils", + "//fboss/lib/config:agent_config_utils", + "//fboss/lib:common_file_utils", + "//fboss/qsfp_service/if:qsfp", + ":cli_metadata", + ":cmd-common-utils", + ":cmd-handler", + ":cmd-list-header", + ":fboss2-lib", + ":table-utils", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) + +fboss2_config_impl() diff --git a/fboss/cli/fboss2/CmdListConfig.cpp b/fboss/cli/fboss2/CmdListConfig.cpp index f31bc47569342..7b764895437f1 100644 --- a/fboss/cli/fboss2/CmdListConfig.cpp +++ b/fboss/cli/fboss2/CmdListConfig.cpp @@ -38,61 +38,13 @@ #include "fboss/cli/fboss2/commands/config/protocol/CmdConfigProtocol.h" #include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" #include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h" #include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h" #include "fboss/cli/fboss2/commands/config/protocol/static/CmdConfigProtocolStatic.h" #include "fboss/cli/fboss2/commands/config/protocol/static/route/add/CmdConfigProtocolStaticRouteAdd.h" #include "fboss/cli/fboss2/commands/config/ptp/CmdConfigPtp.h" @@ -137,6 +89,12 @@ #include "fboss/cli/fboss2/commands/delete/interface/ipv6/CmdDeleteInterfaceIpv6.h" #include "fboss/cli/fboss2/commands/delete/interface/ipv6/ndp/CmdDeleteInterfaceIpv6Ndp.h" #include "fboss/cli/fboss2/commands/delete/protocol/CmdDeleteProtocol.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h" #include "fboss/cli/fboss2/commands/delete/protocol/static/CmdDeleteProtocolStatic.h" #include "fboss/cli/fboss2/commands/delete/protocol/static/route/CmdDeleteProtocolStaticRoute.h" #include "fboss/cli/fboss2/commands/delete/qos/CmdDeleteQos.h" @@ -379,454 +337,99 @@ const CommandTree& kConfigCommandTree() { { { "global", - "Configure BGP global settings", + "Configure BGP global settings: " + "(router-id, local-asn, hold-time, confed-asn, " + "count-confeds-in-as-path-len, " + "graceful-restart-time, rib-allocated-path-ids, " + "network6, switch-limit[-total-path|" + "-max-golden-vips|-overload-protection-mode])", commandHandler, argRegistrar, - { - { - "router-id", - "Set BGP router identifier", - commandHandler< - CmdConfigProtocolBgpGlobalRouterId>, - argRegistrar< - CmdConfigProtocolBgpGlobalRouterIdTraits>, - }, - { - "local-asn", - "Set local AS number", - commandHandler< - CmdConfigProtocolBgpGlobalLocalAsn>, - argRegistrar< - CmdConfigProtocolBgpGlobalLocalAsnTraits>, - }, - { - "hold-time", - "Set BGP hold time in seconds", - commandHandler< - CmdConfigProtocolBgpGlobalHoldTime>, - argRegistrar< - CmdConfigProtocolBgpGlobalHoldTimeTraits>, - }, - { - "confed-asn", - "Set BGP confederation AS number", - commandHandler< - CmdConfigProtocolBgpGlobalConfedAsn>, - argRegistrar< - CmdConfigProtocolBgpGlobalConfedAsnTraits>, - }, - { - "cluster-id", - "Set route reflector cluster ID", - commandHandler< - CmdConfigProtocolBgpGlobalClusterId>, - argRegistrar< - CmdConfigProtocolBgpGlobalClusterIdTraits>, - }, - { - "network6", - "Add IPv6 network to advertise", - commandHandler< - CmdConfigProtocolBgpGlobalNetwork6Add>, - argRegistrar< - CmdConfigProtocolBgpGlobalNetwork6AddTraits>, - }, - { - "switch-limit", - "Set switch limit prefix-limit", - commandHandler< - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit>, - argRegistrar< - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits>, - }, - { - "switch-limit-total-path", - "Set switch limit total-path-limit", - commandHandler< - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit>, - argRegistrar< - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits>, - }, - { - "switch-limit-max-golden-vips", - "Set switch limit max-golden-vips", - commandHandler< - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips>, - argRegistrar< - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits>, - }, - { - "switch-limit-overload-protection-mode", - "Set switch limit overload-protection-mode", - commandHandler< - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode>, - argRegistrar< - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits>, - }, - }, }, { "peer-group", - "Configure BGP peer group", + "Configure BGP peer-group: " + "[ ...] (remote-asn, local-asn, " + "description, peer-tag, ingress-policy, " + "egress-policy, rr-client, confed-peer, " + "redistribute-peer, enhanced-route-refresh, " + "connect-mode, next-hop-self, add-path send|receive, " + "afi disable-ipv4-afi|disable-ipv6-afi|" + "ipv4-over-ipv6-nh, " + "graceful-restart restart-time|stateful-ha, " + "max-route pre-filter|post-filter|" + "pre-warning-threshold|post-warning-threshold|" + "pre-warning-only|post-warning-only, " + "timers hold-time|keepalive|out-delay|" + "withdraw-unprog-delay)", commandHandler, argRegistrar, - { - { - "description", - "Set peer group description", - commandHandler< - CmdConfigProtocolBgpPeerGroupDescription>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupDescriptionTraits>, - }, - { - "remote-asn", - "Set remote AS number", - commandHandler< - CmdConfigProtocolBgpPeerGroupRemoteAsn>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupRemoteAsnTraits>, - }, - { - "next-hop-self", - "Enable/disable next-hop-self", - commandHandler< - CmdConfigProtocolBgpPeerGroupNextHopSelf>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupNextHopSelfTraits>, - }, - { - "confed-peer", - "Enable/disable confederation peer", - commandHandler< - CmdConfigProtocolBgpPeerGroupConfedPeer>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupConfedPeerTraits>, - }, - { - "disable-ipv4-afi", - "Enable/disable IPv4 AFI", - commandHandler< - CmdConfigProtocolBgpPeerGroupDisableIpv4Afi>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits>, - }, - { - "v4-over-v6-nh", - "Enable/disable v4-over-v6 next-hop", - commandHandler< - CmdConfigProtocolBgpPeerGroupV4OverV6Nh>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits>, - }, - { - "rr-client", - "Enable/disable route reflector client", - commandHandler< - CmdConfigProtocolBgpPeerGroupRrClient>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupRrClientTraits>, - }, - { - "ingress-policy", - "Set ingress policy", - commandHandler< - CmdConfigProtocolBgpPeerGroupIngressPolicy>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupIngressPolicyTraits>, - }, - { - "egress-policy", - "Set egress policy", - commandHandler< - CmdConfigProtocolBgpPeerGroupEgressPolicy>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupEgressPolicyTraits>, - }, - { - "max-routes", - "Set maximum routes", - commandHandler< - CmdConfigProtocolBgpPeerGroupMaxRoutes>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupMaxRoutesTraits>, - }, - { - "peer-tag", - "Set peer tag", - commandHandler< - CmdConfigProtocolBgpPeerGroupPeerTag>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupPeerTagTraits>, - }, - { - "warning-only", - "Enable/disable warning-only mode", - commandHandler< - CmdConfigProtocolBgpPeerGroupWarningOnly>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupWarningOnlyTraits>, - }, - { - "warning-limit", - "Set warning limit percentage", - commandHandler< - CmdConfigProtocolBgpPeerGroupWarningLimit>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupWarningLimitTraits>, - }, - { - "timers", - "Configure BGP timers", - commandHandler< - CmdConfigProtocolBgpPeerGroupTimers>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupTimersTraits>, - { - { - "hold-time", - "Set hold time", - commandHandler< - CmdConfigProtocolBgpPeerGroupTimersHoldTime>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits>, - }, - { - "keepalive", - "Set keepalive interval", - commandHandler< - CmdConfigProtocolBgpPeerGroupTimersKeepalive>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits>, - }, - { - "out-delay", - "Set output delay", - commandHandler< - CmdConfigProtocolBgpPeerGroupTimersOutDelay>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits>, - }, - { - "withdraw-unprog-delay", - "Set withdraw unprogrammed delay", - commandHandler< - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay>, - argRegistrar< - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits>, - }, - }, - }, - }, }, { - "peer", - "Configure BGP peer", - commandHandler, - argRegistrar, - { - { - "peer-group", - "Set peer group", - commandHandler< - CmdConfigProtocolBgpPeerPeerGroup>, - argRegistrar< - CmdConfigProtocolBgpPeerPeerGroupTraits>, - }, - { - "description", - "Set peer description", - commandHandler< - CmdConfigProtocolBgpPeerDescription>, - argRegistrar< - CmdConfigProtocolBgpPeerDescriptionTraits>, - }, - { - "remote-asn", - "Set remote AS number", - commandHandler< - CmdConfigProtocolBgpPeerRemoteAsn>, - argRegistrar< - CmdConfigProtocolBgpPeerRemoteAsnTraits>, - }, - { - "local-addr", - "Set local address", - commandHandler< - CmdConfigProtocolBgpPeerLocalAddr>, - argRegistrar< - CmdConfigProtocolBgpPeerLocalAddrTraits>, - }, - { - "next-hop4", - "Set IPv4 next-hop", - commandHandler< - CmdConfigProtocolBgpPeerNextHop4>, - argRegistrar< - CmdConfigProtocolBgpPeerNextHop4Traits>, - }, - { - "next-hop6", - "Set IPv6 next-hop", - commandHandler< - CmdConfigProtocolBgpPeerNextHop6>, - argRegistrar< - CmdConfigProtocolBgpPeerNextHop6Traits>, - }, - { - "next-hop-self", - "Enable/disable next-hop-self", - commandHandler< - CmdConfigProtocolBgpPeerNextHopSelf>, - argRegistrar< - CmdConfigProtocolBgpPeerNextHopSelfTraits>, - }, - { - "disable-ipv4-afi", - "Enable/disable IPv4 AFI", - commandHandler< - CmdConfigProtocolBgpPeerDisableIpv4Afi>, - argRegistrar< - CmdConfigProtocolBgpPeerDisableIpv4AfiTraits>, - }, - { - "v4-over-v6-nh", - "Enable/disable v4-over-v6 next-hop", - commandHandler< - CmdConfigProtocolBgpPeerV4OverV6Nh>, - argRegistrar< - CmdConfigProtocolBgpPeerV4OverV6NhTraits>, - }, - { - "rr-client", - "Enable/disable route reflector client", - commandHandler< - CmdConfigProtocolBgpPeerRrClient>, - argRegistrar< - CmdConfigProtocolBgpPeerRrClientTraits>, - }, - { - "passive", - "Enable/disable passive mode", - commandHandler< - CmdConfigProtocolBgpPeerPassive>, - argRegistrar< - CmdConfigProtocolBgpPeerPassiveTraits>, - }, - { - "type", - "Set peer type", - commandHandler, - argRegistrar< - CmdConfigProtocolBgpPeerTypeTraits>, - }, - { - "ingress-policy", - "Set ingress policy", - commandHandler< - CmdConfigProtocolBgpPeerIngressPolicy>, - argRegistrar< - CmdConfigProtocolBgpPeerIngressPolicyTraits>, - }, - { - "egress-policy", - "Set egress policy", - commandHandler< - CmdConfigProtocolBgpPeerEgressPolicy>, - argRegistrar< - CmdConfigProtocolBgpPeerEgressPolicyTraits>, - }, - { - "max-routes", - "Set maximum routes", - commandHandler< - CmdConfigProtocolBgpPeerMaxRoutes>, - argRegistrar< - CmdConfigProtocolBgpPeerMaxRoutesTraits>, - }, - { - "peer-id", - "Set peer identifier", - commandHandler< - CmdConfigProtocolBgpPeerPeerId>, - argRegistrar< - CmdConfigProtocolBgpPeerPeerIdTraits>, - }, - { - "advertise-lbw", - "Enable/disable link bandwidth advertisement", - commandHandler< - CmdConfigProtocolBgpPeerAdvertiseLbw>, - argRegistrar< - CmdConfigProtocolBgpPeerAdvertiseLbwTraits>, - }, - { - "link-bandwidth", - "Set link bandwidth", - commandHandler< - CmdConfigProtocolBgpPeerLinkBandwidth>, - argRegistrar< - CmdConfigProtocolBgpPeerLinkBandwidthTraits>, - }, - { - "hold-time", - "Set hold time", - commandHandler< - CmdConfigProtocolBgpPeerHoldTime>, - argRegistrar< - CmdConfigProtocolBgpPeerHoldTimeTraits>, - }, - { - "warning-only", - "Enable/disable warning-only mode", - commandHandler< - CmdConfigProtocolBgpPeerWarningOnly>, - argRegistrar< - CmdConfigProtocolBgpPeerWarningOnlyTraits>, - }, - { - "warning-limit", - "Set warning limit percentage", - commandHandler< - CmdConfigProtocolBgpPeerWarningLimit>, - argRegistrar< - CmdConfigProtocolBgpPeerWarningLimitTraits>, - }, - { - "timers", - "Configure BGP timers", - commandHandler< - CmdConfigProtocolBgpPeerTimers>, - argRegistrar< - CmdConfigProtocolBgpPeerTimersTraits>, - { - { - "keepalive", - "Set keepalive interval", - commandHandler< - CmdConfigProtocolBgpPeerTimersKeepalive>, - argRegistrar< - CmdConfigProtocolBgpPeerTimersKeepaliveTraits>, - }, - { - "out-delay", - "Set output delay", - commandHandler< - CmdConfigProtocolBgpPeerTimersOutDelay>, - argRegistrar< - CmdConfigProtocolBgpPeerTimersOutDelayTraits>, - }, - { - "withdraw-unprog-delay", - "Set withdraw unprogrammed delay", - commandHandler< - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay>, - argRegistrar< - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits>, - }, - }, - }, - }, + "neighbor", + "Configure BGP neighbor: " + "[ ...] (remote-asn, local-asn, " + "description, peer-tag, peer-group, ingress-policy, " + "egress-policy, rr-client, confed-peer, " + "redistribute-peer, enhanced-route-refresh, " + "connect-mode, next-hop4, next-hop6, next-hop-self, " + "peer-id, type, link-bandwidth, advertise-lbw, " + "receive-lbw, add-path send|receive, " + "afi disable-ipv4-afi|disable-ipv6-afi|" + "ipv4-over-ipv6-nh, bind-addr address, " + "graceful-restart restart-time|stateful-ha, " + "max-route pre-filter|post-filter|" + "pre-warning-threshold|post-warning-threshold|" + "pre-warning-only|post-warning-only, " + "timers hold-time|keepalive|out-delay|" + "withdraw-unprog-delay)", + commandHandler, + argRegistrar, + }, + { + "policy", + "Configure BGP policy objects", + commandHandler, + argRegistrar, + {{ + "as-path-list", + "Configure BGP AS-path list: " + "[ ...] (description)", + commandHandler< + CmdConfigProtocolBgpPolicyAsPathList>, + argRegistrar< + CmdConfigProtocolBgpPolicyAsPathListTraits>, + {{ + "entry", + "Configure an AS-path list entry: " + " [ ...] " + "(asn-regexp, description, match-logic)", + commandHandler< + CmdConfigProtocolBgpPolicyAsPathListEntry>, + argRegistrar< + CmdConfigProtocolBgpPolicyAsPathListEntryTraits>, + }}, + }, + { + "community-list", + "Configure BGP community-list: " + "[ ...] " + "(boolean-operator, description, exact-match)", + commandHandler< + CmdConfigProtocolBgpPolicyCommunityList>, + argRegistrar< + CmdConfigProtocolBgpPolicyCommunityListTraits>, + {{ + "community", + "Configure a community-list community: " + " [ ...] " + "(description, type, value)", + commandHandler< + CmdConfigProtocolBgpPolicyCommunityListCommunity>, + argRegistrar< + CmdConfigProtocolBgpPolicyCommunityListCommunityTraits>, + }}, + }}, }, }, }, @@ -1109,31 +712,70 @@ const CommandTree& kConfigCommandTree() { commandHandler, argTypeHandler, {{ - "static", - "Delete static routing configuration", - commandHandler, - argTypeHandler, - {{ - "ip", - "Delete IPv4 static routes", - {{ - "route", - "Delete IPv4 static route", - commandHandler, - argRegistrar, - }}, - }, - { - "ipv6", - "Delete IPv6 static routes", - {{ - "route", - "Delete IPv6 static route", - commandHandler, - argRegistrar, - }}, - }}, - }}, + "bgp", + "Delete BGP configuration objects", + commandHandler, + argTypeHandler, + {{ + "neighbor", + "Delete a BGP neighbor: ", + commandHandler, + argRegistrar, + }, + { + "peer-group", + "Delete a BGP peer-group: ", + commandHandler, + argRegistrar, + }, + { + "policy", + "Delete BGP policy objects", + commandHandler, + argTypeHandler, + {{ + "as-path-list", + "Delete a BGP AS-path list: ", + commandHandler, + argRegistrar< + CmdDeleteProtocolBgpPolicyAsPathListTraits>, + }, + { + "community-list", + "Delete a BGP community-list: ", + commandHandler< + CmdDeleteProtocolBgpPolicyCommunityList>, + argRegistrar< + CmdDeleteProtocolBgpPolicyCommunityListTraits>, + }}, + }}, + }, + { + "static", + "Delete static routing configuration", + commandHandler, + argTypeHandler, + {{ + "ip", + "Delete IPv4 static routes", + {{ + "route", + "Delete IPv4 static route", + commandHandler, + argRegistrar, + }}, + }, + { + "ipv6", + "Delete IPv6 static routes", + {{ + "route", + "Delete IPv6 static route", + commandHandler, + argRegistrar, + }}, + }}, + }}, }, { diff --git a/fboss/cli/fboss2/cli_metadata.thrift b/fboss/cli/fboss2/cli_metadata.thrift index f933911900a53..de1071db3a120 100644 --- a/fboss/cli/fboss2/cli_metadata.thrift +++ b/fboss/cli/fboss2/cli_metadata.thrift @@ -17,9 +17,11 @@ namespace cpp2 facebook.fboss.cli // changes. enum ConfigActionLevel { HITLESS = 0, // Can be applied with reloadConfig() - default - AGENT_WARMBOOT = 1, // Requires agent warmboot restart + // Requires a service restart that preserves state where possible. For the + // agent this is a warmboot (forwarding state retained); for bgpd (BGP++), + // which has no hitless reload, it is a plain service restart. + AGENT_WARMBOOT = 1, AGENT_COLDBOOT = 2, // Requires agent coldboot restart (clears ASIC state) - BGP_RESTART = 3, // Requires a restart of the bgpd (BGP++) service } // Identifier for different services that can be configured diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h new file mode 100644 index 0000000000000..4ffc9afff0138 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h @@ -0,0 +1,392 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h" +#include "fmt/format.h" +#include "thrift/lib/cpp2/gen/module_types_h.h" + +/** + * Generic, target-typed per-attribute handler factories shared by every + * `config protocol bgp ...` dispatcher. + * + * Each factory owns one value SHAPE (a bool, a bounded int, a 4-byte ASN, an + * IP address, a seconds-valued timer, ...): it validates the CLI tokens, + * produces the usage and rejection text for that shape, and on success calls + * the caller-supplied setter with an already-parsed value. They are templated + * on the target type T so the same logic mutates any BGP thrift object + * (BgpPeer, PeerGroup, AsPathList, PrefixListEntry, BgpPolicyTerm, ...). + * + * A dispatcher's registry is therefore one line per attribute -- key, shape, + * setter -- with no handler bodies inline. If an attribute seems to need a + * hand-written handler, that means its value shape has no factory yet, and the + * fix is to add the factory here. + */ +namespace facebook::fboss::bgpcli { + +using Tokens = std::vector; + +// A per-attribute handler mutating a typed thrift target T in place. +template +using AttrHandler = std::function; + +// A single-token string value (names, regex patterns, policy names). +template +AttrHandler stringAttr( + std::string_view name, + std::string_view valueName, + std::function set) { + return [name, valueName, set = std::move(set)]( + T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires <{}>", name, valueName)); + } + set(target, values[0]); + return ok(fmt::format("Successfully set {} to: {}", name, values[0])); + }; +} + +// A free-text string value that may span multiple CLI tokens (descriptions); +// the tokens are re-joined with single spaces. +template +AttrHandler joinedStringAttr( + std::string_view name, + std::function set) { + return + [name, set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.empty()) { + return err(fmt::format("Error: {} requires ", name)); + } + std::string joined = values[0]; + for (size_t i = 1; i < values.size(); ++i) { + joined += " " + values[i]; + } + set(target, joined); + return ok(fmt::format("Successfully set {} to: {}", name, joined)); + }; +} + +// A true/false value (accepts the parseBool spellings). +template +AttrHandler boolAttr( + std::string_view name, + std::function set) { + return + [name, set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto enable = parseBool(values[0]); + if (!enable) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected true or false", + name, + values[0])); + } + set(target, *enable); + return ok( + fmt::format( + "Successfully {} {}", *enable ? "enabled" : "disabled", name)); + }; +} + +// A bounded integer value in [minValue, maxValue]. `valueDesc` documents the +// accepted range in both the usage and the rejection message; it is taken by +// value for the same dangling-temporary reason as enumAttr's. +template +AttrHandler intAttr( + std::string_view name, + std::string valueDesc, + int32_t minValue, + int32_t maxValue, + std::function set) { + return [name, + valueDesc = std::move(valueDesc), + minValue, + maxValue, + set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires <{}>", name, valueDesc)); + } + auto parsed = parseInt(values[0]); + if (!parsed || *parsed < minValue || *parsed > maxValue) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected {}", + name, + values[0], + valueDesc)); + } + set(target, static_cast(*parsed)); + return ok(fmt::format("Successfully set {} to: {}", name, values[0])); + }; +} + +// A non-negative integer value in [0, maxValue], for the thrift fields that +// hold an unsigned quantity in a signed i64 (local-pref, med, ...). Unlike +// intAttr the accepted range is DERIVED from maxValue for both the usage and +// the rejection message, so the two cannot drift apart. The setter takes +// int64_t to match those fields directly, with no cast at the call site. +template +AttrHandler uintAttr( + std::string_view name, + int64_t maxValue, + std::function set) { + return [name, maxValue, set = std::move(set)]( + T& target, const Tokens& values) -> Result { + auto parsed = values.size() == 1 ? parseInt(values[0]) + : std::optional(); + if (!parsed || *parsed < 0 || *parsed > maxValue) { + return err(fmt::format("Error: {} requires <0-{}>", name, maxValue)); + } + set(target, *parsed); + return ok(fmt::format("Successfully set {} to: {}", name, values[0])); + }; +} + +// A 4-byte ASN value (RFC 6793). The thrift fields are i64, so an unchecked +// parse would let an out-of-range ASN wrap or exceed the protocol range. +template +AttrHandler asnAttr( + std::string_view name, + std::function set) { + return + [name, set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto asn = parseAsn4Byte(values[0]); + if (!asn) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected an unsigned 4-byte " + "ASN", + name, + values[0])); + } + set(target, *asn); + return ok(fmt::format("Successfully set {} to: {}", name, *asn)); + }; +} + +// A validated IP address value, optionally restricted to one family, stored +// normalized. +template +AttrHandler ipAttr( + std::string_view name, + std::function set, + std::optional requireV6 = std::nullopt) { + return [name, set = std::move(set), requireV6]( + T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto addr = folly::IPAddress::tryFromString(values[0]); + if (!addr.hasValue()) { + return err( + fmt::format("Error: Invalid {} address '{}'", name, values[0])); + } + if (requireV6.has_value() && addr->isV6() != *requireV6) { + return err( + fmt::format( + "Error: {} requires an IPv{} address, got '{}'", + name, + *requireV6 ? 6 : 4, + values[0])); + } + set(target, addr->str()); + return ok(fmt::format("Successfully set {} to: {}", name, addr->str())); + }; +} + +// A non-negative second-valued timer that must fit in int32. +template +AttrHandler secondsAttr( + std::string_view name, + std::function set) { + return + [name, set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto seconds = parseNonNegInt32(values[0]); + if (!seconds) { + return err( + fmt::format( + "Error: {} must be a non-negative integer that fits in " + "int32, got '{}'", + name, + values[0])); + } + set(target, *seconds); + return ok( + fmt::format("Successfully set {} to: {} seconds", name, *seconds)); + }; +} + +// A non-negative int64 route-count value (RouteLimit fields). +template +AttrHandler routeCountAttr( + std::string_view name, + std::function set) { + return + [name, set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto limit = parseNonNegInt64(values[0]); + if (!limit) { + return err( + fmt::format( + "Error: {} must be a non-negative integer, got '{}'", + name, + values[0])); + } + set(target, *limit); + return ok(fmt::format("Successfully set {} to: {}", name, *limit)); + }; +} + +// An attribute the CLI must refuse: either the thrift has no field for it +// (persisting it would stage dead config the daemon ignores) or the knob is +// not settable at this level. The reason is surfaced to the user instead. +template +AttrHandler rejectedAttr(std::string_view name, std::string_view reason) { + return [name, reason](T& /* target */, const Tokens& /* values */) -> Result { + return err(fmt::format("Error: {} is not supported: {}", name, reason)); + }; +} + +// A bit-rate value: digits with an optional K/M/G multiplier suffix (e.g. +// "100G"). The thrift field is a string that bgpd's config parser re-parses, +// so validating the spelling here keeps garbage from reaching the daemon. +template +AttrHandler bitRateAttr( + std::string_view name, + std::function set) { + return [name, set = std::move(set)]( + T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err( + fmt::format("Error: {} requires [K|M|G]", name)); + } + const std::string& v = values[0]; + const size_t digits = v.find_first_not_of("0123456789") == std::string::npos + ? v.size() + : v.find_first_not_of("0123456789"); + const bool valid = digits > 0 && + (digits == v.size() || + (digits == v.size() - 1 && + (v.back() == 'K' || v.back() == 'M' || v.back() == 'G'))); + if (!valid) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected digits with an " + "optional K/M/G suffix (e.g. 100G)", + name, + v)); + } + set(target, v); + return ok(fmt::format("Successfully set {} to: {}", name, v)); + }; +} + +// A value drawn from a fixed set of names, mapped to an enum by `lookup` +// (returns std::nullopt for an unrecognized name). `valueDesc` documents the +// accepted names in both the usage and the rejection message; it is taken by +// value because call sites build it with fmt::format, and a string_view +// capture would dangle once that temporary dies. +template +AttrHandler enumAttr( + std::string_view name, + std::string valueDesc, + std::function(const std::string&)> lookup, + std::function set) { + return [name, + valueDesc = std::move(valueDesc), + lookup = std::move(lookup), + set = std::move(set)](T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires <{}>", name, valueDesc)); + } + auto parsed = lookup(values[0]); + if (!parsed) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected {}", + name, + values[0], + valueDesc)); + } + set(target, *parsed); + return ok(fmt::format("Successfully set {} to: {}", name, values[0])); + }; +} + +// A thrift enum attribute identified by its generated metadata rather than a +// hand-written lookup: accepts the enum value name (e.g. BEST_PATH), the +// integer value, or true/false as aliases for 1/0 (the per-attribute commands +// this replaced took booleans, so existing usage keeps working). Prefer +// enumAttr when only a documented subset of the enum is valid; use this when +// the whole enum is. +template +AttrHandler thriftEnumAttr( + std::string_view name, + std::function set) { + return [name, set = std::move(set)]( + T& target, const Tokens& values) -> Result { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + EnumT mode; + bool valid = false; + if (auto parsed = parseInt(values[0])) { + mode = static_cast(*parsed); + valid = apache::thrift::TEnumTraits::findName(mode) != nullptr; + } else if (auto enable = parseBool(values[0])) { + mode = static_cast(*enable ? 1 : 0); + valid = true; + } else { + valid = apache::thrift::TEnumTraits::findValue(values[0], &mode); + } + if (!valid) { + std::string names; + for (auto n : apache::thrift::TEnumTraits::names) { + names += names.empty() ? "" : ", "; + names += std::string(n); + } + return err( + fmt::format( + "Error: {} value '{}' is not a valid mode; expected one of: " + "{}", + name, + values[0], + names)); + } + set(target, mode); + return ok( + fmt::format( + "Successfully set {} to: {}", name, static_cast(mode))); + }; +} + +} // namespace facebook::fboss::bgpcli diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h new file mode 100644 index 0000000000000..5d610e328cae5 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * Value parsing helpers shared by the BGP config dispatchers + * (`config protocol bgp global` / `config protocol bgp neighbor`). + * + * All parsers return std::nullopt on invalid input instead of throwing so a + * handler can reject the value with a user-facing message and leave the + * session unpersisted. + */ +namespace facebook::fboss::bgpcli { + +// Outcome of an attribute handler: on failure the message is returned to the +// user and the session is NOT persisted, so a rejected value never lands on +// disk. +struct Result { + bool ok; + std::string message; +}; + +inline Result ok(std::string message) { + return Result{true, std::move(message)}; +} + +inline Result err(std::string message) { + return Result{false, std::move(message)}; +} + +inline std::optional parseBool(const std::string& value) { + if (value == "true" || value == "1" || value == "yes") { + return true; + } + if (value == "false" || value == "0" || value == "no") { + return false; + } + return std::nullopt; +} + +template +std::optional parseInt(const std::string& value) { + try { + return folly::to(value); + } catch (const std::exception&) { + return std::nullopt; + } +} + +// Parse a non-negative value that must fit in int32 (used for second-valued +// timers and min-routes). +inline std::optional parseNonNegInt32(const std::string& value) { + auto parsed = parseInt(value); + if (!parsed || *parsed < 0 || *parsed > std::numeric_limits::max()) { + return std::nullopt; + } + return static_cast(*parsed); +} + +// Parse a non-negative int64 (used for route limits). +inline std::optional parseNonNegInt64(const std::string& value) { + auto parsed = parseInt(value); + if (!parsed || *parsed < 0) { + return std::nullopt; + } + return parsed; +} + +// Parse a 4-byte ASN (RFC 6793): an unsigned value in [0, 2^32-1]. The thrift +// fields are i64, so an unchecked uint64 parse would let an out-of-range ASN +// wrap or exceed the protocol range and be persisted. +inline std::optional parseAsn4Byte(const std::string& value) { + auto parsed = parseInt(value); + if (!parsed || *parsed > std::numeric_limits::max()) { + return std::nullopt; + } + return static_cast(*parsed); +} + +// ---- constructor-time token parsing ---------------------------------------- +// Unlike the value parsers above, this runs while constructing a command's +// ObjectArgType, where throwing std::invalid_argument IS the framework's +// error channel — the message is surfaced to the user as the parse error. + +// The ` [ ]` prefix shared by the policy +// list commands (config and delete): the list name, the optional named +// member selected by `keyword`, and where any remaining tokens begin. +struct ListMemberSelector { + std::string listName; + std::optional memberName; + // Index of the first token after the parsed prefix (== tokens.size() when + // nothing follows). The config dispatcher reads an ... + // tail from here; the delete dispatcher rejects any tail. + size_t restStart; +}; + +// Parse the shared prefix. `objectName` is the list flavor for messages +// (e.g. "community-list"), `memberKeyword` selects the nested member (e.g. +// `community`), and `usage` is the whole-command usage line thrown when no +// tokens were given. A second token other than `memberKeyword` is left to +// the caller (restStart == 1): the config grammar treats it as a list-level +// attribute, delete as an unexpected token. +inline ListMemberSelector parseListMemberSelector( + const std::vector& tokens, + std::string_view objectName, + std::string_view memberKeyword, + std::string_view usage) { + if (tokens.empty()) { + throw std::invalid_argument(std::string(usage)); + } + if (tokens[0].empty()) { + throw std::invalid_argument( + fmt::format("Error: {} name must not be empty", objectName)); + } + ListMemberSelector selector{tokens[0], std::nullopt, 1}; + if (tokens.size() > 1 && tokens[1] == memberKeyword) { + if (tokens.size() < 3 || tokens[2].empty()) { + throw std::invalid_argument( + fmt::format("Error: `{}` requires a ", memberKeyword)); + } + selector.memberName = tokens[2]; + selector.restStart = 3; + } + return selector; +} + +} // namespace facebook::fboss::bgpcli diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.cpp index f5378e3609638..637d5aa16337f 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.cpp +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.cpp @@ -13,9 +13,16 @@ #include #include #include +#include #include +#include #include #include +#include +#include +#include +#include +#include "folly/json/dynamic.h" namespace fs = std::filesystem; @@ -42,6 +49,7 @@ folly::dynamic getDefaultBgpConfig() { } // namespace BgpConfigSession::BgpConfigSession() { + // NOLINTNEXTLINE(concurrency-mt-unsafe): single-threaded CLI const char* homeDir = std::getenv("HOME"); if (homeDir == nullptr) { throw std::runtime_error("HOME environment variable not set"); @@ -56,6 +64,7 @@ BgpConfigSession::BgpConfigSession() { bgpConfig_ = getDefaultBgpConfig(); // Check for stub mode via environment variable + // NOLINTNEXTLINE(concurrency-mt-unsafe): single-threaded CLI const char* stubEnv = std::getenv("FBOSS_BGP_STUB_MODE"); if (stubEnv != nullptr && std::string(stubEnv) == "1") { stubMode_ = true; @@ -208,20 +217,6 @@ std::optional BgpConfigSession::getConfedAsn() const { return std::nullopt; } -void BgpConfigSession::setClusterId(const std::string& clusterId) { - ensureConfigLoaded(); - bgpConfig_["cluster_id"] = clusterId; -} - -std::optional BgpConfigSession::getClusterId() const { - const_cast(this)->ensureConfigLoaded(); - if (bgpConfig_.count("cluster_id") && - !bgpConfig_["cluster_id"].asString().empty()) { - return bgpConfig_["cluster_id"].asString(); - } - return std::nullopt; -} - void BgpConfigSession::setListenAddress(const std::string& listenAddr) { ensureConfigLoaded(); bgpConfig_["listen_addr"] = listenAddr; @@ -462,284 +457,6 @@ std::optional BgpConfigSession::getUcmpWidth() const { return std::nullopt; } -// ==================== Peer Configuration ==================== - -folly::dynamic& BgpConfigSession::findOrCreatePeer( - const std::string& peerAddr) { - ensureConfigLoaded(); - auto& peers = bgpConfig_["peers"]; - - // Find existing peer - for (auto& peer : peers) { - if (peer["peer_addr"].asString() == peerAddr) { - return peer; - } - } - - // Create new peer with required fields - folly::dynamic newPeer = folly::dynamic::object("peer_addr", peerAddr)( - "local_addr", "")("next_hop4", "")("next_hop6", ""); - - peers.push_back(std::move(newPeer)); - return peers[peers.size() - 1]; -} - -void BgpConfigSession::createPeer(const std::string& peerAddr) { - findOrCreatePeer(peerAddr); -} - -void BgpConfigSession::setPeerRemoteAsn( - const std::string& peerAddr, - uint64_t remoteAsn) { - findOrCreatePeer(peerAddr)["remote_as_4_byte"] = - static_cast(remoteAsn); -} - -void BgpConfigSession::setPeerLocalAsn( - const std::string& peerAddr, - uint64_t localAsn) { - findOrCreatePeer(peerAddr)["local_as"] = static_cast(localAsn); -} - -void BgpConfigSession::setPeerDescription( - const std::string& peerAddr, - const std::string& description) { - findOrCreatePeer(peerAddr)["description"] = description; -} - -void BgpConfigSession::setPeerLocalAddr( - const std::string& peerAddr, - const std::string& localAddr) { - findOrCreatePeer(peerAddr)["local_addr"] = localAddr; -} - -void BgpConfigSession::setPeerNextHop4( - const std::string& peerAddr, - const std::string& nextHop4) { - findOrCreatePeer(peerAddr)["next_hop4"] = nextHop4; -} - -void BgpConfigSession::setPeerNextHop6( - const std::string& peerAddr, - const std::string& nextHop6) { - findOrCreatePeer(peerAddr)["next_hop6"] = nextHop6; -} - -void BgpConfigSession::setPeerGroupName( - const std::string& peerAddr, - const std::string& peerGroupName) { - findOrCreatePeer(peerAddr)["peer_group_name"] = peerGroupName; -} - -void BgpConfigSession::setPeerPassive( - const std::string& peerAddr, - bool isPassive) { - findOrCreatePeer(peerAddr)["is_passive"] = isPassive; -} - -void BgpConfigSession::setPeerRrClient( - const std::string& peerAddr, - bool isRrClient) { - findOrCreatePeer(peerAddr)["is_rr_client"] = isRrClient; -} - -void BgpConfigSession::setPeerNextHopSelf( - const std::string& peerAddr, - bool nextHopSelf) { - findOrCreatePeer(peerAddr)["next_hop_self"] = nextHopSelf; -} - -void BgpConfigSession::setPeerConfedPeer( - const std::string& peerAddr, - bool isConfedPeer) { - findOrCreatePeer(peerAddr)["is_confed_peer"] = isConfedPeer; -} - -void BgpConfigSession::setPeerPort(const std::string& peerAddr, int32_t port) { - findOrCreatePeer(peerAddr)["peer_port"] = port; -} - -void BgpConfigSession::setPeerLocalPort( - const std::string& peerAddr, - int32_t port) { - findOrCreatePeer(peerAddr)["local_port"] = port; -} - -void BgpConfigSession::setPeerConnectMode( - const std::string& peerAddr, - const std::string& connectMode) { - findOrCreatePeer(peerAddr)["connect_mode"] = connectMode; -} - -// Peer timers helper -folly::dynamic& BgpConfigSession::ensurePeerTimers( - const std::string& peerAddr) { - auto& peer = findOrCreatePeer(peerAddr); - if (!peer.count("bgp_peer_timers")) { - peer["bgp_peer_timers"] = folly::dynamic::object; - } - return peer["bgp_peer_timers"]; -} - -void BgpConfigSession::setPeerHoldTime( - const std::string& peerAddr, - int32_t holdTime) { - ensurePeerTimers(peerAddr)["hold_time_seconds"] = holdTime; -} - -void BgpConfigSession::setPeerKeepalive( - const std::string& peerAddr, - int32_t keepalive) { - ensurePeerTimers(peerAddr)["keep_alive_seconds"] = keepalive; -} - -void BgpConfigSession::setPeerOutDelay( - const std::string& peerAddr, - int32_t outDelay) { - ensurePeerTimers(peerAddr)["out_delay_seconds"] = outDelay; -} - -void BgpConfigSession::setPeerGracefulRestartTime( - const std::string& peerAddr, - int32_t seconds) { - findOrCreatePeer(peerAddr)["graceful_restart_seconds"] = seconds; -} - -void BgpConfigSession::setPeerStatefulHa( - const std::string& peerAddr, - bool enable) { - findOrCreatePeer(peerAddr)["enable_stateful_ha"] = enable; -} - -// Peer AFI/SAFI -void BgpConfigSession::setPeerDisableIpv4Afi( - const std::string& peerAddr, - bool disable) { - findOrCreatePeer(peerAddr)["disable_ipv4_afi"] = disable; -} - -void BgpConfigSession::setPeerDisableIpv6Afi( - const std::string& peerAddr, - bool disable) { - findOrCreatePeer(peerAddr)["disable_ipv6_afi"] = disable; -} - -void BgpConfigSession::setPeerIpv4LabeledUnicast( - const std::string& peerAddr, - bool enable) { - findOrCreatePeer(peerAddr)["is_afi_ipv4_lu_configured"] = enable; -} - -void BgpConfigSession::setPeerIpv6LabeledUnicast( - const std::string& peerAddr, - bool enable) { - findOrCreatePeer(peerAddr)["is_afi_ipv6_lu_configured"] = enable; -} - -void BgpConfigSession::setPeerIpv4OverIpv6Nh( - const std::string& peerAddr, - bool enable) { - findOrCreatePeer(peerAddr)["v4_over_v6_nexthop"] = enable; -} - -// Peer add-path helper -folly::dynamic& BgpConfigSession::ensurePeerAddPath( - const std::string& peerAddr) { - auto& peer = findOrCreatePeer(peerAddr); - if (!peer.count("add_path")) { - peer["add_path"] = folly::dynamic::object; - } - return peer["add_path"]; -} - -void BgpConfigSession::setPeerAddPathSend( - const std::string& peerAddr, - bool enable) { - ensurePeerAddPath(peerAddr)["send"] = enable; -} - -void BgpConfigSession::setPeerAddPathReceive( - const std::string& peerAddr, - bool enable) { - ensurePeerAddPath(peerAddr)["receive"] = enable; -} - -// Peer AS-path settings -void BgpConfigSession::setPeerRemovePrivateAs( - const std::string& peerAddr, - bool remove) { - findOrCreatePeer(peerAddr)["remove_private_as"] = remove; -} - -void BgpConfigSession::setPeerEnforceFirstAs( - const std::string& peerAddr, - bool enforce) { - findOrCreatePeer(peerAddr)["enforce_first_as"] = enforce; -} - -// Peer policies -void BgpConfigSession::setPeerIngressPolicy( - const std::string& peerAddr, - const std::string& policy) { - findOrCreatePeer(peerAddr)["ingress_policy_name"] = policy; -} - -void BgpConfigSession::setPeerEgressPolicy( - const std::string& peerAddr, - const std::string& policy) { - findOrCreatePeer(peerAddr)["egress_policy_name"] = policy; -} - -// Peer route limits helpers -folly::dynamic& BgpConfigSession::ensurePeerPreFilter( - const std::string& peerAddr) { - auto& peer = findOrCreatePeer(peerAddr); - if (!peer.count("pre_filter")) { - peer["pre_filter"] = folly::dynamic::object; - } - return peer["pre_filter"]; -} - -folly::dynamic& BgpConfigSession::ensurePeerPostFilter( - const std::string& peerAddr) { - auto& peer = findOrCreatePeer(peerAddr); - if (!peer.count("post_filter")) { - peer["post_filter"] = folly::dynamic::object; - } - return peer["post_filter"]; -} - -void BgpConfigSession::setPeerPreFilterMaxRoutes( - const std::string& peerAddr, - int64_t maxRoutes) { - ensurePeerPreFilter(peerAddr)["max_routes"] = maxRoutes; -} - -void BgpConfigSession::setPeerPostFilterMaxRoutes( - const std::string& peerAddr, - int64_t maxRoutes) { - ensurePeerPostFilter(peerAddr)["max_routes"] = maxRoutes; -} - -// Peer link bandwidth -void BgpConfigSession::setPeerAdvertiseLbw( - const std::string& peerAddr, - bool advertise) { - findOrCreatePeer(peerAddr)["advertise_link_bandwidth"] = advertise; -} - -void BgpConfigSession::setPeerReceiveLbw( - const std::string& peerAddr, - bool receive) { - findOrCreatePeer(peerAddr)["receive_link_bandwidth"] = receive; -} - -void BgpConfigSession::setPeerLbwValue( - const std::string& peerAddr, - int64_t bps) { - findOrCreatePeer(peerAddr)["link_bandwidth_bps"] = bps; -} - // ==================== Peer Group Configuration ==================== folly::dynamic& BgpConfigSession::findOrCreatePeerGroup( @@ -1038,47 +755,6 @@ void BgpConfigSession::setPeerGroupWithdrawUnprogDelay( ensurePeerGroupTimers(groupName)["withdraw_unprog_delay_seconds"] = seconds; } -// ==================== Peer Identification (RSW compatibility) -// ==================== - -void BgpConfigSession::setPeerPeerId( - const std::string& peerAddr, - const std::string& peerId) { - findOrCreatePeer(peerAddr)["peer_id"] = peerId; -} - -void BgpConfigSession::setPeerType( - const std::string& peerAddr, - const std::string& type) { - findOrCreatePeer(peerAddr)["type"] = type; -} - -void BgpConfigSession::setPeerPeerTag( - const std::string& peerAddr, - const std::string& peerTag) { - findOrCreatePeer(peerAddr)["peer_tag"] = peerTag; -} - -// Peer pre_filter warning settings -void BgpConfigSession::setPeerPreFilterWarningLimit( - const std::string& peerAddr, - int64_t limit) { - ensurePeerPreFilter(peerAddr)["warning_limit"] = limit; -} - -void BgpConfigSession::setPeerPreFilterWarningOnly( - const std::string& peerAddr, - bool warningOnly) { - ensurePeerPreFilter(peerAddr)["warning_only"] = warningOnly; -} - -// Peer timer: withdraw_unprog_delay_seconds -void BgpConfigSession::setPeerWithdrawUnprogDelay( - const std::string& peerAddr, - int32_t seconds) { - ensurePeerTimers(peerAddr)["withdraw_unprog_delay_seconds"] = seconds; -} - // ==================== Networks Configuration ==================== void BgpConfigSession::addNetwork6( diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h index 30569f5a59bde..1ff564e7f70ad 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h @@ -11,6 +11,7 @@ #pragma once #include +#include #include #include @@ -42,7 +43,6 @@ namespace facebook::fboss { * - local_as_4_byte: i64 - Local AS number (RFC 6793) * - hold_time: i32 - Hold time in seconds (default 30) * - local_confed_as_4_byte: i64 - Confederation AS number - * - cluster_id: string - Route reflector cluster ID * - peers: list - List of BGP peers * - peer_groups: list - List of peer groups * @@ -103,10 +103,6 @@ class BgpConfigSession { void setConfedAsn(uint64_t asn); std::optional getConfedAsn() const; - // cluster_id: string - Route reflector cluster ID - void setClusterId(const std::string& clusterId); - std::optional getClusterId() const; - // listen_addr: string - Listen address for BGP sessions void setListenAddress(const std::string& listenAddr); std::optional getListenAddress() const; @@ -182,125 +178,6 @@ class BgpConfigSession { void setUcmpWidth(int32_t width); std::optional getUcmpWidth() const; - // ==================== Peer Configuration (Level: P) ==================== - // These map to BgpPeer thrift struct fields - - // Create/get peer by peer_addr - void createPeer(const std::string& peerAddr); - - // remote_as_4_byte: i64 - Peer's ASN - void setPeerRemoteAsn(const std::string& peerAddr, uint64_t remoteAsn); - - // local_as: i64 - Local ASN override for this peer - void setPeerLocalAsn(const std::string& peerAddr, uint64_t localAsn); - - // description: string - Peer description - void setPeerDescription( - const std::string& peerAddr, - const std::string& description); - - // local_addr: string - Local address to connect/listen on - void setPeerLocalAddr( - const std::string& peerAddr, - const std::string& localAddr); - - // next_hop4: string - IPv4 next-hop for outgoing updates - void setPeerNextHop4( - const std::string& peerAddr, - const std::string& nextHop4); - - // next_hop6: string - IPv6 next-hop for outgoing updates - void setPeerNextHop6( - const std::string& peerAddr, - const std::string& nextHop6); - - // peer_group_name: string - Reference to peer group - void setPeerGroupName( - const std::string& peerAddr, - const std::string& peerGroupName); - - // is_passive: bool - Listen for incoming connections - void setPeerPassive(const std::string& peerAddr, bool isPassive); - - // is_rr_client: bool - Route reflector client - void setPeerRrClient(const std::string& peerAddr, bool isRrClient); - - // next_hop_self: bool - Set next-hop to self - void setPeerNextHopSelf(const std::string& peerAddr, bool nextHopSelf); - - // is_confed_peer: bool - Confederation peer - void setPeerConfedPeer(const std::string& peerAddr, bool isConfedPeer); - - // peer_port: i32 - Remote peer port - void setPeerPort(const std::string& peerAddr, int32_t port); - - // local_port: i32 - Local source port - void setPeerLocalPort(const std::string& peerAddr, int32_t port); - - // connect_mode: string - PASSIVE_ACTIVE, PASSIVE_ONLY, ACTIVE_ONLY - void setPeerConnectMode( - const std::string& peerAddr, - const std::string& connectMode); - - // Peer timers - void setPeerHoldTime(const std::string& peerAddr, int32_t holdTime); - void setPeerKeepalive(const std::string& peerAddr, int32_t keepalive); - void setPeerOutDelay(const std::string& peerAddr, int32_t outDelay); - - // Peer graceful restart - void setPeerGracefulRestartTime(const std::string& peerAddr, int32_t seconds); - void setPeerStatefulHa(const std::string& peerAddr, bool enable); - - // Peer AFI/SAFI - void setPeerDisableIpv4Afi(const std::string& peerAddr, bool disable); - void setPeerDisableIpv6Afi(const std::string& peerAddr, bool disable); - void setPeerIpv4LabeledUnicast(const std::string& peerAddr, bool enable); - void setPeerIpv6LabeledUnicast(const std::string& peerAddr, bool enable); - void setPeerIpv4OverIpv6Nh(const std::string& peerAddr, bool enable); - - // Peer add-path - void setPeerAddPathSend(const std::string& peerAddr, bool enable); - void setPeerAddPathReceive(const std::string& peerAddr, bool enable); - - // Peer AS-path settings - void setPeerRemovePrivateAs(const std::string& peerAddr, bool remove); - void setPeerEnforceFirstAs(const std::string& peerAddr, bool enforce); - - // Peer policies - void setPeerIngressPolicy( - const std::string& peerAddr, - const std::string& policy); - void setPeerEgressPolicy( - const std::string& peerAddr, - const std::string& policy); - - // Peer route limits - void setPeerPreFilterMaxRoutes( - const std::string& peerAddr, - int64_t maxRoutes); - void setPeerPostFilterMaxRoutes( - const std::string& peerAddr, - int64_t maxRoutes); - - // Peer link bandwidth - void setPeerAdvertiseLbw(const std::string& peerAddr, bool advertise); - void setPeerReceiveLbw(const std::string& peerAddr, bool receive); - void setPeerLbwValue(const std::string& peerAddr, int64_t bps); - - // Peer identification (for RSW config compatibility) - void setPeerPeerId(const std::string& peerAddr, const std::string& peerId); - void setPeerType(const std::string& peerAddr, const std::string& type); - void setPeerPeerTag(const std::string& peerAddr, const std::string& peerTag); - - // Peer pre_filter warning settings - void setPeerPreFilterWarningLimit(const std::string& peerAddr, int64_t limit); - void setPeerPreFilterWarningOnly( - const std::string& peerAddr, - bool warningOnly); - - // Peer timer: withdraw_unprog_delay_seconds - void setPeerWithdrawUnprogDelay(const std::string& peerAddr, int32_t seconds); - // ==================== Peer Group Configuration (Level: PG) // ==================== These map to PeerGroup thrift struct fields @@ -468,23 +345,16 @@ class BgpConfigSession { void loadConfig(); void ensureConfigLoaded(); - // Helper to find or create a peer in the peers list - folly::dynamic& findOrCreatePeer(const std::string& peerAddr); - // Helper to find or create a peer group in the peer_groups list folly::dynamic& findOrCreatePeerGroup(const std::string& groupName); - // Helper to ensure peer timers exist - folly::dynamic& ensurePeerTimers(const std::string& peerAddr); + // Helper to ensure peer group timers exist folly::dynamic& ensurePeerGroupTimers(const std::string& groupName); // Helper to ensure add_path config exists - folly::dynamic& ensurePeerAddPath(const std::string& peerAddr); folly::dynamic& ensurePeerGroupAddPath(const std::string& groupName); // Helper to ensure pre_filter/post_filter config exists - folly::dynamic& ensurePeerPreFilter(const std::string& peerAddr); - folly::dynamic& ensurePeerPostFilter(const std::string& peerAddr); folly::dynamic& ensurePeerGroupPreFilter(const std::string& groupName); folly::dynamic& ensurePeerGroupPostFilter(const std::string& groupName); }; diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h new file mode 100644 index 0000000000000..26b4c458b4aee --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include +#include + +/** + * Peer-address helpers shared by the BGP neighbor commands (`config protocol + * bgp neighbor` / `delete protocol bgp neighbor`). + * + * peer_addr is the identity of a BgpPeer, but the same address can be spelled + * many ways (2001:DB8::1 vs 2001:db8::1), and passive listening sessions may + * use prefix notation (2001:db8::/64, per bgp_config.thrift). Both commands + * normalize the CLI-supplied address once and compare stored entries in + * normalized form so every spelling addresses the same peer. + */ +namespace facebook::fboss::bgpcli { + +// Normalize an address (or prefix, for passive listening sessions) to its +// canonical string form. nullopt if the input parses as neither. +inline std::optional normalizeBgpPeerAddr(const std::string& s) { + if (auto addr = folly::IPAddress::tryFromString(s)) { + return addr->str(); + } + if (auto network = folly::IPAddress::tryCreateNetwork( + s, /* defaultCidr */ -1, /* applyMask */ false)) { + return folly::IPAddress::networkToString(*network); + } + return std::nullopt; +} + +// Find the peer whose (normalized) peer_addr matches the given normalized +// address; peers().end() if absent. Stored entries may predate normalization, +// so their normalized form is compared when possible. +inline std::vector::iterator findBgpPeer( + bgp::thrift::BgpConfig& cfg, + const std::string& normalizedAddr) { + auto& peers = *cfg.peers(); + for (auto it = peers.begin(); it != peers.end(); ++it) { + const std::string key = + normalizeBgpPeerAddr(*it->peer_addr()).value_or(*it->peer_addr()); + if (key == normalizedAddr) { + return it; + } + } + return peers.end(); +} + +} // namespace facebook::fboss::bgpcli diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp index ff97042a344b6..b824d1aaae0e7 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.cpp @@ -12,11 +12,395 @@ #include "fboss/cli/fboss2/CmdHandler.cpp" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + namespace facebook::fboss { +namespace { + +// CLI attribute names. Kept here (not as raw string literals at the dispatch +// sites) so the valid-attribute set and the handler table stay in sync. +constexpr std::string_view kRouterId = "router-id"; +constexpr std::string_view kLocalAsn = "local-asn"; +constexpr std::string_view kHoldTime = "hold-time"; +constexpr std::string_view kConfedAsn = "confed-asn"; +constexpr std::string_view kNetwork6 = "network6"; +constexpr std::string_view kSwitchLimit = "switch-limit"; +constexpr std::string_view kSwitchLimitTotalPath = "switch-limit-total-path"; +constexpr std::string_view kSwitchLimitMaxGoldenVips = + "switch-limit-max-golden-vips"; +constexpr std::string_view kSwitchLimitOverloadProtectionMode = + "switch-limit-overload-protection-mode"; +constexpr std::string_view kCountConfedsInAsPathLen = + "count-confeds-in-as-path-len"; +constexpr std::string_view kGracefulRestartTime = "graceful-restart-time"; +constexpr std::string_view kRibAllocatedPathIds = "rib-allocated-path-ids"; + +using Tokens = std::vector; +using BgpConfig = bgp::thrift::BgpConfig; +// Value parsers and the handler Result type are shared with the neighbor +// dispatcher (see BgpCliValueParsers.h). +using bgpcli::err; +using bgpcli::ok; +using bgpcli::parseBool; +using bgpcli::parseInt; +using bgpcli::parseNonNegInt32; +using bgpcli::Result; + +// ---- per-attribute handlers ------------------------------------------------ +// Each handler mutates the typed bgp::thrift::BgpConfig directly. Field names +// map 1:1 to bgp_config.thrift, so the compiler validates them. + +Result applyRouterId(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: router-id requires "); + } + cfg.router_id() = values[0]; + return ok(fmt::format("Successfully set BGP router-id to: {}", values[0])); +} + +Result applyLocalAsn(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: local-asn requires "); + } + auto asn = bgpcli::parseAsn4Byte(values[0]); + if (!asn) { + return err( + fmt::format( + "Error: Invalid local-asn value '{}'; expected an unsigned " + "4-byte ASN", + values[0])); + } + cfg.local_as_4_byte() = *asn; + return ok(fmt::format("Successfully set BGP local-asn to: {}", *asn)); +} + +Result applyConfedAsn(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: confed-asn requires "); + } + auto asn = bgpcli::parseAsn4Byte(values[0]); + if (!asn) { + return err( + fmt::format( + "Error: Invalid confed-asn value '{}'; expected an unsigned " + "4-byte ASN", + values[0])); + } + cfg.local_confed_as_4_byte() = *asn; + return ok( + fmt::format("Successfully set BGP confederation AS number to: {}", *asn)); +} + +Result applyHoldTime(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: hold-time requires "); + } + auto seconds = parseNonNegInt32(values[0]); + if (!seconds) { + return err(fmt::format("Error: Invalid hold-time value '{}'", values[0])); + } + cfg.hold_time() = *seconds; + return ok( + fmt::format("Successfully set BGP hold-time to: {} seconds", *seconds)); +} + +Result applyGracefulRestartTime(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: graceful-restart-time requires "); + } + auto seconds = parseNonNegInt32(values[0]); + if (!seconds) { + return err( + fmt::format( + "Error: graceful-restart-time must be a non-negative integer " + "that fits in int32, got '{}'", + values[0])); + } + cfg.graceful_restart_convergence_seconds() = *seconds; + return ok( + fmt::format( + "Successfully set BGP graceful-restart-time to: {} seconds", + *seconds)); +} + +Result applyCountConfedsInAsPathLen(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: count-confeds-in-as-path-len requires "); + } + auto enable = parseBool(values[0]); + if (!enable) { + return err( + fmt::format( + "Error: Invalid value '{}'; expected true or false", values[0])); + } + cfg.count_confeds_in_as_path_len() = *enable; + return ok( + fmt::format( + "Successfully {} count-confeds-in-as-path-len", + *enable ? "enabled" : "disabled")); +} + +Result applyRibAllocatedPathIds(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: rib-allocated-path-ids requires "); + } + auto enable = parseBool(values[0]); + if (!enable) { + return err( + fmt::format( + "Error: Invalid value '{}'; expected true or false", values[0])); + } + // enable_rib_allocated_path_id lives inside the nested bgp_setting_config. + cfg.bgp_setting_config().ensure().enable_rib_allocated_path_id() = *enable; + return ok( + fmt::format( + "Successfully {} rib-allocated-path-ids", + *enable ? "enabled" : "disabled")); +} + +// Shared implementation for the switch-limit attributes, which differ only in +// the field setter, the field name in the success message, and the upper bound +// (i64 fields use INT64_MAX; the i32 max_golden_vips field uses INT32_MAX so an +// out-of-range value is rejected rather than silently truncated). All limits +// must be non-negative. +Result applyInt64Limit( + BgpConfig& cfg, + const Tokens& values, + std::string_view attrName, + std::string_view fieldName, + int64_t maxValue, + const std::function& setter) { + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", attrName)); + } + auto limit = parseInt(values[0]); + if (!limit) { + return err( + fmt::format("Error: Invalid {} value '{}'", attrName, values[0])); + } + if (*limit < 0 || *limit > maxValue) { + return err( + fmt::format( + "Error: {} value '{}' is out of range [0, {}]", + attrName, + values[0], + maxValue)); + } + setter(cfg, *limit); + return ok( + fmt::format( + "Successfully set switch_limit_config {} to: {}", fieldName, *limit)); +} + +Result applyOverloadProtectionMode(BgpConfig& cfg, const Tokens& values) { + if (values.size() != 1) { + return err("Error: switch-limit-overload-protection-mode requires "); + } + auto mode = parseInt(values[0]); + if (!mode) { + return err( + fmt::format( + "Error: Invalid overload-protection-mode value '{}'", values[0])); + } + cfg.switch_limit_config().ensure().overload_protection_mode() = + static_cast(*mode); + return ok( + fmt::format( + "Successfully set switch_limit_config overload_protection_mode to: {}", + *mode)); +} + +Result applyNetwork6(BgpConfig& cfg, const Tokens& values) { + // Usage: network6 add [policy ] [install-to-fib ] + // [min-routes ] + if (values.size() < 2 || values[0] != "add") { + return err( + "Error: usage: network6 add [policy ] " + "[install-to-fib ] [min-routes ]"); + } + std::string prefix = values[1]; + std::string policyName; + bool installToFib = false; + int32_t minSupportingRoutes = 0; + + for (size_t i = 2; i < values.size(); i++) { + if (values[i] == "policy" && i + 1 < values.size()) { + policyName = values[++i]; + } else if (values[i] == "install-to-fib" && i + 1 < values.size()) { + auto parsed = parseBool(values[++i]); + if (!parsed) { + return err( + fmt::format( + "Error: Invalid install-to-fib value '{}'; expected true or false", + values[i])); + } + installToFib = *parsed; + } else if (values[i] == "min-routes" && i + 1 < values.size()) { + auto parsed = parseNonNegInt32(values[++i]); + if (!parsed) { + return err( + fmt::format("Error: Invalid min-routes value '{}'", values[i])); + } + minSupportingRoutes = *parsed; + } else { + return err( + fmt::format("Error: unexpected network6 token '{}'", values[i])); + } + } + + // Find-or-update the networks6 entry keyed by prefix. + auto& networks = *cfg.networks6(); + bgp::thrift::BgpNetwork* entry = nullptr; + for (auto& n : networks) { + if (*n.prefix() == prefix) { + entry = &n; + break; + } + } + if (entry == nullptr) { + networks.emplace_back(); + entry = &networks.back(); + } + entry->prefix() = prefix; + entry->policy_name() = policyName; + entry->install_to_fib() = installToFib; + entry->minimum_supporting_routes() = minSupportingRoutes; + + return ok( + fmt::format( + "Successfully added network6 prefix: {} (policy: {}, install_to_fib: {}, " + "min_routes: {})", + prefix, + policyName.empty() ? "(none)" : policyName, + installToFib ? "true" : "false", + minSupportingRoutes)); +} + +using AttrHandler = std::function; + +const std::map& attrHandlers() { + static const std::map kHandlers = { + {kRouterId, applyRouterId}, + {kLocalAsn, applyLocalAsn}, + {kConfedAsn, applyConfedAsn}, + {kHoldTime, applyHoldTime}, + {kGracefulRestartTime, applyGracefulRestartTime}, + {kCountConfedsInAsPathLen, applyCountConfedsInAsPathLen}, + {kRibAllocatedPathIds, applyRibAllocatedPathIds}, + {kNetwork6, applyNetwork6}, + {kSwitchLimit, + [](BgpConfig& cfg, const Tokens& v) { + return applyInt64Limit( + cfg, + v, + kSwitchLimit, + "prefix_limit", + std::numeric_limits::max(), + [](BgpConfig& c, int64_t l) { + c.switch_limit_config().ensure().prefix_limit() = l; + }); + }}, + {kSwitchLimitTotalPath, + [](BgpConfig& cfg, const Tokens& v) { + return applyInt64Limit( + cfg, + v, + kSwitchLimitTotalPath, + "total_path_limit", + std::numeric_limits::max(), + [](BgpConfig& c, int64_t l) { + c.switch_limit_config().ensure().total_path_limit() = l; + }); + }}, + {kSwitchLimitMaxGoldenVips, + [](BgpConfig& cfg, const Tokens& v) { + // max_golden_vips is an i32 field; bound it so an out-of-range value + // is rejected rather than silently truncated by the static_cast. + return applyInt64Limit( + cfg, + v, + kSwitchLimitMaxGoldenVips, + "max_golden_vips", + std::numeric_limits::max(), + [](BgpConfig& c, int64_t l) { + c.switch_limit_config().ensure().max_golden_vips() = + static_cast(l); + }); + }}, + {kSwitchLimitOverloadProtectionMode, applyOverloadProtectionMode}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : attrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += std::string(name); + } + return out; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as InterfacesConfig / parseTokens). +BgpGlobalConfig::BgpGlobalConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + fmt::format( + "Error: attribute is required. Valid attributes: {}", + validAttrList())); + } + if (attrHandlers().find(v[0]) == attrHandlers().end()) { + throw std::invalid_argument( + fmt::format( + "Error: unknown global attribute '{}'. Valid attributes: {}", + v[0], + validAttrList())); + } + attr_ = v[0]; + values_.assign(v.begin() + 1, v.end()); +} + CmdConfigProtocolBgpGlobalTraits::RetType -CmdConfigProtocolBgpGlobal::queryClient(const HostInfo& /* hostInfo */) { - return "BGP global configuration. Use subcommands: router-id, local-asn, hold-time, graceful-restart, best-path, link-bw, nh-tracking, network-originate"; +CmdConfigProtocolBgpGlobal::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + + // The attribute is guaranteed valid: BgpGlobalConfig's constructor rejects + // an empty/unknown attribute before we get here. + auto handler = attrHandlers().find(args.attr()); + Result result = handler->second(session.getBgpConfig(), args.values()); + if (result.ok) { + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } + return result.message; } void CmdConfigProtocolBgpGlobal::printOutput(const RetType& output) { diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h index 0a6faa7a09fb6..2c64bc0d4d537 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h @@ -10,14 +10,50 @@ #pragma once +#include +#include +#include "CLI/App.hpp" #include "fboss/cli/fboss2/CmdHandler.h" #include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" namespace facebook::fboss { +// Parsed `config protocol bgp global [value ...]`, validated at +// construction. values() is greedy to keep network6's multi-token tail. +class BgpGlobalConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpGlobalConfig(std::vector v); + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string attr_; + std::vector values_; +}; + +// Single handler for the whole `config protocol bgp global` family. The +// attribute name is the first positional token and the remaining tokens are +// its value(s); dispatch and per-attribute parsing live in the .cpp so adding +// a new global tunable is a one-entry change rather than a new command class. struct CmdConfigProtocolBgpGlobalTraits : public WriteCommandTraits { using ParentCmd = CmdConfigProtocolBgp; - using ObjectArgType = std::monostate; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // Stop CLI11's parent-chain subcommand fallthrough from stealing value + // tokens that happen to match a sibling command name (e.g. a policy + // named "peer-group"); see CmdConfigProtocolBgpNeighborTraits. + cmd.positionals_at_end(); + cmd.add_option("args", args, " [value ...]"); + } + using ObjectArgType = BgpGlobalConfig; using RetType = std::string; }; @@ -28,7 +64,7 @@ class CmdConfigProtocolBgpGlobal : public CmdHandler< using ObjectArgType = CmdConfigProtocolBgpGlobalTraits::ObjectArgType; using RetType = CmdConfigProtocolBgpGlobalTraits::RetType; - RetType queryClient(const HostInfo& hostInfo); + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); void printOutput(const RetType& output); }; diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.cpp deleted file mode 100644 index ed1b541d0298f..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalClusterIdTraits::RetType -CmdConfigProtocolBgpGlobalClusterId::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& clusterIdList) { - auto& session = BgpConfigSession::getInstance(); - - if (clusterIdList.data().empty()) { - return "Error: cluster-id is required"; - } - - std::string clusterId = clusterIdList.data()[0]; - session.setClusterId(clusterId); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP cluster-id to: {}\nConfig saved to: {}", - clusterId, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalClusterId::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalClusterId, - CmdConfigProtocolBgpGlobalClusterIdTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h deleted file mode 100644 index 8345a5b485888..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalClusterId.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalClusterIdTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("ipAddrs", args, "IPv4 or IPv6 addr(s)"); - } - using ObjectArgType = utils::IPList; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalClusterId - : public CmdHandler< - CmdConfigProtocolBgpGlobalClusterId, - CmdConfigProtocolBgpGlobalClusterIdTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalClusterIdTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalClusterIdTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& clusterId); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.cpp deleted file mode 100644 index bcc6512e89a38..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalConfedAsnTraits::RetType -CmdConfigProtocolBgpGlobalConfedAsn::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& confedAsnMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (confedAsnMsg.data().empty()) { - return "Error: confed-asn value is required"; - } - - std::string asnStr = confedAsnMsg.data()[0]; - uint64_t confedAsn; - try { - confedAsn = folly::to(asnStr); - } catch (const std::exception& e) { - return fmt::format("Error: Invalid confed-asn '{}': {}", asnStr, e.what()); - } - - session.setConfedAsn(confedAsn); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP confederation AS number to: {}\nConfig saved to: {}", - confedAsn, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalConfedAsn::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalConfedAsn, - CmdConfigProtocolBgpGlobalConfedAsnTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h deleted file mode 100644 index 2020e1b4cb1f6..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalConfedAsn.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalConfedAsnTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalConfedAsn - : public CmdHandler< - CmdConfigProtocolBgpGlobalConfedAsn, - CmdConfigProtocolBgpGlobalConfedAsnTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalConfedAsnTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalConfedAsnTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& confedAsn); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.cpp deleted file mode 100644 index c526e68c97028..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalHoldTimeTraits::RetType -CmdConfigProtocolBgpGlobalHoldTime::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& holdTimeMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (holdTimeMsg.data().empty()) { - return "Error: hold-time value is required"; - } - - // Extract string and parse to uint32_t - std::string holdTimeStr = holdTimeMsg.data()[0]; - uint32_t holdTime; - try { - holdTime = folly::to(holdTimeStr); - } catch (const std::exception& e) { - return fmt::format( - "Error: Invalid hold-time value '{}': {}", holdTimeStr, e.what()); - } - - // Set the hold-time in the BGP config session - session.setHoldTime(holdTime); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP hold-time to: {} seconds\nConfig saved to: {}", - holdTime, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalHoldTime::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalHoldTime, - CmdConfigProtocolBgpGlobalHoldTimeTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h deleted file mode 100644 index 1db1004d320b3..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalHoldTime.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalHoldTimeTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalHoldTime - : public CmdHandler< - CmdConfigProtocolBgpGlobalHoldTime, - CmdConfigProtocolBgpGlobalHoldTimeTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpGlobalHoldTimeTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalHoldTimeTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& holdTime); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.cpp deleted file mode 100644 index 81a8571197a79..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalLocalAsnTraits::RetType -CmdConfigProtocolBgpGlobalLocalAsn::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& localAsnMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (localAsnMsg.data().empty()) { - return "Error: local-asn value is required"; - } - - // Extract string and parse to uint32_t - std::string asnStr = localAsnMsg.data()[0]; - uint32_t localAsn; - try { - localAsn = folly::to(asnStr); - } catch (const std::exception& e) { - return fmt::format( - "Error: Invalid local-asn value '{}': {}", asnStr, e.what()); - } - - // Set the local-asn in the BGP config session - session.setLocalAsn(localAsn); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP local-asn to: {}\nConfig saved to: {}", - localAsn, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalLocalAsn::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalLocalAsn, - CmdConfigProtocolBgpGlobalLocalAsnTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h deleted file mode 100644 index d39cc07e490bf..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalLocalAsn.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalLocalAsnTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalLocalAsn - : public CmdHandler< - CmdConfigProtocolBgpGlobalLocalAsn, - CmdConfigProtocolBgpGlobalLocalAsnTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpGlobalLocalAsnTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalLocalAsnTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& localAsn); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.cpp deleted file mode 100644 index 336f5f50f6f70..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalNetwork6AddTraits::RetType -CmdConfigProtocolBgpGlobalNetwork6Add::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& args) { - auto& session = BgpConfigSession::getInstance(); - - // args.data() returns a vector of strings - // Command: "config protocol bgp global network6 add [policy ] - // [install-to-fib ] [min-routes ]" - // After "network6", args contains: ["add", "", ...] - // So we need to skip tokens[0] which is "add" - const auto& tokens = args.data(); - - if (tokens.size() < 2) { - return "Error: prefix is required. Usage: network6 add [policy " - "] [install-to-fib ] [min-routes ]"; - } - - // tokens[0] is "add", tokens[1] is the actual prefix - std::string prefixStr = tokens[1]; - std::string policyName; - bool installToFib = false; - int32_t minSupportingRoutes = 0; - - // Start parsing optional args from index 2 - for (size_t i = 2; i < tokens.size(); i++) { - if (tokens[i] == "policy" && i + 1 < tokens.size()) { - policyName = tokens[++i]; - } else if (tokens[i] == "install-to-fib" && i + 1 < tokens.size()) { - std::string val = tokens[++i]; - installToFib = (val == "true" || val == "1"); - } else if (tokens[i] == "min-routes" && i + 1 < tokens.size()) { - std::string minRoutesStr = tokens[++i]; - try { - minSupportingRoutes = folly::to(minRoutesStr); - } catch (const std::exception& e) { - return fmt::format( - "Error: Invalid min-routes value '{}': {}", minRoutesStr, e.what()); - } - } - } - - session.addNetwork6(prefixStr, policyName, installToFib, minSupportingRoutes); - session.saveConfig(); - - return fmt::format( - "Successfully added network6 prefix: {} (policy: {}, install_to_fib: {}, min_routes: {})\nConfig saved to: {}", - prefixStr, - policyName.empty() ? "(none)" : policyName, - installToFib ? "true" : "false", - minSupportingRoutes, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalNetwork6Add::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalNetwork6Add, - CmdConfigProtocolBgpGlobalNetwork6AddTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h deleted file mode 100644 index 885e7b3e2b63a..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalNetwork6Add.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalNetwork6AddTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalNetwork6Add - : public CmdHandler< - CmdConfigProtocolBgpGlobalNetwork6Add, - CmdConfigProtocolBgpGlobalNetwork6AddTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalNetwork6AddTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalNetwork6AddTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.cpp deleted file mode 100644 index c7093026cd1e7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalRouterIdTraits::RetType -CmdConfigProtocolBgpGlobalRouterId::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& routerIdList) { - auto& session = BgpConfigSession::getInstance(); - - if (routerIdList.data().empty()) { - return "Error: router-id is required"; - } - - // Extract the first IP from the list as router-id - std::string routerId = routerIdList.data()[0]; - - // Set the router-id in the BGP config session - session.setRouterId(routerId); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP router-id to: {}\nConfig saved to: {}", - routerId, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalRouterId::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalRouterId, - CmdConfigProtocolBgpGlobalRouterIdTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h deleted file mode 100644 index dd2f2871144c5..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalRouterId.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalRouterIdTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("ipAddrs", args, "IPv4 or IPv6 addr(s)"); - } - using ObjectArgType = utils::IPList; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalRouterId - : public CmdHandler< - CmdConfigProtocolBgpGlobalRouterId, - CmdConfigProtocolBgpGlobalRouterIdTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpGlobalRouterIdTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpGlobalRouterIdTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& routerId); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.cpp deleted file mode 100644 index 6ef8c4fd536f5..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits::RetType -CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& limitStr) { - auto& session = BgpConfigSession::getInstance(); - - if (limitStr.data().empty()) { - return "Error: max-golden-vips value is required"; - } - - int64_t limit = std::stoll(limitStr.data()[0]); - - session.setSwitchLimitMaxGoldenVips(limit); - session.saveConfig(); - - return fmt::format( - "Successfully set switch_limit_config max_golden_vips to: {}\nConfig saved to: {}", - limit, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips, - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h deleted file mode 100644 index c28eab45fc3f9..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips - : public CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVips, - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits::ObjectArgType; - using RetType = - CmdConfigProtocolBgpGlobalSwitchLimitMaxGoldenVipsTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& limit); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.cpp deleted file mode 100644 index 78c634bf4bcd2..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits::RetType -CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& modeStr) { - auto& session = BgpConfigSession::getInstance(); - - if (modeStr.data().empty()) { - return "Error: overload-protection-mode value is required"; - } - - int32_t mode = std::stoi(modeStr.data()[0]); - - session.setSwitchLimitOverloadProtectionMode(mode); - session.saveConfig(); - - return fmt::format( - "Successfully set switch_limit_config overload_protection_mode to: {}\nConfig saved to: {}", - mode, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode, - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h deleted file mode 100644 index 2a155cf1460a4..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode - : public CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionMode, - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits:: - ObjectArgType; - using RetType = - CmdConfigProtocolBgpGlobalSwitchLimitOverloadProtectionModeTraits:: - RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& mode); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.cpp deleted file mode 100644 index 0241e189f6f1c..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits::RetType -CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& limitStr) { - auto& session = BgpConfigSession::getInstance(); - - // Command: "config protocol bgp global switch-limit " - // After "switch-limit", args contains just [""] - const auto& tokens = limitStr.data(); - if (tokens.empty()) { - return "Error: prefix-limit value is required. Usage: switch-limit "; - } - - int64_t limit = std::stoll(tokens[0]); - - session.setSwitchLimitPrefixLimit(limit); - session.saveConfig(); - - return fmt::format( - "Successfully set switch_limit_config prefix_limit to: {}\nConfig saved to: {}", - limit, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit, - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h deleted file mode 100644 index d6496f037c749..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit - : public CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimit, - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits::ObjectArgType; - using RetType = - CmdConfigProtocolBgpGlobalSwitchLimitPrefixLimitTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& limit); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.cpp deleted file mode 100644 index b0d67f57ec616..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits::RetType -CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& limitStr) { - auto& session = BgpConfigSession::getInstance(); - - if (limitStr.data().empty()) { - return "Error: total-path-limit value is required"; - } - - int64_t limit = std::stoll(limitStr.data()[0]); - - session.setSwitchLimitTotalPathLimit(limit); - session.saveConfig(); - - return fmt::format( - "Successfully set switch_limit_config total_path_limit to: {}\nConfig saved to: {}", - limit, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit, - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h b/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h deleted file mode 100644 index 23e702fa743d7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/global/CmdConfigProtocolBgpGlobal.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpGlobal; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit - : public CmdHandler< - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimit, - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits::ObjectArgType; - using RetType = - CmdConfigProtocolBgpGlobalSwitchLimitTotalPathLimitTraits::RetType; - - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& limit); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp new file mode 100644 index 0000000000000..06fec6544680b --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.cpp @@ -0,0 +1,583 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/fboss/bgp/if/gen-cpp2/bgp_attr_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" +#include "thrift/lib/cpp/Thrift.h" + +namespace facebook::fboss { + +namespace { + +// CLI attribute names, exactly as documented (two-token attributes keep their +// space). Kept here (not as raw string literals at the dispatch sites) so the +// valid-attribute set and the handler table stay in sync. +constexpr std::string_view kRemoteAsn = "remote-asn"; +constexpr std::string_view kLocalAsn = "local-asn"; +constexpr std::string_view kDescription = "description"; +constexpr std::string_view kPeerTag = "peer-tag"; +constexpr std::string_view kPeerGroup = "peer-group"; +constexpr std::string_view kIngressPolicy = "ingress-policy"; +constexpr std::string_view kEgressPolicy = "egress-policy"; +constexpr std::string_view kRrClient = "rr-client"; +constexpr std::string_view kConfedPeer = "confed-peer"; +constexpr std::string_view kRedistributePeer = "redistribute-peer"; +constexpr std::string_view kEnhancedRouteRefresh = "enhanced-route-refresh"; +constexpr std::string_view kConnectMode = "connect-mode"; +constexpr std::string_view kPeerPort = "peer-port"; +constexpr std::string_view kAddPathSend = "add-path send"; +constexpr std::string_view kAddPathReceive = "add-path receive"; +constexpr std::string_view kAfiDisableIpv4Afi = "afi disable-ipv4-afi"; +constexpr std::string_view kAfiDisableIpv6Afi = "afi disable-ipv6-afi"; +constexpr std::string_view kAfiIpv4OverIpv6Nh = "afi ipv4-over-ipv6-nh"; +constexpr std::string_view kAfiIpv4LabeledUnicast = "afi ipv4-labeled-unicast"; +constexpr std::string_view kAfiIpv6LabeledUnicast = "afi ipv6-labeled-unicast"; +constexpr std::string_view kBindAddrAddress = "bind-addr address"; +constexpr std::string_view kBindAddrPort = "bind-addr port"; +constexpr std::string_view kGracefulRestartTime = + "graceful-restart restart-time"; +constexpr std::string_view kGracefulRestartStatefulHa = + "graceful-restart stateful-ha"; +constexpr std::string_view kMaxRoutePreFilter = "max-route pre-filter"; +constexpr std::string_view kMaxRoutePostFilter = "max-route post-filter"; +constexpr std::string_view kMaxRoutePostWarningThreshold = + "max-route post-warning-threshold"; +constexpr std::string_view kTimersHoldTime = "timers hold-time"; +constexpr std::string_view kTimersKeepalive = "timers keepalive"; +constexpr std::string_view kTimersOutDelay = "timers out-delay"; +// Parity attributes: not in the documented neighbor grammar, but supported by +// the per-attribute peer commands this dispatcher replaces (and by real +// BgpPeer thrift fields), so dropping them would regress existing usage. +constexpr std::string_view kNextHop4 = "next-hop4"; +constexpr std::string_view kNextHop6 = "next-hop6"; +constexpr std::string_view kNextHopSelf = "next-hop-self"; +constexpr std::string_view kPeerId = "peer-id"; +constexpr std::string_view kPeerType = "type"; +constexpr std::string_view kLinkBandwidth = "link-bandwidth"; +constexpr std::string_view kAdvertiseLbw = "advertise-lbw"; +constexpr std::string_view kReceiveLbw = "receive-lbw"; +constexpr std::string_view kTimersWithdrawUnprogDelay = + "timers withdraw-unprog-delay"; +constexpr std::string_view kMaxRoutePreWarningThreshold = + "max-route pre-warning-threshold"; +constexpr std::string_view kMaxRoutePreWarningOnly = + "max-route pre-warning-only"; +constexpr std::string_view kMaxRoutePostWarningOnly = + "max-route post-warning-only"; + +// connect-mode values +constexpr std::string_view kConnectModePassive = "PASSIVE"; +constexpr std::string_view kConnectModeActive = "ACTIVE"; +constexpr std::string_view kConnectModeBoth = "BOTH"; + +using bgpcli::Tokens; +using BgpPeer = bgp::thrift::BgpPeer; +using bgpcli::asnAttr; +using bgpcli::AttrHandler; +using bgpcli::bitRateAttr; +using bgpcli::boolAttr; +using bgpcli::err; +using bgpcli::ipAttr; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::parseBool; +using bgpcli::rejectedAttr; +using bgpcli::Result; +using bgpcli::routeCountAttr; +using bgpcli::secondsAttr; +using bgpcli::stringAttr; +using bgpcli::thriftEnumAttr; +using facebook::neteng::fboss::bgp_attr::AddPath; +using facebook::neteng::fboss::bgp_attr::AdvertiseLinkBandwidth; +using facebook::neteng::fboss::bgp_attr::ReceiveLinkBandwidth; + +// ---- per-attribute setters ------------------------------------------------- +// Pure thrift assignment: no validation, no messages. Parsing, bounds and the +// user-facing text all live in the shared factories in BgpCliAttrHandlers.h, +// so a setter is just the field this attribute writes. Field names map 1:1 to +// bgp_config.thrift, so the compiler validates them. + +void setRemoteAsn(BgpPeer& p, int64_t v) { + p.remote_as_4_byte() = v; +} + +void setLocalAsn(BgpPeer& p, int64_t v) { + p.local_as_4_byte() = v; +} + +void setDescription(BgpPeer& p, const std::string& v) { + p.description() = v; +} + +void setPeerTag(BgpPeer& p, const std::string& v) { + p.peer_tag() = v; +} + +void setPeerGroup(BgpPeer& p, const std::string& v) { + p.peer_group_name() = v; +} + +void setIngressPolicy(BgpPeer& p, const std::string& v) { + p.ingress_policy_name() = v; +} + +void setEgressPolicy(BgpPeer& p, const std::string& v) { + p.egress_policy_name() = v; +} + +void setRrClient(BgpPeer& p, bool v) { + p.is_rr_client() = v; +} + +void setConfedPeer(BgpPeer& p, bool v) { + p.is_confed_peer() = v; +} + +void setRedistributePeer(BgpPeer& p, bool v) { + p.is_redistribute_peer() = v; +} + +void setEnhancedRouteRefresh(BgpPeer& p, bool v) { + p.enhanced_route_refresh() = v; +} + +void setDisableIpv4Afi(BgpPeer& p, bool v) { + p.disable_ipv4_afi() = v; +} + +void setDisableIpv6Afi(BgpPeer& p, bool v) { + p.disable_ipv6_afi() = v; +} + +void setIpv4OverIpv6Nh(BgpPeer& p, bool v) { + p.v4_over_v6_nexthop() = v; +} + +void setBindAddrAddress(BgpPeer& p, const std::string& v) { + p.local_addr() = v; +} + +void setGracefulRestartTime(BgpPeer& p, int32_t v) { + p.bgp_peer_timers().ensure().graceful_restart_seconds() = v; +} + +void setGracefulRestartStatefulHa(BgpPeer& p, bool v) { + p.enable_stateful_ha() = v; +} + +void setMaxRoutePreFilter(BgpPeer& p, int64_t v) { + p.pre_filter().ensure().max_routes() = v; +} + +void setMaxRoutePostFilter(BgpPeer& p, int64_t v) { + p.post_filter().ensure().max_routes() = v; +} + +// RouteLimit.warning_limit is an absolute route count in the thrift schema, +// not a percentage. +void setMaxRoutePreWarningThreshold(BgpPeer& p, int64_t v) { + p.pre_filter().ensure().warning_limit() = v; +} + +void setMaxRoutePostWarningThreshold(BgpPeer& p, int64_t v) { + p.post_filter().ensure().warning_limit() = v; +} + +void setMaxRoutePreWarningOnly(BgpPeer& p, bool v) { + p.pre_filter().ensure().warning_only() = v; +} + +void setMaxRoutePostWarningOnly(BgpPeer& p, bool v) { + p.post_filter().ensure().warning_only() = v; +} + +void setTimersHoldTime(BgpPeer& p, int32_t v) { + p.bgp_peer_timers().ensure().hold_time_seconds() = v; +} + +void setTimersKeepalive(BgpPeer& p, int32_t v) { + p.bgp_peer_timers().ensure().keep_alive_seconds() = v; +} + +void setTimersOutDelay(BgpPeer& p, int32_t v) { + p.bgp_peer_timers().ensure().out_delay_seconds() = v; +} + +void setTimersWithdrawUnprogDelay(BgpPeer& p, int32_t v) { + p.bgp_peer_timers().ensure().withdraw_unprog_delay_seconds() = v; +} + +void setNextHop4(BgpPeer& p, const std::string& v) { + p.next_hop4() = v; +} + +void setNextHop6(BgpPeer& p, const std::string& v) { + p.next_hop6() = v; +} + +void setNextHopSelf(BgpPeer& p, bool v) { + p.next_hop_self() = v; +} + +void setPeerId(BgpPeer& p, const std::string& v) { + p.peer_id() = v; +} + +void setPeerType(BgpPeer& p, const std::string& v) { + p.type() = v; +} + +void setLinkBandwidth(BgpPeer& p, const std::string& v) { + p.link_bandwidth_bps() = v; +} + +void setAdvertiseLbw(BgpPeer& p, AdvertiseLinkBandwidth v) { + p.advertise_link_bandwidth() = v; +} + +void setReceiveLbw(BgpPeer& p, ReceiveLinkBandwidth v) { + p.receive_link_bandwidth() = v; +} + +// ---- hand-written handlers ------------------------------------------------- +// Only for value shapes no factory covers, because the shape is unique to this +// attribute rather than reusable. + +// connect-mode: the thrift model only has is_passive (listen vs actively +// connect), so this is not an enum mapping — BOTH has no representation and is +// rejected with an explanation rather than silently mapped. +Result connectMode(BgpPeer& peer, const Tokens& values) { + if (values.size() != 1) { + return err( + fmt::format( + "Error: {} requires <{}|{}>", + kConnectMode, + kConnectModePassive, + kConnectModeActive)); + } + if (values[0] == kConnectModePassive) { + peer.is_passive() = true; + } else if (values[0] == kConnectModeActive) { + peer.is_passive() = false; + } else if (values[0] == kConnectModeBoth) { + return err( + fmt::format( + "Error: {} {} has no representation in bgp_config.thrift " + "(BgpPeer only models is_passive); use {} or {}", + kConnectMode, + kConnectModeBoth, + kConnectModePassive, + kConnectModeActive)); + } else { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected {} or {}", + kConnectMode, + values[0], + kConnectModePassive, + kConnectModeActive)); + } + return ok(fmt::format("Successfully set {} to: {}", kConnectMode, values[0])); +} + +// add-path send/receive: a boolean at the CLI, but the two attributes share +// one thrift field — add_path is a single enum whose values form a bitmask by +// design (RECEIVE=1, SEND=2, BOTH=3). Each takes the boolAttr text but merges +// its direction into the current value instead of overwriting it; clearing the +// last direction unsets the field. +Result applyAddPath(BgpPeer& peer, bool send, const Tokens& values) { + const std::string_view name = send ? kAddPathSend : kAddPathReceive; + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto enable = parseBool(values[0]); + if (!enable) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected true or false", + name, + values[0])); + } + int bits = peer.add_path() ? static_cast(*peer.add_path()) : 0; + const int bit = send ? static_cast(AddPath::SEND) + : static_cast(AddPath::RECEIVE); + bits = *enable ? (bits | bit) : (bits & ~bit); + if (bits == 0) { + peer.add_path().reset(); + } else { + peer.add_path() = static_cast(bits); + } + return ok( + fmt::format( + "Successfully {} {}", *enable ? "enabled" : "disabled", name)); +} + +Result addPathSend(BgpPeer& peer, const Tokens& values) { + return applyAddPath(peer, /* send */ true, values); +} + +Result addPathReceive(BgpPeer& peer, const Tokens& values) { + return applyAddPath(peer, /* send */ false, values); +} + +// ---- the dispatch table ---------------------------------------------------- +// One line per attribute: dispatch key, value shape, setter. There are no +// handler bodies here by design — if an attribute appears to need one, its +// value shape is missing a factory and the fix is to add the factory. + +constexpr std::string_view kNoPeerPortField = + "BgpPeer has no per-neighbor port field; the daemon listens on the global " + "listen_port"; +constexpr std::string_view kNoLabeledUnicastField = + "bgp_config.thrift has no labeled-unicast field on BgpPeer"; + +const std::map, std::less<>>& attrHandlers() { + static const std::map, std::less<>> + kHandlers = { + {std::string(kRemoteAsn), asnAttr(kRemoteAsn, setRemoteAsn)}, + {std::string(kLocalAsn), asnAttr(kLocalAsn, setLocalAsn)}, + {std::string(kDescription), + joinedStringAttr(kDescription, setDescription)}, + {std::string(kPeerTag), + stringAttr(kPeerTag, "string", setPeerTag)}, + {std::string(kPeerGroup), + stringAttr(kPeerGroup, "name", setPeerGroup)}, + {std::string(kIngressPolicy), + stringAttr( + kIngressPolicy, "policy-name", setIngressPolicy)}, + {std::string(kEgressPolicy), + stringAttr(kEgressPolicy, "policy-name", setEgressPolicy)}, + {std::string(kRrClient), boolAttr(kRrClient, setRrClient)}, + {std::string(kConfedPeer), + boolAttr(kConfedPeer, setConfedPeer)}, + {std::string(kRedistributePeer), + boolAttr(kRedistributePeer, setRedistributePeer)}, + {std::string(kEnhancedRouteRefresh), + boolAttr(kEnhancedRouteRefresh, setEnhancedRouteRefresh)}, + {std::string(kConnectMode), connectMode}, + {std::string(kPeerPort), + rejectedAttr(kPeerPort, kNoPeerPortField)}, + {std::string(kAddPathSend), addPathSend}, + {std::string(kAddPathReceive), addPathReceive}, + {std::string(kAfiDisableIpv4Afi), + boolAttr(kAfiDisableIpv4Afi, setDisableIpv4Afi)}, + {std::string(kAfiDisableIpv6Afi), + boolAttr(kAfiDisableIpv6Afi, setDisableIpv6Afi)}, + {std::string(kAfiIpv4OverIpv6Nh), + boolAttr(kAfiIpv4OverIpv6Nh, setIpv4OverIpv6Nh)}, + {std::string(kAfiIpv4LabeledUnicast), + rejectedAttr( + kAfiIpv4LabeledUnicast, kNoLabeledUnicastField)}, + {std::string(kAfiIpv6LabeledUnicast), + rejectedAttr( + kAfiIpv6LabeledUnicast, kNoLabeledUnicastField)}, + {std::string(kBindAddrAddress), + ipAttr(kBindAddrAddress, setBindAddrAddress)}, + {std::string(kBindAddrPort), + rejectedAttr(kBindAddrPort, kNoPeerPortField)}, + {std::string(kGracefulRestartTime), + secondsAttr(kGracefulRestartTime, setGracefulRestartTime)}, + {std::string(kGracefulRestartStatefulHa), + boolAttr( + kGracefulRestartStatefulHa, setGracefulRestartStatefulHa)}, + {std::string(kMaxRoutePreFilter), + routeCountAttr(kMaxRoutePreFilter, setMaxRoutePreFilter)}, + {std::string(kMaxRoutePostFilter), + routeCountAttr(kMaxRoutePostFilter, setMaxRoutePostFilter)}, + {std::string(kMaxRoutePreWarningThreshold), + routeCountAttr( + kMaxRoutePreWarningThreshold, setMaxRoutePreWarningThreshold)}, + {std::string(kMaxRoutePostWarningThreshold), + routeCountAttr( + kMaxRoutePostWarningThreshold, setMaxRoutePostWarningThreshold)}, + {std::string(kMaxRoutePreWarningOnly), + boolAttr( + kMaxRoutePreWarningOnly, setMaxRoutePreWarningOnly)}, + {std::string(kMaxRoutePostWarningOnly), + boolAttr( + kMaxRoutePostWarningOnly, setMaxRoutePostWarningOnly)}, + {std::string(kTimersHoldTime), + secondsAttr(kTimersHoldTime, setTimersHoldTime)}, + {std::string(kTimersKeepalive), + secondsAttr(kTimersKeepalive, setTimersKeepalive)}, + {std::string(kTimersOutDelay), + secondsAttr(kTimersOutDelay, setTimersOutDelay)}, + {std::string(kTimersWithdrawUnprogDelay), + secondsAttr( + kTimersWithdrawUnprogDelay, setTimersWithdrawUnprogDelay)}, + {std::string(kNextHop4), + ipAttr(kNextHop4, setNextHop4, /* requireV6 */ false)}, + {std::string(kNextHop6), + ipAttr(kNextHop6, setNextHop6, /* requireV6 */ true)}, + {std::string(kNextHopSelf), + boolAttr(kNextHopSelf, setNextHopSelf)}, + {std::string(kPeerId), + stringAttr(kPeerId, "string", setPeerId)}, + {std::string(kPeerType), + stringAttr(kPeerType, "string", setPeerType)}, + {std::string(kLinkBandwidth), + bitRateAttr(kLinkBandwidth, setLinkBandwidth)}, + {std::string(kAdvertiseLbw), + thriftEnumAttr( + kAdvertiseLbw, setAdvertiseLbw)}, + {std::string(kReceiveLbw), + thriftEnumAttr( + kReceiveLbw, setReceiveLbw)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : attrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +// Find the peer keyed by (normalized) peer_addr, creating it if absent. +// Setting an attribute on a not-yet-created neighbor implicitly creates it, +// so command ordering stays forgiving; a bare `neighbor ` creates one +// explicitly. +bgp::thrift::BgpPeer& findOrCreatePeer( + bgp::thrift::BgpConfig& cfg, + const std::string& peerAddr) { + auto& peers = *cfg.peers(); + if (auto it = bgpcli::findBgpPeer(cfg, peerAddr); it != peers.end()) { + return *it; + } + peers.emplace_back(); + auto& peer = peers.back(); + peer.peer_addr() = peerAddr; + // local_addr / next_hop4 / next_hop6 are non-optional thrift fields that + // bgpd parses with folly::IPAddress at config load — an empty string makes + // the daemon abort (IPAddressFormatException) before serving any config. + // Seed them with the unspecified address of the right family; the user + // overrides them via `bind-addr address` / `next-hop4` / `next-hop6`. + const bool isV6 = peerAddr.find(':') != std::string::npos; + peer.local_addr() = isV6 ? "::" : "0.0.0.0"; + peer.next_hop4() = "0.0.0.0"; + peer.next_hop6() = "::"; + return peer; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpGlobalConfig). +BgpNeighborConfig::BgpNeighborConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + "Error: neighbor is required, followed by an optional " + " "); + } + auto normalized = bgpcli::normalizeBgpPeerAddr(v[0]); + if (!normalized) { + throw std::invalid_argument( + fmt::format("Error: Invalid neighbor address '{}'", v[0])); + } + peerAddr_ = std::move(*normalized); + + if (v.size() == 1) { + return; // bare `neighbor `: create the peer + } + + // Attributes may span two tokens (e.g. `timers hold-time`); match the + // longest prefix of the remaining tokens against the dispatch table. + const auto& handlers = attrHandlers(); + if (v.size() >= 3) { + std::string twoToken = v[1] + " " + v[2]; + if (handlers.find(twoToken) != handlers.end()) { + attr_ = std::move(twoToken); + values_.assign(v.begin() + 3, v.end()); + return; + } + } + if (handlers.find(v[1]) != handlers.end()) { + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + return; + } + throw std::invalid_argument( + fmt::format( + "Error: unknown neighbor attribute '{}'. Valid attributes: {}", + v[1], + validAttrList())); +} + +CmdConfigProtocolBgpNeighborTraits::RetType +CmdConfigProtocolBgpNeighbor::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool created = + bgpcli::findBgpPeer(cfg, args.peerAddr()) == cfg.peers()->end(); + auto& peer = findOrCreatePeer(cfg, args.peerAddr()); + + Result result = args.attr().empty() + ? ok(fmt::format("Successfully created BGP neighbor {}", args.peerAddr())) + // The attribute is guaranteed valid: BgpNeighborConfig's constructor + // rejects an unknown attribute before we get here. + : attrHandlers().find(args.attr())->second(peer, args.values()); + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format(" for neighbor {}", args.peerAddr()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else if (created) { + // A rejected value must not leave a half-created peer in the in-memory + // config (visible to later lookups in the same process, e.g. tests). + cfg.peers()->pop_back(); + } + return result.message; +} + +void CmdConfigProtocolBgpNeighbor::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdConfigProtocolBgpNeighbor, + CmdConfigProtocolBgpNeighborTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h b/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h new file mode 100644 index 0000000000000..7b15488692b42 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `config protocol bgp neighbor [ ...]`, +// validated at construction. The neighbor address is normalized via +// folly::IPAddress so different spellings of the same address (e.g. +// 2001:DB8::1 vs 2001:db8::1) key the same peer. Attributes may span two +// tokens (e.g. `timers hold-time`); the dispatch table is matched +// longest-prefix-first. A bare `neighbor ` (no attribute) creates the +// peer. +class BgpNeighborConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpNeighborConfig(std::vector v); + const std::string& peerAddr() const { + return peerAddr_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string peerAddr_; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// Single handler for the whole `config protocol bgp neighbor` family. The +// first positional token is the neighbor address, the next one or two tokens +// name the attribute, and the remaining tokens are its value(s); dispatch and +// per-attribute parsing live in the .cpp so adding a new neighbor tunable is +// a one-entry change rather than a new command class. Mirrors +// CmdConfigProtocolBgpGlobal. +struct CmdConfigProtocolBgpNeighborTraits : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgp; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // positionals_at_end: once the first positional (the neighbor address, + // which never collides with a command name) is consumed, CLI11 stops + // classifying later tokens as subcommands. Without this, an attribute + // token that matches a sibling command name (e.g. `peer-group`) is + // stolen by CLI11's parent-chain subcommand fallthrough and the + // remaining tokens are misparsed. + cmd.positionals_at_end(); + cmd.add_option("args", args, " [ ...]"); + } + using ObjectArgType = BgpNeighborConfig; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpNeighbor : public CmdHandler< + CmdConfigProtocolBgpNeighbor, + CmdConfigProtocolBgpNeighborTraits> { + public: + using ObjectArgType = CmdConfigProtocolBgpNeighborTraits::ObjectArgType; + using RetType = CmdConfigProtocolBgpNeighborTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp index 9fdb301293a89..a9eede5cdd694 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.cpp @@ -13,30 +13,480 @@ #include "fboss/cli/fboss2/CmdHandler.cpp" #include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/fboss/bgp/if/gen-cpp2/bgp_attr_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" namespace facebook::fboss { +namespace { + +// CLI attribute names, exactly as documented (two-token attributes keep their +// space). Kept here (not as raw string literals at the dispatch sites) so the +// valid-attribute set and the handler table stay in sync. +constexpr std::string_view kRemoteAsn = "remote-asn"; +constexpr std::string_view kLocalAsn = "local-asn"; +constexpr std::string_view kDescription = "description"; +constexpr std::string_view kPeerTag = "peer-tag"; +constexpr std::string_view kIngressPolicy = "ingress-policy"; +constexpr std::string_view kEgressPolicy = "egress-policy"; +constexpr std::string_view kRrClient = "rr-client"; +constexpr std::string_view kRedistributePeer = "redistribute-peer"; +constexpr std::string_view kEnhancedRouteRefresh = "enhanced-route-refresh"; +constexpr std::string_view kConnectMode = "connect-mode"; +constexpr std::string_view kAddPathSend = "add-path send"; +constexpr std::string_view kAddPathReceive = "add-path receive"; +constexpr std::string_view kAfiDisableIpv4Afi = "afi disable-ipv4-afi"; +constexpr std::string_view kAfiDisableIpv6Afi = "afi disable-ipv6-afi"; +constexpr std::string_view kAfiIpv4OverIpv6Nh = "afi ipv4-over-ipv6-nh"; +constexpr std::string_view kGracefulRestartTime = + "graceful-restart restart-time"; +constexpr std::string_view kGracefulRestartStatefulHa = + "graceful-restart stateful-ha"; +constexpr std::string_view kMaxRoutePreFilter = "max-route pre-filter"; +constexpr std::string_view kMaxRoutePostFilter = "max-route post-filter"; +constexpr std::string_view kMaxRoutePostWarningThreshold = + "max-route post-warning-threshold"; +constexpr std::string_view kTimersHoldTime = "timers hold-time"; +constexpr std::string_view kTimersKeepalive = "timers keepalive"; +constexpr std::string_view kTimersOutDelay = "timers out-delay"; +// Parity attributes: not in the documented peer-group grammar, but supported +// by the per-attribute peer-group commands this dispatcher replaces (and by +// real PeerGroup thrift fields), so dropping them would regress existing +// usage. +constexpr std::string_view kConfedPeer = "confed-peer"; +constexpr std::string_view kNextHopSelf = "next-hop-self"; +constexpr std::string_view kTimersWithdrawUnprogDelay = + "timers withdraw-unprog-delay"; +constexpr std::string_view kMaxRoutePreWarningThreshold = + "max-route pre-warning-threshold"; +constexpr std::string_view kMaxRoutePreWarningOnly = + "max-route pre-warning-only"; +constexpr std::string_view kMaxRoutePostWarningOnly = + "max-route post-warning-only"; + +// connect-mode values +constexpr std::string_view kConnectModePassive = "PASSIVE"; +constexpr std::string_view kConnectModeActive = "ACTIVE"; +constexpr std::string_view kConnectModeBoth = "BOTH"; + +using PeerGroup = bgp::thrift::PeerGroup; +using bgpcli::asnAttr; +using bgpcli::AttrHandler; +using bgpcli::boolAttr; +using bgpcli::err; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::parseBool; +using bgpcli::Result; +using bgpcli::routeCountAttr; +using bgpcli::secondsAttr; +using bgpcli::stringAttr; +using bgpcli::Tokens; +using facebook::neteng::fboss::bgp_attr::AddPath; + +// ---- per-attribute setters ------------------------------------------------- +// Pure thrift assignment: no validation, no messages. Parsing, bounds and the +// user-facing text all live in the shared factories in BgpCliAttrHandlers.h, +// so a setter is just the field this attribute writes. Field names map 1:1 to +// bgp_config.thrift, so the compiler validates them. + +void setRemoteAsn(PeerGroup& g, int64_t v) { + g.remote_as_4_byte() = v; +} + +void setLocalAsn(PeerGroup& g, int64_t v) { + g.local_as_4_byte() = v; +} + +void setDescription(PeerGroup& g, const std::string& v) { + g.description() = v; +} + +void setPeerTag(PeerGroup& g, const std::string& v) { + g.peer_tag() = v; +} + +void setIngressPolicy(PeerGroup& g, const std::string& v) { + g.ingress_policy_name() = v; +} + +void setEgressPolicy(PeerGroup& g, const std::string& v) { + g.egress_policy_name() = v; +} + +void setRrClient(PeerGroup& g, bool v) { + g.is_rr_client() = v; +} + +void setConfedPeer(PeerGroup& g, bool v) { + g.is_confed_peer() = v; +} + +void setRedistributePeer(PeerGroup& g, bool v) { + g.is_redistribute_peer() = v; +} + +void setEnhancedRouteRefresh(PeerGroup& g, bool v) { + g.enhanced_route_refresh() = v; +} + +void setDisableIpv4Afi(PeerGroup& g, bool v) { + g.disable_ipv4_afi() = v; +} + +void setDisableIpv6Afi(PeerGroup& g, bool v) { + g.disable_ipv6_afi() = v; +} + +void setIpv4OverIpv6Nh(PeerGroup& g, bool v) { + g.v4_over_v6_nexthop() = v; +} + +void setGracefulRestartTime(PeerGroup& g, int32_t v) { + g.bgp_peer_timers().ensure().graceful_restart_seconds() = v; +} + +void setGracefulRestartStatefulHa(PeerGroup& g, bool v) { + g.enable_stateful_ha() = v; +} + +void setMaxRoutePreFilter(PeerGroup& g, int64_t v) { + g.pre_filter().ensure().max_routes() = v; +} + +void setMaxRoutePostFilter(PeerGroup& g, int64_t v) { + g.post_filter().ensure().max_routes() = v; +} + +// RouteLimit.warning_limit is an absolute route count in the thrift schema, +// not a percentage. +void setMaxRoutePreWarningThreshold(PeerGroup& g, int64_t v) { + g.pre_filter().ensure().warning_limit() = v; +} + +void setMaxRoutePostWarningThreshold(PeerGroup& g, int64_t v) { + g.post_filter().ensure().warning_limit() = v; +} + +void setMaxRoutePreWarningOnly(PeerGroup& g, bool v) { + g.pre_filter().ensure().warning_only() = v; +} + +void setMaxRoutePostWarningOnly(PeerGroup& g, bool v) { + g.post_filter().ensure().warning_only() = v; +} + +void setTimersHoldTime(PeerGroup& g, int32_t v) { + g.bgp_peer_timers().ensure().hold_time_seconds() = v; +} + +void setTimersKeepalive(PeerGroup& g, int32_t v) { + g.bgp_peer_timers().ensure().keep_alive_seconds() = v; +} + +void setTimersOutDelay(PeerGroup& g, int32_t v) { + g.bgp_peer_timers().ensure().out_delay_seconds() = v; +} + +void setTimersWithdrawUnprogDelay(PeerGroup& g, int32_t v) { + g.bgp_peer_timers().ensure().withdraw_unprog_delay_seconds() = v; +} + +void setNextHopSelf(PeerGroup& g, bool v) { + g.next_hop_self() = v; +} + +// ---- hand-written handlers ------------------------------------------------- +// Only for value shapes no factory covers, because the shape is unique to this +// attribute rather than reusable. Both mirror the neighbor dispatcher's +// versions, which write the identically-named BgpPeer fields. + +// connect-mode: the thrift model only has is_passive (listen vs actively +// connect), so this is not an enum mapping — BOTH has no representation and is +// rejected with an explanation rather than silently mapped. +Result connectMode(PeerGroup& group, const Tokens& values) { + if (values.size() != 1) { + return err( + fmt::format( + "Error: {} requires <{}|{}>", + kConnectMode, + kConnectModePassive, + kConnectModeActive)); + } + if (values[0] == kConnectModePassive) { + group.is_passive() = true; + } else if (values[0] == kConnectModeActive) { + group.is_passive() = false; + } else if (values[0] == kConnectModeBoth) { + return err( + fmt::format( + "Error: {} {} has no representation in bgp_config.thrift " + "(PeerGroup only models is_passive); use {} or {}", + kConnectMode, + kConnectModeBoth, + kConnectModePassive, + kConnectModeActive)); + } else { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected {} or {}", + kConnectMode, + values[0], + kConnectModePassive, + kConnectModeActive)); + } + return ok(fmt::format("Successfully set {} to: {}", kConnectMode, values[0])); +} + +// add-path send/receive: a boolean at the CLI, but the two attributes share +// one thrift field — add_path is a single enum whose values form a bitmask by +// design (RECEIVE=1, SEND=2, BOTH=3). Each takes the boolAttr text but merges +// its direction into the current value instead of overwriting it; clearing the +// last direction unsets the field. +Result applyAddPath(PeerGroup& group, bool send, const Tokens& values) { + const std::string_view name = send ? kAddPathSend : kAddPathReceive; + if (values.size() != 1) { + return err(fmt::format("Error: {} requires ", name)); + } + auto enable = parseBool(values[0]); + if (!enable) { + return err( + fmt::format( + "Error: Invalid {} value '{}'; expected true or false", + name, + values[0])); + } + int bits = group.add_path() ? static_cast(*group.add_path()) : 0; + const int bit = send ? static_cast(AddPath::SEND) + : static_cast(AddPath::RECEIVE); + bits = *enable ? (bits | bit) : (bits & ~bit); + if (bits == 0) { + group.add_path().reset(); + } else { + group.add_path() = static_cast(bits); + } + return ok( + fmt::format( + "Successfully {} {}", *enable ? "enabled" : "disabled", name)); +} + +Result addPathSend(PeerGroup& group, const Tokens& values) { + return applyAddPath(group, /* send */ true, values); +} + +Result addPathReceive(PeerGroup& group, const Tokens& values) { + return applyAddPath(group, /* send */ false, values); +} + +// ---- the dispatch table ---------------------------------------------------- +// One line per attribute: dispatch key, value shape, setter. There are no +// handler bodies here by design — if an attribute appears to need one, its +// value shape is missing a factory and the fix is to add the factory. + +const std::map, std::less<>>& +attrHandlers() { + static const std::map, std::less<>> + kHandlers = { + {std::string(kRemoteAsn), + asnAttr(kRemoteAsn, setRemoteAsn)}, + {std::string(kLocalAsn), asnAttr(kLocalAsn, setLocalAsn)}, + {std::string(kDescription), + joinedStringAttr(kDescription, setDescription)}, + {std::string(kPeerTag), + stringAttr(kPeerTag, "string", setPeerTag)}, + {std::string(kIngressPolicy), + stringAttr( + kIngressPolicy, "policy-name", setIngressPolicy)}, + {std::string(kEgressPolicy), + stringAttr( + kEgressPolicy, "policy-name", setEgressPolicy)}, + {std::string(kRrClient), boolAttr(kRrClient, setRrClient)}, + {std::string(kConfedPeer), + boolAttr(kConfedPeer, setConfedPeer)}, + {std::string(kRedistributePeer), + boolAttr(kRedistributePeer, setRedistributePeer)}, + {std::string(kEnhancedRouteRefresh), + boolAttr(kEnhancedRouteRefresh, setEnhancedRouteRefresh)}, + {std::string(kConnectMode), connectMode}, + {std::string(kAddPathSend), addPathSend}, + {std::string(kAddPathReceive), addPathReceive}, + {std::string(kAfiDisableIpv4Afi), + boolAttr(kAfiDisableIpv4Afi, setDisableIpv4Afi)}, + {std::string(kAfiDisableIpv6Afi), + boolAttr(kAfiDisableIpv6Afi, setDisableIpv6Afi)}, + {std::string(kAfiIpv4OverIpv6Nh), + boolAttr(kAfiIpv4OverIpv6Nh, setIpv4OverIpv6Nh)}, + {std::string(kGracefulRestartTime), + secondsAttr( + kGracefulRestartTime, setGracefulRestartTime)}, + {std::string(kGracefulRestartStatefulHa), + boolAttr( + kGracefulRestartStatefulHa, setGracefulRestartStatefulHa)}, + {std::string(kMaxRoutePreFilter), + routeCountAttr(kMaxRoutePreFilter, setMaxRoutePreFilter)}, + {std::string(kMaxRoutePostFilter), + routeCountAttr( + kMaxRoutePostFilter, setMaxRoutePostFilter)}, + {std::string(kMaxRoutePreWarningThreshold), + routeCountAttr( + kMaxRoutePreWarningThreshold, setMaxRoutePreWarningThreshold)}, + {std::string(kMaxRoutePostWarningThreshold), + routeCountAttr( + kMaxRoutePostWarningThreshold, setMaxRoutePostWarningThreshold)}, + {std::string(kMaxRoutePreWarningOnly), + boolAttr( + kMaxRoutePreWarningOnly, setMaxRoutePreWarningOnly)}, + {std::string(kMaxRoutePostWarningOnly), + boolAttr( + kMaxRoutePostWarningOnly, setMaxRoutePostWarningOnly)}, + {std::string(kTimersHoldTime), + secondsAttr(kTimersHoldTime, setTimersHoldTime)}, + {std::string(kTimersKeepalive), + secondsAttr(kTimersKeepalive, setTimersKeepalive)}, + {std::string(kTimersOutDelay), + secondsAttr(kTimersOutDelay, setTimersOutDelay)}, + {std::string(kTimersWithdrawUnprogDelay), + secondsAttr( + kTimersWithdrawUnprogDelay, setTimersWithdrawUnprogDelay)}, + {std::string(kNextHopSelf), + boolAttr(kNextHopSelf, setNextHopSelf)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : attrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +// Find the peer-group keyed by name, creating it if absent. Setting an +// attribute on a not-yet-created group implicitly creates it, so command +// ordering stays forgiving; a bare `peer-group ` creates one explicitly. +// Unlike a BgpPeer, PeerGroup's only non-optional field is `name`, so no +// address seeding is needed. +bgp::thrift::PeerGroup& findOrCreatePeerGroup( + bgp::thrift::BgpConfig& cfg, + const std::string& groupName) { + auto& groups = cfg.peer_groups().ensure(); + for (auto& group : groups) { + if (*group.name() == groupName) { + return group; + } + } + groups.emplace_back(); + auto& group = groups.back(); + group.name() = groupName; + return group; +} + +// Whether a peer-group with the given name already exists. +bool peerGroupExists( + const bgp::thrift::BgpConfig& cfg, + const std::string& groupName) { + if (!cfg.peer_groups().has_value()) { + return false; + } + for (const auto& group : *cfg.peer_groups()) { + if (*group.name() == groupName) { + return true; + } + } + return false; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpNeighborConfig). +BgpPeerGroupConfig::BgpPeerGroupConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + "Error: peer-group is required, followed by an optional " + " "); + } + if (v[0].empty()) { + throw std::invalid_argument("Error: peer-group name must not be empty"); + } + groupName_ = v[0]; + + if (v.size() == 1) { + return; // bare `peer-group `: create the group + } + + // Attributes may span two tokens (e.g. `timers hold-time`); match the + // longest prefix of the remaining tokens against the dispatch table. + const auto& handlers = attrHandlers(); + if (v.size() >= 3) { + std::string twoToken = v[1] + " " + v[2]; + if (handlers.find(twoToken) != handlers.end()) { + attr_ = std::move(twoToken); + values_.assign(v.begin() + 3, v.end()); + return; + } + } + if (handlers.find(v[1]) != handlers.end()) { + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + return; + } + throw std::invalid_argument( + fmt::format( + "Error: unknown peer-group attribute '{}'. Valid attributes: {}", + v[1], + validAttrList())); +} + CmdConfigProtocolBgpPeerGroupTraits::RetType CmdConfigProtocolBgpPeerGroup::queryClient( const HostInfo& /* hostInfo */, - const ObjectArgType& groupNameMsg) { - auto& session = BgpConfigSession::getInstance(); + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool created = !peerGroupExists(cfg, args.groupName()); + auto& group = findOrCreatePeerGroup(cfg, args.groupName()); - if (groupNameMsg.data().empty()) { - return "Error: peer-group name is required"; + Result result = args.attr().empty() + ? ok(fmt::format( + "Successfully created BGP peer-group {}", args.groupName())) + // The attribute is guaranteed valid: BgpPeerGroupConfig's constructor + // rejects an unknown attribute before we get here. + : attrHandlers().find(args.attr())->second(group, args.values()); + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format(" for peer-group {}", args.groupName()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else if (created) { + // A rejected value must not leave a half-created group in the in-memory + // config (visible to later lookups in the same process, e.g. tests). + cfg.peer_groups()->pop_back(); } - - std::string groupName = groupNameMsg.data()[0]; - session.createPeerGroup(groupName); - session.saveConfig(); - - return fmt::format( - "BGP peer-group {} created.\n" - "Use subcommands: remote-asn, description, hold-time, keepalive\n" - "Config saved to: {}", - groupName, - session.getSessionConfigPath()); + return result.message; } void CmdConfigProtocolBgpPeerGroup::printOutput(const RetType& output) { diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h index 1c6d74e0f375a..1eca3e696eff3 100644 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h @@ -10,18 +10,54 @@ #pragma once +#include +#include +#include "CLI/App.hpp" #include "fboss/cli/fboss2/CmdHandler.h" #include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" namespace facebook::fboss { +// Parsed `peer-group [ ...]`, validated at +// construction. Attributes may span two tokens (e.g. `timers hold-time`), +// matched longest-prefix-first. Bare `peer-group ` creates the group. +// Mirrors BgpNeighborConfig. +class BgpPeerGroupConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpPeerGroupConfig(std::vector v); + const std::string& groupName() const { + return groupName_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string groupName_; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// Single handler for the whole `config protocol bgp peer-group` family; +// dispatch and per-attribute parsing live in the .cpp so a new tunable is a +// one-entry change. Mirrors CmdConfigProtocolBgpNeighbor. struct CmdConfigProtocolBgpPeerGroupTraits : public WriteCommandTraits { using ParentCmd = CmdConfigProtocolBgp; static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); + // Stops CLI11 from classifying attribute tokens as subcommands once the + // group name is consumed. See CmdConfigProtocolBgpNeighborTraits. + cmd.positionals_at_end(); + cmd.add_option("args", args, " [ ...]"); } - using ObjectArgType = utils::Message; + using ObjectArgType = BgpPeerGroupConfig; using RetType = std::string; }; @@ -32,7 +68,7 @@ class CmdConfigProtocolBgpPeerGroup : public CmdHandler< using ObjectArgType = CmdConfigProtocolBgpPeerGroupTraits::ObjectArgType; using RetType = CmdConfigProtocolBgpPeerGroupTraits::RetType; - RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& groupName); + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); void printOutput(const RetType& output); }; diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.cpp deleted file mode 100644 index 13b8c1bd31e76..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupConfedPeerTraits::RetType -CmdConfigProtocolBgpPeerGroupConfedPeer::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value required for peer-group '{}'", peerGroupName); - } - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeerGroup(peerGroupName); - session.setPeerGroupConfedPeer(peerGroupName, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} confederation-peer for peer-group '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupConfedPeer::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupConfedPeer, - CmdConfigProtocolBgpPeerGroupConfedPeerTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h deleted file mode 100644 index 32fb0f19c28a6..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupConfedPeer.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupConfedPeerTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupConfedPeer - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupConfedPeer, - CmdConfigProtocolBgpPeerGroupConfedPeerTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupConfedPeerTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupConfedPeerTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.cpp deleted file mode 100644 index f316e3477be66..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupDescriptionTraits::RetType -CmdConfigProtocolBgpPeerGroupDescription::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameMsg, - const ObjectArgType& descriptionMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - if (descriptionMsg.data().empty()) { - return "Error: description is required"; - } - - std::string groupName = groupNameMsg.data()[0]; - std::string description = descriptionMsg.data()[0]; - - session.setPeerGroupDescription(groupName, description); - session.saveConfig(); - - return fmt::format( - "Successfully set peer-group {} description to: {}\nConfig saved to: {}", - groupName, - description, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupDescription::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupDescription, - CmdConfigProtocolBgpPeerGroupDescriptionTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h deleted file mode 100644 index 37ee936eeaaa1..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDescription.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupDescriptionTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupDescription - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupDescription, - CmdConfigProtocolBgpPeerGroupDescriptionTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupDescriptionTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupDescriptionTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& groupName, - const ObjectArgType& description); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.cpp deleted file mode 100644 index 0ab361e4cbeb7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits::RetType -CmdConfigProtocolBgpPeerGroupDisableIpv4Afi::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& disableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (disableMsg.data().empty()) { - return fmt::format( - "Error: disable value required for peer-group '{}'", peerGroupName); - } - std::string disableStr = disableMsg.data()[0]; - bool disable = - (disableStr == "true" || disableStr == "1" || disableStr == "yes"); - - session.createPeerGroup(peerGroupName); - session.setPeerGroupDisableIpv4Afi(peerGroupName, disable); - session.saveConfig(); - - return fmt::format( - "Successfully {} IPv4 AFI for peer-group '{}'\n" - "Config saved to: {}", - disable ? "disabled" : "enabled", - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupDisableIpv4Afi::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupDisableIpv4Afi, - CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h deleted file mode 100644 index cd06d0f7568d8..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupDisableIpv4Afi.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupDisableIpv4Afi - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupDisableIpv4Afi, - CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupDisableIpv4AfiTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& disable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.cpp deleted file mode 100644 index de09a95dedf21..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupEgressPolicyTraits::RetType -CmdConfigProtocolBgpPeerGroupEgressPolicy::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& policyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (policyMsg.data().empty()) { - return fmt::format( - "Error: egress policy name is required for peer-group '{}'", - peerGroupName); - } - std::string policyName = policyMsg.data()[0]; - - session.createPeerGroup(peerGroupName); - session.setPeerGroupEgressPolicy(peerGroupName, policyName); - session.saveConfig(); - - return fmt::format( - "Successfully set egress policy for peer-group '{}' to: '{}'\n" - "Config saved to: {}", - peerGroupName, - policyName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupEgressPolicy::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupEgressPolicy, - CmdConfigProtocolBgpPeerGroupEgressPolicyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h deleted file mode 100644 index e55ae153a80d7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupEgressPolicy.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupEgressPolicyTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupEgressPolicy - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupEgressPolicy, - CmdConfigProtocolBgpPeerGroupEgressPolicyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupEgressPolicyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupEgressPolicyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& policyName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.cpp deleted file mode 100644 index 3e7b7fe50d2b9..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupIngressPolicyTraits::RetType -CmdConfigProtocolBgpPeerGroupIngressPolicy::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& policyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (policyMsg.data().empty()) { - return fmt::format( - "Error: ingress policy name is required for peer-group '{}'", - peerGroupName); - } - std::string policyName = policyMsg.data()[0]; - - session.createPeerGroup(peerGroupName); - session.setPeerGroupIngressPolicy(peerGroupName, policyName); - session.saveConfig(); - - return fmt::format( - "Successfully set ingress policy for peer-group '{}' to: '{}'\n" - "Config saved to: {}", - peerGroupName, - policyName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupIngressPolicy::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupIngressPolicy, - CmdConfigProtocolBgpPeerGroupIngressPolicyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h deleted file mode 100644 index f3345936405ae..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupIngressPolicy.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupIngressPolicyTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupIngressPolicy - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupIngressPolicy, - CmdConfigProtocolBgpPeerGroupIngressPolicyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupIngressPolicyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupIngressPolicyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& policyName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.cpp deleted file mode 100644 index a3af4c904f8b4..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupMaxRoutesTraits::RetType -CmdConfigProtocolBgpPeerGroupMaxRoutes::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& maxRoutesMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (maxRoutesMsg.data().empty()) { - return fmt::format( - "Error: max-routes value is required for peer-group '{}'", - peerGroupName); - } - - int64_t maxRoutes; - try { - maxRoutes = folly::to(maxRoutesMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid max-routes value '{}': {}", - maxRoutesMsg.data()[0], - e.what()); - } - - session.createPeerGroup(peerGroupName); - session.setPeerGroupPreFilterMaxRoutes(peerGroupName, maxRoutes); - session.saveConfig(); - - return fmt::format( - "Successfully set max-routes for peer-group '{}' to: {}\n" - "Config saved to: {}", - peerGroupName, - maxRoutes, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupMaxRoutes::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupMaxRoutes, - CmdConfigProtocolBgpPeerGroupMaxRoutesTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h deleted file mode 100644 index 655b445f342cb..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupMaxRoutes.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupMaxRoutesTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupMaxRoutes - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupMaxRoutes, - CmdConfigProtocolBgpPeerGroupMaxRoutesTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupMaxRoutesTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupMaxRoutesTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& maxRoutes); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.cpp deleted file mode 100644 index 6800cdddac8c9..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupNextHopSelfTraits::RetType -CmdConfigProtocolBgpPeerGroupNextHopSelf::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value (true/false) is required for peer-group '{}'", - peerGroupName); - } - - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeerGroup(peerGroupName); - session.setPeerGroupNextHopSelf(peerGroupName, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} next-hop-self for peer-group '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupNextHopSelf::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupNextHopSelf, - CmdConfigProtocolBgpPeerGroupNextHopSelfTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h deleted file mode 100644 index 83e39041a99b9..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupNextHopSelf.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupNextHopSelfTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupNextHopSelf - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupNextHopSelf, - CmdConfigProtocolBgpPeerGroupNextHopSelfTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupNextHopSelfTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupNextHopSelfTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.cpp deleted file mode 100644 index 1fbb6a228e603..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupPeerTagTraits::RetType -CmdConfigProtocolBgpPeerGroupPeerTag::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameArg, - const ObjectArgType& peerTagMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameArg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string groupName = groupNameArg.data()[0]; - - if (peerTagMsg.data().empty()) { - return fmt::format( - "Error: peer-tag value is required for peer-group '{}'", groupName); - } - - session.createPeerGroup(groupName); - session.setPeerGroupPeerTag(groupName, peerTagMsg.data()[0]); - session.saveConfig(); - - return fmt::format( - "Successfully set peer_tag for peer-group '{}' to: '{}'\n" - "Config saved to: {}", - groupName, - peerTagMsg.data()[0], - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupPeerTag::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupPeerTag, - CmdConfigProtocolBgpPeerGroupPeerTagTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h deleted file mode 100644 index 4715f131fe8b8..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupPeerTag.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupPeerTagTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupPeerTag - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupPeerTag, - CmdConfigProtocolBgpPeerGroupPeerTagTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupPeerTagTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupPeerTagTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& groupName, - const ObjectArgType& peerTag); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.cpp deleted file mode 100644 index ea967b32e0e2d..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.cpp +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupRemoteAsnTraits::RetType -CmdConfigProtocolBgpPeerGroupRemoteAsn::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameMsg, - const ObjectArgType& remoteAsnMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - if (remoteAsnMsg.data().empty()) { - return "Error: remote-asn value is required"; - } - - std::string groupName = groupNameMsg.data()[0]; - std::string asnStr = remoteAsnMsg.data()[0]; - uint64_t remoteAsn; - try { - remoteAsn = folly::to(asnStr); - } catch (const std::exception& e) { - return fmt::format("Error: Invalid remote-asn '{}': {}", asnStr, e.what()); - } - - session.setPeerGroupRemoteAsn(groupName, remoteAsn); - session.saveConfig(); - - return fmt::format( - "Successfully set peer-group {} remote-asn to: {}\nConfig saved to: {}", - groupName, - remoteAsn, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupRemoteAsn::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupRemoteAsn, - CmdConfigProtocolBgpPeerGroupRemoteAsnTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h deleted file mode 100644 index 7f7c79898d233..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRemoteAsn.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupRemoteAsnTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupRemoteAsn - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupRemoteAsn, - CmdConfigProtocolBgpPeerGroupRemoteAsnTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupRemoteAsnTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupRemoteAsnTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& groupName, - const ObjectArgType& remoteAsn); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.cpp deleted file mode 100644 index e6cff47df37bb..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupRrClientTraits::RetType -CmdConfigProtocolBgpPeerGroupRrClient::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value (true/false) is required for peer-group '{}'", - peerGroupName); - } - - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeerGroup(peerGroupName); - session.setPeerGroupRrClient(peerGroupName, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} route-reflector-client for peer-group '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupRrClient::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupRrClient, - CmdConfigProtocolBgpPeerGroupRrClientTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h deleted file mode 100644 index c98cac2f2f97c..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupRrClient.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupRrClientTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupRrClient - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupRrClient, - CmdConfigProtocolBgpPeerGroupRrClientTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupRrClientTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupRrClientTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.cpp deleted file mode 100644 index f1ebe72da4592..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupTimersTraits::RetType -CmdConfigProtocolBgpPeerGroupTimers::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg) { - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - - std::string groupName = peerGroupNameMsg.data()[0]; - - return fmt::format( - "Configure timers for peer-group {}.\n" - "Use subcommands: hold-time, keepalive, out-delay", - groupName); -} - -void CmdConfigProtocolBgpPeerGroupTimers::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupTimers, - CmdConfigProtocolBgpPeerGroupTimersTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h deleted file mode 100644 index 2b457c60909f3..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupTimersTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - using ObjectArgType = std::monostate; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupTimers - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupTimers, - CmdConfigProtocolBgpPeerGroupTimersTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupTimersTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupTimersTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.cpp deleted file mode 100644 index 0e5b83da36dd2..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits::RetType -CmdConfigProtocolBgpPeerGroupTimersHoldTime::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& holdTimeMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - if (holdTimeMsg.data().empty()) { - return "Error: hold-time value is required"; - } - - std::string groupName = peerGroupNameMsg.data()[0]; - std::string holdTimeStr = holdTimeMsg.data()[0]; - int32_t holdTime; - try { - holdTime = folly::to(holdTimeStr); - } catch (const std::exception& e) { - return fmt::format( - "Error: Invalid hold-time '{}': {}", holdTimeStr, e.what()); - } - - session.setPeerGroupHoldTime(groupName, holdTime); - session.saveConfig(); - - return fmt::format( - "Successfully set peer-group {} hold-time to: {} seconds\nConfig saved to: {}", - groupName, - holdTime, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupTimersHoldTime::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersHoldTime, - CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h deleted file mode 100644 index 21351570d9400..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersHoldTime.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroupTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupTimersHoldTime - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersHoldTime, - CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupTimersHoldTimeTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& holdTime); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.cpp deleted file mode 100644 index 7038f9a0e2c50..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits::RetType -CmdConfigProtocolBgpPeerGroupTimersKeepalive::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& keepaliveMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (keepaliveMsg.data().empty()) { - return fmt::format( - "Error: keepalive interval is required for peer-group '{}'", - peerGroupName); - } - - int32_t keepalive; - try { - keepalive = folly::to(keepaliveMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid keepalive value '{}': {}", - keepaliveMsg.data()[0], - e.what()); - } - - session.createPeerGroup(peerGroupName); - session.setPeerGroupKeepalive(peerGroupName, keepalive); - session.saveConfig(); - - return fmt::format( - "Successfully set keepalive interval for peer-group '{}' to: {} seconds\n" - "Config saved to: {}", - peerGroupName, - keepalive, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupTimersKeepalive::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersKeepalive, - CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h deleted file mode 100644 index c2088385b391d..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersKeepalive.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroupTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupTimersKeepalive - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersKeepalive, - CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupTimersKeepaliveTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& keepalive); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.cpp deleted file mode 100644 index 21e4dc4c47eeb..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits::RetType -CmdConfigProtocolBgpPeerGroupTimersOutDelay::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& outDelayMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (outDelayMsg.data().empty()) { - return fmt::format( - "Error: out-delay value is required for peer-group '{}'", - peerGroupName); - } - - int32_t outDelay; - try { - outDelay = folly::to(outDelayMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid out-delay value '{}': {}", - outDelayMsg.data()[0], - e.what()); - } - - session.createPeerGroup(peerGroupName); - session.setPeerGroupOutDelay(peerGroupName, outDelay); - session.saveConfig(); - - return fmt::format( - "Successfully set out-delay for peer-group '{}' to: {} seconds\n" - "Config saved to: {}", - peerGroupName, - outDelay, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupTimersOutDelay::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersOutDelay, - CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h deleted file mode 100644 index 16542ecc3b225..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersOutDelay.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroupTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupTimersOutDelay - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersOutDelay, - CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupTimersOutDelayTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& outDelay); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.cpp deleted file mode 100644 index 92ccb97ff4a69..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits::RetType -CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameArg, - const ObjectArgType& delayMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameArg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string groupName = groupNameArg.data()[0]; - - if (delayMsg.data().empty()) { - return fmt::format( - "Error: withdraw-unprog-delay value (seconds) is required for peer-group '{}'", - groupName); - } - - int32_t delay; - try { - delay = std::stoi(delayMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid withdraw-unprog-delay value '{}': {}", - delayMsg.data()[0], - e.what()); - } - - session.createPeerGroup(groupName); - session.setPeerGroupWithdrawUnprogDelay(groupName, delay); - session.saveConfig(); - - return fmt::format( - "Successfully set withdraw-unprog-delay for peer-group '{}' to: {} seconds\n" - "Config saved to: {}", - groupName, - delay, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay, - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h deleted file mode 100644 index 83355fc1b1e96..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroupTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelay, - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits:: - ObjectArgType; - using RetType = - CmdConfigProtocolBgpPeerGroupTimersWithdrawUnprogDelayTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& withdrawUnprogDelay); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.cpp deleted file mode 100644 index ae03372ca1686..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.cpp +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits::RetType -CmdConfigProtocolBgpPeerGroupV4OverV6Nh::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& peerGroupNameMsg, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value required for peer-group '{}'", peerGroupName); - } - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeerGroup(peerGroupName); - session.setPeerGroupIpv4OverIpv6Nh(peerGroupName, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} v4-over-v6-nexthop for peer-group '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupV4OverV6Nh::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupV4OverV6Nh, - CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h deleted file mode 100644 index 89e5f72751f7b..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupV4OverV6Nh.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupV4OverV6Nh - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupV4OverV6Nh, - CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupV4OverV6NhTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& peerGroupName, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.cpp deleted file mode 100644 index ec21c05d82865..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupWarningLimitTraits::RetType -CmdConfigProtocolBgpPeerGroupWarningLimit::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameArg, - const ObjectArgType& warningLimitMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameArg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string groupName = groupNameArg.data()[0]; - - if (warningLimitMsg.data().empty()) { - return fmt::format( - "Error: warning-limit value is required for peer-group '{}'", - groupName); - } - - int64_t warningLimit; - try { - warningLimit = std::stoll(warningLimitMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid warning-limit value '{}': {}", - warningLimitMsg.data()[0], - e.what()); - } - - session.createPeerGroup(groupName); - session.setPeerGroupPreFilterWarningLimit(groupName, warningLimit); - session.saveConfig(); - - return fmt::format( - "Successfully set pre_filter warning_limit for peer-group '{}' to: {}\n" - "Config saved to: {}", - groupName, - warningLimit, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupWarningLimit::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupWarningLimit, - CmdConfigProtocolBgpPeerGroupWarningLimitTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h deleted file mode 100644 index c72b72da59750..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningLimit.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupWarningLimitTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupWarningLimit - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupWarningLimit, - CmdConfigProtocolBgpPeerGroupWarningLimitTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupWarningLimitTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupWarningLimitTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& groupName, - const ObjectArgType& warningLimit); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.cpp deleted file mode 100644 index ca39a63b8ecd4..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerGroupWarningOnlyTraits::RetType -CmdConfigProtocolBgpPeerGroupWarningOnly::queryClient( - const HostInfo& /* hostInfo */, - const utils::Message& groupNameArg, - const ObjectArgType& warningOnlyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (groupNameArg.data().empty()) { - return "Error: peer-group name is required"; - } - std::string groupName = groupNameArg.data()[0]; - - if (warningOnlyMsg.data().empty()) { - return fmt::format( - "Error: warning-only value (true|false) is required for peer-group '{}'", - groupName); - } - - std::string value = warningOnlyMsg.data()[0]; - bool warningOnly; - if (value == "true" || value == "1") { - warningOnly = true; - } else if (value == "false" || value == "0") { - warningOnly = false; - } else { - return fmt::format( - "Error: invalid warning-only value '{}', expected 'true' or 'false'", - value); - } - - session.createPeerGroup(groupName); - session.setPeerGroupPreFilterWarningOnly(groupName, warningOnly); - session.saveConfig(); - - return fmt::format( - "Successfully set pre_filter warning_only for peer-group '{}' to: {}\n" - "Config saved to: {}", - groupName, - warningOnly ? "true" : "false", - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerGroupWarningOnly::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerGroupWarningOnly, - CmdConfigProtocolBgpPeerGroupWarningOnlyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h deleted file mode 100644 index 9288c4dd9ae45..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroupWarningOnly.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerGroupWarningOnlyTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerGroup; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerGroupWarningOnly - : public CmdHandler< - CmdConfigProtocolBgpPeerGroupWarningOnly, - CmdConfigProtocolBgpPeerGroupWarningOnlyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerGroupWarningOnlyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerGroupWarningOnlyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::Message& groupName, - const ObjectArgType& warningOnly); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.cpp deleted file mode 100644 index 756a1f4e958af..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTraits::RetType CmdConfigProtocolBgpPeer::queryClient( - const HostInfo& /* hostInfo */, - const ObjectArgType& peerAddressList) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - - // Extract the first IP from the list as peer address - std::string peerAddress = peerAddressList.data()[0]; - - // Create peer entry in the peers list (translates to BGP++ thrift format) - session.createPeer(peerAddress); - session.saveConfig(); - - return fmt::format( - "BGP peer {} created.\n" - "Use subcommands: remote-asn, local-addr, next-hop4, next-hop6, peer-group\n" - "Config saved to: {}", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeer::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void -CmdHandler::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h deleted file mode 100644 index eaee525fe41b3..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgp; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("ipAddrs", args, "IPv4 or IPv6 addr(s)"); - } - using ObjectArgType = utils::IPList; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeer : public CmdHandler< - CmdConfigProtocolBgpPeer, - CmdConfigProtocolBgpPeerTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const ObjectArgType& peerAddress); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.cpp deleted file mode 100644 index 2cc45ff10335e..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerAdvertiseLbwTraits::RetType -CmdConfigProtocolBgpPeerAdvertiseLbw::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value required for peer '{}'", peerAddress); - } - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerAdvertiseLbw(peerAddress, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} advertise-link-bandwidth for peer '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerAdvertiseLbw::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerAdvertiseLbw, - CmdConfigProtocolBgpPeerAdvertiseLbwTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h deleted file mode 100644 index 0b6de963abefc..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerAdvertiseLbw.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerAdvertiseLbwTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerAdvertiseLbw - : public CmdHandler< - CmdConfigProtocolBgpPeerAdvertiseLbw, - CmdConfigProtocolBgpPeerAdvertiseLbwTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerAdvertiseLbwTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerAdvertiseLbwTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.cpp deleted file mode 100644 index 51f1fcab3265b..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerDescriptionTraits::RetType -CmdConfigProtocolBgpPeerDescription::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& descriptionMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (descriptionMsg.data().empty()) { - return fmt::format( - "Error: description value is required for peer '{}'", peerAddress); - } - - session.createPeer(peerAddress); - session.setPeerDescription(peerAddress, descriptionMsg.data()[0]); - session.saveConfig(); - - return fmt::format( - "Successfully set description for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - descriptionMsg.data()[0], - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerDescription::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerDescription, - CmdConfigProtocolBgpPeerDescriptionTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h deleted file mode 100644 index 7e689baf6f19e..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDescription.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerDescriptionTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerDescription - : public CmdHandler< - CmdConfigProtocolBgpPeerDescription, - CmdConfigProtocolBgpPeerDescriptionTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerDescriptionTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerDescriptionTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& description); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.cpp deleted file mode 100644 index ccbf99291fce6..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerDisableIpv4AfiTraits::RetType -CmdConfigProtocolBgpPeerDisableIpv4Afi::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& disableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (disableMsg.data().empty()) { - return fmt::format( - "Error: disable value required for peer '{}'", peerAddress); - } - std::string disableStr = disableMsg.data()[0]; - bool disable = - (disableStr == "true" || disableStr == "1" || disableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerDisableIpv4Afi(peerAddress, disable); - session.saveConfig(); - - return fmt::format( - "Successfully {} IPv4 AFI for peer '{}'\n" - "Config saved to: {}", - disable ? "disabled" : "enabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerDisableIpv4Afi::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerDisableIpv4Afi, - CmdConfigProtocolBgpPeerDisableIpv4AfiTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h deleted file mode 100644 index 285bc4fb56be1..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerDisableIpv4Afi.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerDisableIpv4AfiTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerDisableIpv4Afi - : public CmdHandler< - CmdConfigProtocolBgpPeerDisableIpv4Afi, - CmdConfigProtocolBgpPeerDisableIpv4AfiTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerDisableIpv4AfiTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerDisableIpv4AfiTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& disable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.cpp deleted file mode 100644 index 816f2e529b030..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerEgressPolicyTraits::RetType -CmdConfigProtocolBgpPeerEgressPolicy::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& policyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (policyMsg.data().empty()) { - return fmt::format( - "Error: egress policy name is required for peer '{}'", peerAddress); - } - std::string policyName = policyMsg.data()[0]; - - session.createPeer(peerAddress); - session.setPeerEgressPolicy(peerAddress, policyName); - session.saveConfig(); - - return fmt::format( - "Successfully set egress policy for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - policyName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerEgressPolicy::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerEgressPolicy, - CmdConfigProtocolBgpPeerEgressPolicyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h deleted file mode 100644 index abf65d3c8a601..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerEgressPolicy.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerEgressPolicyTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerEgressPolicy - : public CmdHandler< - CmdConfigProtocolBgpPeerEgressPolicy, - CmdConfigProtocolBgpPeerEgressPolicyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerEgressPolicyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerEgressPolicyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& policyName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.cpp deleted file mode 100644 index 521aeb95a135b..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerHoldTimeTraits::RetType -CmdConfigProtocolBgpPeerHoldTime::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& holdTimeMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (holdTimeMsg.data().empty()) { - return fmt::format( - "Error: hold-time value is required for peer '{}'", peerAddress); - } - - int32_t holdTime; - try { - holdTime = folly::to(holdTimeMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid hold-time value '{}': {}", - holdTimeMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerHoldTime(peerAddress, holdTime); - session.saveConfig(); - - return fmt::format( - "Successfully set hold-time for peer '{}' to: {} seconds\n" - "Config saved to: {}", - peerAddress, - holdTime, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerHoldTime::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerHoldTime, - CmdConfigProtocolBgpPeerHoldTimeTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h deleted file mode 100644 index 22c2149ab7ebc..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerHoldTime.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerHoldTimeTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerHoldTime - : public CmdHandler< - CmdConfigProtocolBgpPeerHoldTime, - CmdConfigProtocolBgpPeerHoldTimeTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerHoldTimeTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerHoldTimeTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& holdTime); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.cpp deleted file mode 100644 index 0f26e9045b9e2..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerIngressPolicyTraits::RetType -CmdConfigProtocolBgpPeerIngressPolicy::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& policyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (policyMsg.data().empty()) { - return fmt::format( - "Error: ingress policy name is required for peer '{}'", peerAddress); - } - std::string policyName = policyMsg.data()[0]; - - session.createPeer(peerAddress); - session.setPeerIngressPolicy(peerAddress, policyName); - session.saveConfig(); - - return fmt::format( - "Successfully set ingress policy for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - policyName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerIngressPolicy::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerIngressPolicy, - CmdConfigProtocolBgpPeerIngressPolicyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h deleted file mode 100644 index 57647d9acd537..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerIngressPolicy.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerIngressPolicyTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerIngressPolicy - : public CmdHandler< - CmdConfigProtocolBgpPeerIngressPolicy, - CmdConfigProtocolBgpPeerIngressPolicyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerIngressPolicyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerIngressPolicyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& policyName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.cpp deleted file mode 100644 index 7f42aecef6632..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -namespace { -// Parse bandwidth string like "10G", "100M", "1000" to bps -int64_t parseBandwidth(const std::string& bwStr) { - std::string upper = bwStr; - for (auto& c : upper) { - c = std::toupper(c); - } - - int64_t multiplier = 1; - std::string numPart = upper; - - if (upper.back() == 'G') { - multiplier = 1000000000LL; - numPart = upper.substr(0, upper.length() - 1); - } else if (upper.back() == 'M') { - multiplier = 1000000LL; - numPart = upper.substr(0, upper.length() - 1); - } else if (upper.back() == 'K') { - multiplier = 1000LL; - numPart = upper.substr(0, upper.length() - 1); - } - - return folly::to(numPart) * multiplier; -} -} // namespace - -CmdConfigProtocolBgpPeerLinkBandwidthTraits::RetType -CmdConfigProtocolBgpPeerLinkBandwidth::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& bandwidthMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (bandwidthMsg.data().empty()) { - return fmt::format( - "Error: link-bandwidth value is required for peer '{}'", peerAddress); - } - - int64_t bps; - try { - bps = parseBandwidth(bandwidthMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid link-bandwidth value '{}': {}", - bandwidthMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerLbwValue(peerAddress, bps); - session.saveConfig(); - - return fmt::format( - "Successfully set link-bandwidth for peer '{}' to: {} bps\n" - "Config saved to: {}", - peerAddress, - bps, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerLinkBandwidth::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerLinkBandwidth, - CmdConfigProtocolBgpPeerLinkBandwidthTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h deleted file mode 100644 index 21efd752db201..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLinkBandwidth.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerLinkBandwidthTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerLinkBandwidth - : public CmdHandler< - CmdConfigProtocolBgpPeerLinkBandwidth, - CmdConfigProtocolBgpPeerLinkBandwidthTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerLinkBandwidthTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerLinkBandwidthTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& bandwidth); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.cpp deleted file mode 100644 index 16b702514cb68..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerLocalAddrTraits::RetType -CmdConfigProtocolBgpPeerLocalAddr::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& localAddrMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (localAddrMsg.data().empty()) { - return fmt::format( - "Error: local-addr value required for peer '{}'", peerAddress); - } - std::string localAddr = localAddrMsg.data()[0]; - - session.createPeer(peerAddress); - session.setPeerLocalAddr(peerAddress, localAddr); - session.saveConfig(); - - return fmt::format( - "Successfully set local-addr for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - localAddr, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerLocalAddr::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerLocalAddr, - CmdConfigProtocolBgpPeerLocalAddrTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h deleted file mode 100644 index e982e20e79d0b..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerLocalAddr.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerLocalAddrTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerLocalAddr - : public CmdHandler< - CmdConfigProtocolBgpPeerLocalAddr, - CmdConfigProtocolBgpPeerLocalAddrTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerLocalAddrTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerLocalAddrTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& localAddr); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.cpp deleted file mode 100644 index 8f7171c157076..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerMaxRoutesTraits::RetType -CmdConfigProtocolBgpPeerMaxRoutes::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& maxRoutesMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (maxRoutesMsg.data().empty()) { - return fmt::format( - "Error: max-routes value is required for peer '{}'", peerAddress); - } - - int64_t maxRoutes; - try { - maxRoutes = folly::to(maxRoutesMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid max-routes value '{}': {}", - maxRoutesMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerPreFilterMaxRoutes(peerAddress, maxRoutes); - session.saveConfig(); - - return fmt::format( - "Successfully set max-routes for peer '{}' to: {}\n" - "Config saved to: {}", - peerAddress, - maxRoutes, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerMaxRoutes::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerMaxRoutes, - CmdConfigProtocolBgpPeerMaxRoutesTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h deleted file mode 100644 index 4cec005468d9b..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerMaxRoutes.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerMaxRoutesTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerMaxRoutes - : public CmdHandler< - CmdConfigProtocolBgpPeerMaxRoutes, - CmdConfigProtocolBgpPeerMaxRoutesTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerMaxRoutesTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerMaxRoutesTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& maxRoutes); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.cpp deleted file mode 100644 index 2e0846c898931..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerNextHop4Traits::RetType -CmdConfigProtocolBgpPeerNextHop4::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& nextHop4Msg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (nextHop4Msg.data().empty()) { - return fmt::format( - "Error: next-hop4 value required for peer '{}'", peerAddress); - } - std::string nextHop4 = nextHop4Msg.data()[0]; - - session.createPeer(peerAddress); - session.setPeerNextHop4(peerAddress, nextHop4); - session.saveConfig(); - - return fmt::format( - "Successfully set next-hop4 for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - nextHop4, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerNextHop4::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerNextHop4, - CmdConfigProtocolBgpPeerNextHop4Traits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h deleted file mode 100644 index 9f84c4b6813ab..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop4.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerNextHop4Traits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerNextHop4 - : public CmdHandler< - CmdConfigProtocolBgpPeerNextHop4, - CmdConfigProtocolBgpPeerNextHop4Traits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerNextHop4Traits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerNextHop4Traits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& nextHop4); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.cpp deleted file mode 100644 index da3f6b4a57d9c..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.cpp +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerNextHop6Traits::RetType -CmdConfigProtocolBgpPeerNextHop6::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& nextHop6Msg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (nextHop6Msg.data().empty()) { - return fmt::format( - "Error: next-hop6 value required for peer '{}'", peerAddress); - } - std::string nextHop6 = nextHop6Msg.data()[0]; - - session.createPeer(peerAddress); - session.setPeerNextHop6(peerAddress, nextHop6); - session.saveConfig(); - - return fmt::format( - "Successfully set next-hop6 for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - nextHop6, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerNextHop6::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerNextHop6, - CmdConfigProtocolBgpPeerNextHop6Traits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h deleted file mode 100644 index 6c7ba583d3743..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHop6.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerNextHop6Traits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerNextHop6 - : public CmdHandler< - CmdConfigProtocolBgpPeerNextHop6, - CmdConfigProtocolBgpPeerNextHop6Traits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerNextHop6Traits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerNextHop6Traits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& nextHop6); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.cpp deleted file mode 100644 index 5e4f9d722770d..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerNextHopSelfTraits::RetType -CmdConfigProtocolBgpPeerNextHopSelf::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value (true/false) is required for peer '{}'", - peerAddress); - } - - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerNextHopSelf(peerAddress, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} next-hop-self for peer '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerNextHopSelf::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerNextHopSelf, - CmdConfigProtocolBgpPeerNextHopSelfTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h deleted file mode 100644 index 3fd450a707441..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerNextHopSelf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerNextHopSelfTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerNextHopSelf - : public CmdHandler< - CmdConfigProtocolBgpPeerNextHopSelf, - CmdConfigProtocolBgpPeerNextHopSelfTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerNextHopSelfTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerNextHopSelfTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.cpp deleted file mode 100644 index afdf292bac5d7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerPassiveTraits::RetType -CmdConfigProtocolBgpPeerPassive::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value required for peer '{}'", peerAddress); - } - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerPassive(peerAddress, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} passive mode for peer '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerPassive::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerPassive, - CmdConfigProtocolBgpPeerPassiveTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h deleted file mode 100644 index fc03203a62d81..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPassive.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerPassiveTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerPassive - : public CmdHandler< - CmdConfigProtocolBgpPeerPassive, - CmdConfigProtocolBgpPeerPassiveTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerPassiveTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerPassiveTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.cpp deleted file mode 100644 index 6d39e53a2ad90..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerPeerGroupTraits::RetType -CmdConfigProtocolBgpPeerPeerGroup::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& peerGroupNameMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - if (peerGroupNameMsg.data().empty()) { - return "Error: peer-group name is required"; - } - - std::string peerAddress = peerAddressList.data()[0]; - std::string peerGroupName = peerGroupNameMsg.data()[0]; - - session.setPeerGroupName(peerAddress, peerGroupName); - session.saveConfig(); - - return fmt::format( - "Successfully set peer {} peer-group to: {}\nConfig saved to: {}", - peerAddress, - peerGroupName, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerPeerGroup::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerPeerGroup, - CmdConfigProtocolBgpPeerPeerGroupTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h deleted file mode 100644 index 346af38f9ca42..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerGroup.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerPeerGroupTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerPeerGroup - : public CmdHandler< - CmdConfigProtocolBgpPeerPeerGroup, - CmdConfigProtocolBgpPeerPeerGroupTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerPeerGroupTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerPeerGroupTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& peerGroupName); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.cpp deleted file mode 100644 index a4ac20d0e5ecd..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerPeerIdTraits::RetType -CmdConfigProtocolBgpPeerPeerId::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& peerIdMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (peerIdMsg.data().empty()) { - return fmt::format( - "Error: peer-id value is required for peer '{}'", peerAddress); - } - - session.createPeer(peerAddress); - session.setPeerPeerId(peerAddress, peerIdMsg.data()[0]); - session.saveConfig(); - - return fmt::format( - "Successfully set peer-id for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - peerIdMsg.data()[0], - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerPeerId::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerPeerId, - CmdConfigProtocolBgpPeerPeerIdTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h deleted file mode 100644 index 2091ffe5a495a..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerPeerId.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerPeerIdTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerPeerId - : public CmdHandler< - CmdConfigProtocolBgpPeerPeerId, - CmdConfigProtocolBgpPeerPeerIdTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerPeerIdTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerPeerIdTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& peerId); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.cpp deleted file mode 100644 index dbfb714a3b9e3..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerRemoteAsnTraits::RetType -CmdConfigProtocolBgpPeerRemoteAsn::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& remoteAsnMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - - if (remoteAsnMsg.data().empty()) { - return "Error: remote-asn value is required"; - } - - // Extract the first IP from the list as peer address - std::string peerAddress = peerAddressList.data()[0]; - - // Extract string and parse to uint64_t (4-byte ASN per RFC 6793) - std::string asnStr = remoteAsnMsg.data()[0]; - uint64_t remoteAsn; - try { - remoteAsn = folly::to(asnStr); - } catch (const std::exception& e) { - return fmt::format( - "Error: Invalid remote-asn value '{}': {}", asnStr, e.what()); - } - - // Set the remote-asn for the peer (internally maps to remote_as_4_byte) - session.setPeerRemoteAsn(peerAddress, remoteAsn); - session.saveConfig(); - - return fmt::format( - "Successfully set BGP peer {} remote-asn to: {}\nConfig saved to: {}", - peerAddress, - remoteAsn, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerRemoteAsn::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerRemoteAsn, - CmdConfigProtocolBgpPeerRemoteAsnTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h deleted file mode 100644 index 76059df98381a..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRemoteAsn.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerRemoteAsnTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerRemoteAsn - : public CmdHandler< - CmdConfigProtocolBgpPeerRemoteAsn, - CmdConfigProtocolBgpPeerRemoteAsnTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerRemoteAsnTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerRemoteAsnTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& remoteAsn); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.cpp deleted file mode 100644 index 025e3a4d4c797..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerRrClientTraits::RetType -CmdConfigProtocolBgpPeerRrClient::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value (true/false) is required for peer '{}'", - peerAddress); - } - - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerRrClient(peerAddress, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} route-reflector-client for peer '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerRrClient::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerRrClient, - CmdConfigProtocolBgpPeerRrClientTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h deleted file mode 100644 index 2eaba6e61b7c0..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerRrClient.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerRrClientTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerRrClient - : public CmdHandler< - CmdConfigProtocolBgpPeerRrClient, - CmdConfigProtocolBgpPeerRrClientTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerRrClientTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerRrClientTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.cpp deleted file mode 100644 index c4a43abf408b8..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTimersTraits::RetType -CmdConfigProtocolBgpPeerTimers::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList) { - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - return fmt::format( - "BGP peer timers configuration for peer '{}'.\n" - "Available subcommands:\n" - " hold-time - Set hold time\n" - " keepalive - Set keepalive interval\n" - " out-delay - Set output delay\n" - " withdraw-unprog-delay - Set withdraw unprog delay", - peerAddress); -} - -void CmdConfigProtocolBgpPeerTimers::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerTimers, - CmdConfigProtocolBgpPeerTimersTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h deleted file mode 100644 index a3fe71082ab57..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTimersTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - using ObjectArgType = std::monostate; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerTimers - : public CmdHandler< - CmdConfigProtocolBgpPeerTimers, - CmdConfigProtocolBgpPeerTimersTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerTimersTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerTimersTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.cpp deleted file mode 100644 index c6a582ebab8c9..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTimersKeepaliveTraits::RetType -CmdConfigProtocolBgpPeerTimersKeepalive::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& keepaliveMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (keepaliveMsg.data().empty()) { - return fmt::format( - "Error: keepalive value (seconds) is required for peer '{}'", - peerAddress); - } - - int32_t keepalive; - try { - keepalive = std::stoi(keepaliveMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid keepalive value '{}': {}", - keepaliveMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerKeepalive(peerAddress, keepalive); - session.saveConfig(); - - return fmt::format( - "Successfully set keepalive for peer '{}' to: {} seconds\n" - "Config saved to: {}", - peerAddress, - keepalive, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerTimersKeepalive::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerTimersKeepalive, - CmdConfigProtocolBgpPeerTimersKeepaliveTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h deleted file mode 100644 index 8449f76d2d7fb..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersKeepalive.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTimersKeepaliveTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerTimersKeepalive - : public CmdHandler< - CmdConfigProtocolBgpPeerTimersKeepalive, - CmdConfigProtocolBgpPeerTimersKeepaliveTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerTimersKeepaliveTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerTimersKeepaliveTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& keepalive); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.cpp deleted file mode 100644 index 46cb4cbe18168..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTimersOutDelayTraits::RetType -CmdConfigProtocolBgpPeerTimersOutDelay::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& outDelayMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (outDelayMsg.data().empty()) { - return fmt::format( - "Error: out-delay value (seconds) is required for peer '{}'", - peerAddress); - } - - int32_t outDelay; - try { - outDelay = std::stoi(outDelayMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid out-delay value '{}': {}", - outDelayMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerOutDelay(peerAddress, outDelay); - session.saveConfig(); - - return fmt::format( - "Successfully set out-delay for peer '{}' to: {} seconds\n" - "Config saved to: {}", - peerAddress, - outDelay, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerTimersOutDelay::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerTimersOutDelay, - CmdConfigProtocolBgpPeerTimersOutDelayTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h deleted file mode 100644 index a4817268b16a1..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersOutDelay.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTimersOutDelayTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerTimersOutDelay - : public CmdHandler< - CmdConfigProtocolBgpPeerTimersOutDelay, - CmdConfigProtocolBgpPeerTimersOutDelayTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerTimersOutDelayTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerTimersOutDelayTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& outDelay); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.cpp deleted file mode 100644 index ff95a1dce0d78..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits::RetType -CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& delayMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (delayMsg.data().empty()) { - return fmt::format( - "Error: withdraw-unprog-delay value (seconds) is required for peer '{}'", - peerAddress); - } - - int32_t delay; - try { - delay = std::stoi(delayMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid withdraw-unprog-delay value '{}': {}", - delayMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerWithdrawUnprogDelay(peerAddress, delay); - session.saveConfig(); - - return fmt::format( - "Successfully set withdraw-unprog-delay for peer '{}' to: {} seconds\n" - "Config saved to: {}", - peerAddress, - delay, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay::printOutput( - const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay, - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h deleted file mode 100644 index 47b28cd791ce7..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerTimers.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits - : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeerTimers; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay - : public CmdHandler< - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelay, - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits::ObjectArgType; - using RetType = - CmdConfigProtocolBgpPeerTimersWithdrawUnprogDelayTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& withdrawUnprogDelay); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.cpp deleted file mode 100644 index af460feecbf90..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerTypeTraits::RetType -CmdConfigProtocolBgpPeerType::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& peerTypeMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (peerTypeMsg.data().empty()) { - return fmt::format( - "Error: type value is required for peer '{}'", peerAddress); - } - - session.createPeer(peerAddress); - session.setPeerType(peerAddress, peerTypeMsg.data()[0]); - session.saveConfig(); - - return fmt::format( - "Successfully set type for peer '{}' to: '{}'\n" - "Config saved to: {}", - peerAddress, - peerTypeMsg.data()[0], - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerType::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerType, - CmdConfigProtocolBgpPeerTypeTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h deleted file mode 100644 index 8b5a593677bf1..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerType.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerTypeTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerType : public CmdHandler< - CmdConfigProtocolBgpPeerType, - CmdConfigProtocolBgpPeerTypeTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerTypeTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerTypeTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& peerType); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.cpp deleted file mode 100644 index 94c3500946321..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.cpp +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerV4OverV6NhTraits::RetType -CmdConfigProtocolBgpPeerV4OverV6Nh::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& enableMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (enableMsg.data().empty()) { - return fmt::format( - "Error: enable value required for peer '{}'", peerAddress); - } - std::string enableStr = enableMsg.data()[0]; - bool enable = (enableStr == "true" || enableStr == "1" || enableStr == "yes"); - - session.createPeer(peerAddress); - session.setPeerIpv4OverIpv6Nh(peerAddress, enable); - session.saveConfig(); - - return fmt::format( - "Successfully {} v4-over-v6-nexthop for peer '{}'\n" - "Config saved to: {}", - enable ? "enabled" : "disabled", - peerAddress, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerV4OverV6Nh::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerV4OverV6Nh, - CmdConfigProtocolBgpPeerV4OverV6NhTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h deleted file mode 100644 index af68ab9d07c62..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerV4OverV6Nh.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerV4OverV6NhTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerV4OverV6Nh - : public CmdHandler< - CmdConfigProtocolBgpPeerV4OverV6Nh, - CmdConfigProtocolBgpPeerV4OverV6NhTraits> { - public: - using ObjectArgType = CmdConfigProtocolBgpPeerV4OverV6NhTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerV4OverV6NhTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& enable); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.cpp deleted file mode 100644 index 6b361f89e0e25..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerWarningLimitTraits::RetType -CmdConfigProtocolBgpPeerWarningLimit::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& warningLimitMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (warningLimitMsg.data().empty()) { - return fmt::format( - "Error: warning-limit value is required for peer '{}'", peerAddress); - } - - int64_t warningLimit; - try { - warningLimit = std::stoll(warningLimitMsg.data()[0]); - } catch (const std::exception& e) { - return fmt::format( - "Error: invalid warning-limit value '{}': {}", - warningLimitMsg.data()[0], - e.what()); - } - - session.createPeer(peerAddress); - session.setPeerPreFilterWarningLimit(peerAddress, warningLimit); - session.saveConfig(); - - return fmt::format( - "Successfully set pre_filter warning_limit for peer '{}' to: {}\n" - "Config saved to: {}", - peerAddress, - warningLimit, - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerWarningLimit::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerWarningLimit, - CmdConfigProtocolBgpPeerWarningLimitTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h deleted file mode 100644 index 97dbae5059eab..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningLimit.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerWarningLimitTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerWarningLimit - : public CmdHandler< - CmdConfigProtocolBgpPeerWarningLimit, - CmdConfigProtocolBgpPeerWarningLimitTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerWarningLimitTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerWarningLimitTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& warningLimit); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.cpp deleted file mode 100644 index 2871824d4475c..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h" - -#include "fboss/cli/fboss2/CmdHandler.cpp" - -#include -#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" - -namespace facebook::fboss { - -CmdConfigProtocolBgpPeerWarningOnlyTraits::RetType -CmdConfigProtocolBgpPeerWarningOnly::queryClient( - const HostInfo& /* hostInfo */, - const utils::IPList& peerAddressList, - const ObjectArgType& warningOnlyMsg) { - auto& session = BgpConfigSession::getInstance(); - - if (peerAddressList.data().empty()) { - return "Error: peer address is required"; - } - std::string peerAddress = peerAddressList.data()[0]; - - if (warningOnlyMsg.data().empty()) { - return fmt::format( - "Error: warning-only value (true|false) is required for peer '{}'", - peerAddress); - } - - std::string value = warningOnlyMsg.data()[0]; - bool warningOnly; - if (value == "true" || value == "1") { - warningOnly = true; - } else if (value == "false" || value == "0") { - warningOnly = false; - } else { - return fmt::format( - "Error: invalid warning-only value '{}', expected 'true' or 'false'", - value); - } - - session.createPeer(peerAddress); - session.setPeerPreFilterWarningOnly(peerAddress, warningOnly); - session.saveConfig(); - - return fmt::format( - "Successfully set pre_filter warning_only for peer '{}' to: {}\n" - "Config saved to: {}", - peerAddress, - warningOnly ? "true" : "false", - session.getSessionConfigPath()); -} - -void CmdConfigProtocolBgpPeerWarningOnly::printOutput(const RetType& output) { - std::cout << output << std::endl; -} - -// Explicit template instantiation -template void CmdHandler< - CmdConfigProtocolBgpPeerWarningOnly, - CmdConfigProtocolBgpPeerWarningOnlyTraits>::run(); - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h b/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h deleted file mode 100644 index 22f27198597dd..0000000000000 --- a/fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeerWarningOnly.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2004-present, Facebook, Inc. - * All rights reserved. - * - * This source code is licensed under the BSD-style license found in the - * LICENSE file in the root directory of this source tree. An additional grant - * of patent rights can be found in the PATENTS file in the same directory. - * - */ - -#pragma once - -#include "fboss/cli/fboss2/CmdHandler.h" -#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer/CmdConfigProtocolBgpPeer.h" -#include "fboss/cli/fboss2/utils/CmdUtils.h" - -namespace facebook::fboss { - -struct CmdConfigProtocolBgpPeerWarningOnlyTraits : public WriteCommandTraits { - using ParentCmd = CmdConfigProtocolBgpPeer; - static void addCliArg(CLI::App& cmd, std::vector& args) { - cmd.add_option("msg", args, "Message"); - } - using ObjectArgType = utils::Message; - using RetType = std::string; -}; - -class CmdConfigProtocolBgpPeerWarningOnly - : public CmdHandler< - CmdConfigProtocolBgpPeerWarningOnly, - CmdConfigProtocolBgpPeerWarningOnlyTraits> { - public: - using ObjectArgType = - CmdConfigProtocolBgpPeerWarningOnlyTraits::ObjectArgType; - using RetType = CmdConfigProtocolBgpPeerWarningOnlyTraits::RetType; - - RetType queryClient( - const HostInfo& hostInfo, - const utils::IPList& peerAddress, - const ObjectArgType& warningOnly); - - void printOutput(const RetType& output); -}; - -} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp new file mode 100644 index 0000000000000..ace33a2b0c2ce --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.cpp @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +namespace facebook::fboss { + +CmdConfigProtocolBgpPolicyTraits::RetType +CmdConfigProtocolBgpPolicy::queryClient(const HostInfo& /* hostInfo */) { + return "BGP policy configuration. Use subcommands: as-path-list"; +} + +void CmdConfigProtocolBgpPolicy::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void +CmdHandler::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h new file mode 100644 index 0000000000000..6d0115fb5aa0f --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/CmdConfigProtocolBgp.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Grouping node for `config protocol bgp policy ...`. Holds no +// state of its own; the per-object-type dispatchers (as-path-list, +// community-list, and later prefix-list/routing-policy) are its subcommands. +// Mirrors CmdConfigProtocolBgp. +struct CmdConfigProtocolBgpPolicyTraits : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgp; + using ObjectArgType = std::monostate; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpPolicy : public CmdHandler< + CmdConfigProtocolBgpPolicy, + CmdConfigProtocolBgpPolicyTraits> { + public: + using ObjectArgType = CmdConfigProtocolBgpPolicyTraits::ObjectArgType; + using RetType = CmdConfigProtocolBgpPolicyTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h new file mode 100644 index 0000000000000..5c627006a629f --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" + +/** + * Lookup/create helpers for the as-path-list CLI family, shared between the + * list-level dispatcher (CmdConfigProtocolBgpPolicyAsPathList), the entry + * subcommand (CmdConfigProtocolBgpPolicyAsPathListEntry), and the delete + * counterparts. An AsPathList is keyed by name; an AsPathListEntry (in + * as_path_list[]) is keyed by sequence_number. + */ +namespace facebook::fboss::bgpcli { + +inline bool asPathListExists( + const bgp::thrift::BgpConfig& cfg, + const std::string& name) { + if (!cfg.policies().has_value()) { + return false; + } + const auto& lists = *cfg.policies()->aspath_lists(); + return std::any_of(lists.begin(), lists.end(), [&](const auto& list) { + return *list.name() == name; + }); +} + +// Find the as-path-list keyed by name, creating it if absent. Setting an +// attribute on a not-yet-created list implicitly creates it, so command +// ordering stays forgiving; a bare `as-path-list ` creates one +// explicitly. AsPathList's only key field is `name`. +inline bgp::bgp_policy::AsPathList& findOrCreateAsPathList( + bgp::thrift::BgpConfig& cfg, + const std::string& name) { + auto& lists = *cfg.policies().ensure().aspath_lists(); + for (auto& list : lists) { + if (*list.name() == name) { + return list; + } + } + lists.emplace_back(); + auto& list = lists.back(); + list.name() = name; + return list; +} + +inline bool asPathListEntryExists( + const bgp::bgp_policy::AsPathList& list, + int64_t seqNum) { + const auto& entries = *list.as_path_list(); + return std::any_of(entries.begin(), entries.end(), [&](const auto& entry) { + return entry.sequence_number().has_value() && + *entry.sequence_number() == seqNum; + }); +} + +// Find the entry keyed by sequence_number within a list, creating it if +// absent. sequence_number is the entry's identity. +inline bgp::bgp_policy::AsPathListEntry& findOrCreateAsPathListEntry( + bgp::bgp_policy::AsPathList& list, + int64_t seqNum) { + auto& entries = *list.as_path_list(); + for (auto& entry : entries) { + if (entry.sequence_number().has_value() && + *entry.sequence_number() == seqNum) { + return entry; + } + } + entries.emplace_back(); + auto& entry = entries.back(); + entry.sequence_number() = seqNum; + return entry; +} + +} // namespace facebook::fboss::bgpcli diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp new file mode 100644 index 0000000000000..e4c6edbc7c0ec --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.cpp @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +namespace { + +// The attribute names, exactly as documented. Kept here so the +// valid-attribute set and the handler table stay in sync. The list's entries +// are their own subcommand, not attributes. +constexpr std::string_view kDescription = "description"; + +using AsPathList = bgp::bgp_policy::AsPathList; +using bgpcli::AttrHandler; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::Result; + +// ---- setters ---------------------------------------------------------------- +// Each writes one already-parsed, already-validated value. Parsing and message +// text belong to the shared factories in BgpCliAttrHandlers.h. + +void setListDescription(AsPathList& list, const std::string& description) { + list.description() = description; +} + +// ---- list-level attribute registry ------------------------------------------ +// One line per documented attribute: its dispatch key, its value shape, and +// the setter that stores it. +const std::map, std::less<>>& +listAttrHandlers() { + static const std::map, std::less<>> + kHandlers = { + {std::string(kDescription), + joinedStringAttr(kDescription, setListDescription)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : listAttrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpPeerGroupConfig). +BgpAsPathListConfig::BgpAsPathListConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + "Error: as-path-list is required, optionally followed by an " + " "); + } + if (v[0].empty()) { + throw std::invalid_argument("Error: as-path-list name must not be empty"); + } + listName_ = v[0]; + + if (v.size() == 1) { + return; // bare `as-path-list `: create the list + } + + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + + if (listAttrHandlers().find(attr_) == listAttrHandlers().end()) { + throw std::invalid_argument( + fmt::format( + "Error: unknown as-path-list attribute '{}'. Valid attributes: {}", + attr_, + validAttrList())); + } +} + +CmdConfigProtocolBgpPolicyAsPathListTraits::RetType +CmdConfigProtocolBgpPolicyAsPathList::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool listCreated = !bgpcli::asPathListExists(cfg, args.listName()); + auto& list = bgpcli::findOrCreateAsPathList(cfg, args.listName()); + + Result result = args.attr().empty() + ? ok(listCreated + ? fmt::format( + "Successfully created BGP as-path-list {}", + args.listName()) + : fmt::format( + "BGP as-path-list {} already exists", args.listName())) + // The attribute is guaranteed valid: BgpAsPathListConfig's constructor + // rejects an unknown attribute before we get here. + : listAttrHandlers().find(args.attr())->second(list, args.values()); + + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format(" for as-path-list {}", args.listName()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else if (listCreated) { + // Drop the phantom list so a rejected value is not visible to later + // lookups in the same process. + cfg.policies()->aspath_lists()->pop_back(); + } + return result.message; +} + +void CmdConfigProtocolBgpPolicyAsPathList::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdConfigProtocolBgpPolicyAsPathList, + CmdConfigProtocolBgpPolicyAsPathListTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h new file mode 100644 index 0000000000000..7fe25d5f548de --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `as-path-list [ ...]`, validated at +// construction. An AsPathList is keyed by . The list's entries are their +// own subcommand (CmdConfigProtocolBgpPolicyAsPathListEntry), not attributes. +// +// Grammar (from the FBOSS proposed syntax): +// as-path-list (create/select list) +// as-path-list description (list attribute) +class BgpAsPathListConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpAsPathListConfig(std::vector v); + const std::string& listName() const { + return listName_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string listName_; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// The list level of the `config protocol bgp policy as-path-list` family; +// dispatch and per-attribute parsing live in the .cpp so a new tunable is a +// one-entry change. Mirrors CmdConfigProtocolBgpPolicyRoutingPolicy, whose +// nested level (term / entry) is likewise its own subcommand. +struct CmdConfigProtocolBgpPolicyAsPathListTraits : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgpPolicy; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // No positionals_at_end() here: CLI11 must stay free to classify the + // `entry` token as this command's subcommand rather than swallowing it + // into args. See CmdConfigProtocolBgpPolicyRoutingPolicyTraits. + cmd.add_option("args", args, " [ ...]"); + } + using ObjectArgType = BgpAsPathListConfig; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpPolicyAsPathList + : public CmdHandler< + CmdConfigProtocolBgpPolicyAsPathList, + CmdConfigProtocolBgpPolicyAsPathListTraits> { + public: + using ObjectArgType = + CmdConfigProtocolBgpPolicyAsPathListTraits::ObjectArgType; + using RetType = CmdConfigProtocolBgpPolicyAsPathListTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp new file mode 100644 index 0000000000000..846ffa28fe29a --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.cpp @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/routing_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/BgpAsPathListCliUtils.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +namespace { + +// The attribute names, exactly as documented. Kept here so the +// valid-attribute set and the handler table stay in sync. +constexpr std::string_view kDescription = "description"; +constexpr std::string_view kAsnRegexp = "asn-regexp"; +constexpr std::string_view kMatchLogic = "match-logic"; + +// match-logic values (routing_policy.MatchValueLogicOperator names). +constexpr std::string_view kMatchLogicEqual = "EQUAL"; +constexpr std::string_view kMatchLogicNotEqual = "NOT_EQUAL"; + +using AsPathListEntry = bgp::bgp_policy::AsPathListEntry; +using MatchValueLogicOperator = bgp::routing_policy::MatchValueLogicOperator; +using bgpcli::AttrHandler; +using bgpcli::enumAttr; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::Result; + +// ---- value lookups ---------------------------------------------------------- + +std::optional lookupMatchLogic(const std::string& s) { + if (s == kMatchLogicEqual) { + return MatchValueLogicOperator::EQUAL; + } + if (s == kMatchLogicNotEqual) { + return MatchValueLogicOperator::NOT_EQUAL; + } + return std::nullopt; +} + +// ---- entry-level setters ---------------------------------------------------- +// Each writes one already-parsed, already-validated value. Parsing and message +// text belong to the shared factories in BgpCliAttrHandlers.h. + +void setDescription(AsPathListEntry& entry, const std::string& description) { + entry.description() = description; +} + +// The AS path is modelled as an AsPathType union; the CLI sets the inline +// `as_path` (AsPath) arm and its regexp, matching the thrift path +// .as_path.as_path.asn_regexp. +void setAsnRegexp(AsPathListEntry& entry, const std::string& regexp) { + entry.as_path()->set_as_path().asn_regexp() = regexp; +} + +void setMatchLogic(AsPathListEntry& entry, MatchValueLogicOperator op) { + entry.match_logic_type() = op; +} + +// ---- entry-level attribute registry ----------------------------------------- +// One line per documented attribute: its dispatch key, its value shape, and +// the setter that stores it. asn-regexp is a joined string because an AS-path +// regex separates ASNs with spaces (e.g. `^65000 65001$`), so its tokens must +// be re-joined rather than required to be single. +const std::map, std::less<>>& +entryAttrHandlers() { + static const std::string kMatchLogicValues = + fmt::format("{}|{}", kMatchLogicEqual, kMatchLogicNotEqual); + static const std::map, std::less<>> + kHandlers = { + {std::string(kAsnRegexp), + joinedStringAttr(kAsnRegexp, setAsnRegexp)}, + {std::string(kDescription), + joinedStringAttr(kDescription, setDescription)}, + {std::string(kMatchLogic), + enumAttr( + kMatchLogic, + kMatchLogicValues, + lookupMatchLogic, + setMatchLogic)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : entryAttrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpAsPathListConfig). +BgpAsPathListEntryConfig::BgpAsPathListEntryConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + "Error: entry is required, optionally followed by an " + " "); + } + auto seq = bgpcli::parseNonNegInt64(v[0]); + if (!seq) { + throw std::invalid_argument( + fmt::format( + "Error: entry must be a non-negative integer, got '{}'", + v[0])); + } + seqNum_ = *seq; + if (v.size() == 1) { + return; // bare `entry `: create it + } + + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + + if (entryAttrHandlers().find(attr_) == entryAttrHandlers().end()) { + throw std::invalid_argument( + fmt::format( + "Error: unknown as-path-list entry attribute '{}'. Valid " + "attributes: {}", + attr_, + validAttrList())); + } +} + +CmdConfigProtocolBgpPolicyAsPathListEntryTraits::RetType +CmdConfigProtocolBgpPolicyAsPathListEntry::queryClient( + const HostInfo& /* hostInfo */, + const BgpAsPathListConfig& listArgs, + const ObjectArgType& args) { + // The parent parse accepts `as-path-list ... entry + // ...`, but only the leaf (this command) runs — silently dropping the + // list-level attribute would look like it was staged. Reject the mix. + if (!listArgs.attr().empty()) { + return fmt::format( + "Error: configure as-path-list attributes and entry in separate " + "commands (got as-path-list attribute '{}' alongside entry {})", + listArgs.attr(), + args.seqNum()); + } + + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool listCreated = !bgpcli::asPathListExists(cfg, listArgs.listName()); + auto& list = bgpcli::findOrCreateAsPathList(cfg, listArgs.listName()); + const bool entryCreated = !bgpcli::asPathListEntryExists(list, args.seqNum()); + auto& entry = bgpcli::findOrCreateAsPathListEntry(list, args.seqNum()); + + Result result = args.attr().empty() + ? ok(entryCreated + ? fmt::format( + "Successfully created BGP as-path-list {} entry {}", + listArgs.listName(), + args.seqNum()) + : fmt::format( + "BGP as-path-list {} entry {} already exists", + listArgs.listName(), + args.seqNum())) + // The attribute is guaranteed valid: BgpAsPathListEntryConfig's + // constructor rejects an unknown attribute before we get here. + : entryAttrHandlers().find(args.attr())->second(entry, args.values()); + + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format( + " for as-path-list {} entry {}", listArgs.listName(), args.seqNum()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else { + // A rejected value must not leave a phantom entry (or a phantom list + // implicitly created for it) visible to later lookups in this process. + if (entryCreated) { + list.as_path_list()->pop_back(); + } + if (listCreated) { + cfg.policies()->aspath_lists()->pop_back(); + } + } + return result.message; +} + +void CmdConfigProtocolBgpPolicyAsPathListEntry::printOutput( + const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdConfigProtocolBgpPolicyAsPathListEntry, + CmdConfigProtocolBgpPolicyAsPathListEntryTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h new file mode 100644 index 0000000000000..d2718c4d59b1e --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `entry [ ...]`, validated at +// construction. An entry (bgp_policy.AsPathListEntry in +// AsPathList.as_path_list[]) is keyed by ; the list it belongs to is +// supplied by the parent command's args. +// +// Grammar (from the FBOSS proposed syntax): +// ... as-path-list entry (create/select) +// ... as-path-list entry asn-regexp +// ... as-path-list entry description +// ... as-path-list entry match-logic +class BgpAsPathListEntryConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpAsPathListEntryConfig(std::vector v); + int64_t seqNum() const { + return seqNum_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + int64_t seqNum_{0}; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// The entry level of the as-path-list family as its own CLI11 subcommand; the +// parent's parsed args arrive through the ancestor-args tuple, mirroring +// CmdConfigProtocolBgpPolicyRoutingPolicyTerm. +struct CmdConfigProtocolBgpPolicyAsPathListEntryTraits + : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgpPolicyAsPathList; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // Entry has no nested subcommands; stop CLI11's parent-chain fallthrough + // from stealing a value token that spells `entry` (e.g. in a description). + cmd.positionals_at_end(); + cmd.add_option("args", args, " [ ...]"); + } + using ObjectArgType = BgpAsPathListEntryConfig; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpPolicyAsPathListEntry + : public CmdHandler< + CmdConfigProtocolBgpPolicyAsPathListEntry, + CmdConfigProtocolBgpPolicyAsPathListEntryTraits> { + public: + using ObjectArgType = + CmdConfigProtocolBgpPolicyAsPathListEntryTraits::ObjectArgType; + using RetType = CmdConfigProtocolBgpPolicyAsPathListEntryTraits::RetType; + + RetType queryClient( + const HostInfo& hostInfo, + const BgpAsPathListConfig& listArgs, + const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h new file mode 100644 index 0000000000000..5b6f5c60394d4 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" + +/** + * Lookup/create helpers for the community-list CLI family, shared between the + * list-level dispatcher (CmdConfigProtocolBgpPolicyCommunityList), the + * community subcommand (CmdConfigProtocolBgpPolicyCommunityListCommunity), and + * the delete counterparts. A CommunityList is keyed by name; the inline + * Community members it holds are keyed by their own name. + */ +namespace facebook::fboss::bgpcli { + +inline bool communityListExists( + const bgp::thrift::BgpConfig& cfg, + const std::string& name) { + if (!cfg.policies().has_value()) { + return false; + } + const auto& lists = *cfg.policies()->community_lists(); + return std::any_of(lists.begin(), lists.end(), [&](const auto& list) { + return *list.name() == name; + }); +} + +// Find the community-list keyed by name, creating it if absent. Setting an +// attribute on a not-yet-created list implicitly creates it, so command +// ordering stays forgiving; a bare `community-list ` creates one +// explicitly. CommunityList's only key field is `name`. +inline bgp::bgp_policy::CommunityList& findOrCreateCommunityList( + bgp::thrift::BgpConfig& cfg, + const std::string& name) { + auto& lists = *cfg.policies().ensure().community_lists(); + for (auto& list : lists) { + if (*list.name() == name) { + return list; + } + } + lists.emplace_back(); + auto& list = lists.back(); + list.name() = name; + return list; +} + +inline bool communityMemberExists( + const bgp::bgp_policy::CommunityList& list, + const std::string& name) { + if (!list.members().has_value()) { + return false; + } + const auto& members = *list.members(); + return std::any_of(members.begin(), members.end(), [&](const auto& member) { + return member.community_ref().has_value() && + *member.community_ref()->name() == name; + }); +} + +// Find the inline Community member keyed by name within a list, creating it +// if absent. The CLI always defines members inline (the CommunityRefType +// union's `community` arm); the member's name is its identity. +inline bgp::bgp_policy::Community& findOrCreateCommunityMember( + bgp::bgp_policy::CommunityList& list, + const std::string& name) { + auto& members = list.members().ensure(); + for (auto& member : members) { + if (member.community_ref().has_value() && + *member.community_ref()->name() == name) { + return *member.community_ref(); + } + } + members.emplace_back(); + auto& community = members.back().set_community(); + community.name() = name; + return community; +} + +} // namespace facebook::fboss::bgpcli diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp new file mode 100644 index 0000000000000..fcf7f8dd73725 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.cpp @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/routing_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +namespace { + +// The attribute names, exactly as documented. Kept here so the +// valid-attribute set and the handler table stay in sync. The list's inline +// Community members are their own subcommand, not attributes. +constexpr std::string_view kBooleanOperator = "boolean-operator"; +constexpr std::string_view kDescription = "description"; +constexpr std::string_view kExactMatch = "exact-match"; + +// boolean-operator values (routing_policy.BooleanOperator names). +constexpr std::string_view kBooleanOperatorAnd = "AND"; +constexpr std::string_view kBooleanOperatorOr = "OR"; +constexpr std::string_view kBooleanOperatorNot = "NOT"; + +using BooleanOperator = bgp::routing_policy::BooleanOperator; +using CommunityList = bgp::bgp_policy::CommunityList; +using bgpcli::AttrHandler; +using bgpcli::boolAttr; +using bgpcli::enumAttr; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::Result; + +// ---- value lookups ---------------------------------------------------------- + +std::optional lookupBooleanOperator(const std::string& s) { + if (s == kBooleanOperatorAnd) { + return BooleanOperator::AND; + } + if (s == kBooleanOperatorOr) { + return BooleanOperator::OR; + } + if (s == kBooleanOperatorNot) { + return BooleanOperator::NOT; + } + return std::nullopt; +} + +// ---- list-level setters ----------------------------------------------------- +// Each writes one already-parsed, already-validated value. Parsing and message +// text belong to the shared factories in BgpCliAttrHandlers.h. + +void setListBooleanOperator(CommunityList& list, BooleanOperator op) { + list.boolean_operator() = op; +} + +void setListDescription(CommunityList& list, const std::string& description) { + list.description() = description; +} + +void setListExactMatch(CommunityList& list, bool exactMatch) { + list.exact_match() = exactMatch; +} + +// ---- list-level attribute registry ------------------------------------------ +// One line per documented attribute: its dispatch key, its value shape, and +// the setter that stores it. +const std::map, std::less<>>& +listAttrHandlers() { + static const std::string kBooleanOperatorValues = fmt::format( + "{}|{}|{}", kBooleanOperatorAnd, kBooleanOperatorOr, kBooleanOperatorNot); + static const std::map, std::less<>> + kHandlers = { + {std::string(kBooleanOperator), + enumAttr( + kBooleanOperator, + kBooleanOperatorValues, + lookupBooleanOperator, + setListBooleanOperator)}, + {std::string(kDescription), + joinedStringAttr(kDescription, setListDescription)}, + {std::string(kExactMatch), + boolAttr(kExactMatch, setListExactMatch)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : listAttrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpAsPathListConfig). +BgpCommunityListConfig::BgpCommunityListConfig(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty()) { + throw std::invalid_argument( + "Error: community-list is required, optionally followed by an " + " "); + } + if (v[0].empty()) { + throw std::invalid_argument("Error: community-list name must not be empty"); + } + listName_ = v[0]; + + if (v.size() == 1) { + return; // bare `community-list `: create the list + } + + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + + if (listAttrHandlers().find(attr_) == listAttrHandlers().end()) { + throw std::invalid_argument( + fmt::format( + "Error: unknown community-list attribute '{}'. Valid attributes: " + "{}", + attr_, + validAttrList())); + } +} + +CmdConfigProtocolBgpPolicyCommunityListTraits::RetType +CmdConfigProtocolBgpPolicyCommunityList::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool listCreated = !bgpcli::communityListExists(cfg, args.listName()); + auto& list = bgpcli::findOrCreateCommunityList(cfg, args.listName()); + + Result result = args.attr().empty() + ? ok(listCreated + ? fmt::format( + "Successfully created BGP community-list {}", + args.listName()) + : fmt::format( + "BGP community-list {} already exists", args.listName())) + // The attribute is guaranteed valid: BgpCommunityListConfig's + // constructor rejects an unknown attribute before we get here. + : listAttrHandlers().find(args.attr())->second(list, args.values()); + + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format(" for community-list {}", args.listName()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else if (listCreated) { + // Drop the phantom list so a rejected value is not visible to later + // lookups in the same process. + cfg.policies()->community_lists()->pop_back(); + } + return result.message; +} + +void CmdConfigProtocolBgpPolicyCommunityList::printOutput( + const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdConfigProtocolBgpPolicyCommunityList, + CmdConfigProtocolBgpPolicyCommunityListTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h new file mode 100644 index 0000000000000..e8113a09cbe6d --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/CmdConfigProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `community-list [ ...]`, validated at +// construction. A CommunityList is keyed by . Its inline Community +// members are their own subcommand +// (CmdConfigProtocolBgpPolicyCommunityListCommunity), not attributes. +// Mirrors BgpAsPathListConfig. +// +// Grammar (from the FBOSS proposed syntax): +// community-list (create/select list) +// community-list boolean-operator (list attribute) +// community-list description (list attribute) +// community-list exact-match (list attribute) +class BgpCommunityListConfig : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpCommunityListConfig(std::vector v); + const std::string& listName() const { + return listName_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string listName_; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// Single handler for the whole `config protocol bgp policy community-list` +// family; dispatch and per-attribute parsing live in the .cpp so a new tunable +// is a one-entry change. Mirrors CmdConfigProtocolBgpPolicyAsPathList. +struct CmdConfigProtocolBgpPolicyCommunityListTraits + : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgpPolicy; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // No positionals_at_end() here: CLI11 must stay free to classify the + // `community` token as this command's subcommand rather than swallowing it + // into args. See CmdConfigProtocolBgpPolicyAsPathListTraits. + cmd.add_option("args", args, " [ ...]"); + } + using ObjectArgType = BgpCommunityListConfig; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpPolicyCommunityList + : public CmdHandler< + CmdConfigProtocolBgpPolicyCommunityList, + CmdConfigProtocolBgpPolicyCommunityListTraits> { + public: + using ObjectArgType = + CmdConfigProtocolBgpPolicyCommunityListTraits::ObjectArgType; + using RetType = CmdConfigProtocolBgpPolicyCommunityListTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp new file mode 100644 index 0000000000000..0c1df51f1dfd5 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.cpp @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliAttrHandlers.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +namespace { + +// The attribute names, exactly as documented. Kept here so the +// valid-attribute set and the handler table stay in sync. +constexpr std::string_view kDescription = "description"; +constexpr std::string_view kType = "type"; +constexpr std::string_view kValue = "value"; + +// type values (bgp_policy.CommunityType names). +constexpr std::string_view kCommunityTypeNormal = "NORMAL"; +constexpr std::string_view kCommunityTypeExtended = "EXTENDED"; +constexpr std::string_view kCommunityTypeLarge = "LARGE"; + +using Community = bgp::bgp_policy::Community; +using CommunityType = bgp::bgp_policy::CommunityType; +using bgpcli::AttrHandler; +using bgpcli::enumAttr; +using bgpcli::joinedStringAttr; +using bgpcli::ok; +using bgpcli::Result; +using bgpcli::stringAttr; + +// ---- value lookups ---------------------------------------------------------- + +std::optional lookupCommunityType(const std::string& s) { + if (s == kCommunityTypeNormal) { + return CommunityType::NORMAL; + } + if (s == kCommunityTypeExtended) { + return CommunityType::EXTENDED; + } + if (s == kCommunityTypeLarge) { + return CommunityType::LARGE; + } + return std::nullopt; +} + +// ---- community-level setters ------------------------------------------------ +// Each writes one already-parsed, already-validated value. Parsing and message +// text belong to the shared factories in BgpCliAttrHandlers.h. + +void setDescription(Community& community, const std::string& description) { + community.description() = description; +} + +void setType(Community& community, CommunityType type) { + community.type() = type; +} + +void setValue(Community& community, const std::string& value) { + community.value() = value; +} + +// ---- community-level attribute registry ------------------------------------- +// One line per documented attribute: its dispatch key, its value shape, and +// the setter that stores it. +const std::map, std::less<>>& +communityAttrHandlers() { + static const std::string kCommunityTypeValues = fmt::format( + "{}|{}|{}", + kCommunityTypeNormal, + kCommunityTypeExtended, + kCommunityTypeLarge); + static const std::map, std::less<>> + kHandlers = { + {std::string(kDescription), + joinedStringAttr(kDescription, setDescription)}, + {std::string(kType), + enumAttr( + kType, kCommunityTypeValues, lookupCommunityType, setType)}, + {std::string(kValue), + stringAttr(kValue, "string", setValue)}, + }; + return kHandlers; +} + +std::string validAttrList() { + std::string out; + for (const auto& [name, _] : communityAttrHandlers()) { + if (!out.empty()) { + out += ", "; + } + out += name; + } + return out; +} + +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpCommunityListConfig). +BgpCommunityListCommunityConfig::BgpCommunityListCommunityConfig( + std::vector v) + : utils::BaseObjectArgType(v) { + if (v.empty() || v[0].empty()) { + throw std::invalid_argument( + "Error: community is required, optionally followed by an " + " "); + } + communityName_ = v[0]; + if (v.size() == 1) { + return; // bare `community `: create it + } + + attr_ = v[1]; + values_.assign(v.begin() + 2, v.end()); + + if (communityAttrHandlers().find(attr_) == communityAttrHandlers().end()) { + throw std::invalid_argument( + fmt::format( + "Error: unknown community-list community attribute '{}'. Valid " + "attributes: {}", + attr_, + validAttrList())); + } +} + +CmdConfigProtocolBgpPolicyCommunityListCommunityTraits::RetType +CmdConfigProtocolBgpPolicyCommunityListCommunity::queryClient( + const HostInfo& /* hostInfo */, + const BgpCommunityListConfig& listArgs, + const ObjectArgType& args) { + // The parent parse accepts `community-list ... + // community ...`, but only the leaf (this command) runs — silently dropping + // the list-level attribute would look like it was staged. Reject the mix. + if (!listArgs.attr().empty()) { + return fmt::format( + "Error: configure community-list attributes and community in separate " + "commands (got community-list attribute '{}' alongside community {})", + listArgs.attr(), + args.communityName()); + } + + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + const bool listCreated = + !bgpcli::communityListExists(cfg, listArgs.listName()); + auto& list = bgpcli::findOrCreateCommunityList(cfg, listArgs.listName()); + const bool hadMembers = list.members().has_value(); + const bool memberCreated = + !bgpcli::communityMemberExists(list, args.communityName()); + auto& community = + bgpcli::findOrCreateCommunityMember(list, args.communityName()); + + Result result = args.attr().empty() + ? ok(memberCreated + ? fmt::format( + "Successfully created BGP community-list {} community {}", + listArgs.listName(), + args.communityName()) + : fmt::format( + "BGP community-list {} community {} already exists", + listArgs.listName(), + args.communityName())) + // The attribute is guaranteed valid: BgpCommunityListCommunityConfig's + // constructor rejects an unknown attribute before we get here. + : communityAttrHandlers() + .find(args.attr()) + ->second(community, args.values()); + + if (result.ok) { + if (!args.attr().empty()) { + result.message += fmt::format( + " for community-list {} community {}", + listArgs.listName(), + args.communityName()); + } + session.saveBgpConfig(); + result.message += + fmt::format("\nConfig saved to: {}", session.getBgpSessionConfigPath()); + } else { + // A rejected value must not leave a phantom member (or a phantom list + // implicitly created for it) visible to later lookups in this process — + // restoring an unset members field if this invocation ensured it. + if (memberCreated) { + if (hadMembers) { + list.members()->pop_back(); + } else { + list.members().reset(); + } + } + if (listCreated) { + cfg.policies()->community_lists()->pop_back(); + } + } + return result.message; +} + +void CmdConfigProtocolBgpPolicyCommunityListCommunity::printOutput( + const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdConfigProtocolBgpPolicyCommunityListCommunity, + CmdConfigProtocolBgpPolicyCommunityListCommunityTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h new file mode 100644 index 0000000000000..857d344622ae4 --- /dev/null +++ b/fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `community [ ...]`, validated at +// construction. A member (bgp_policy.Community, held inline through the +// CommunityRefType union's `community` arm in CommunityList.members[]) is +// keyed by ; the list it belongs to is supplied by the parent command's +// args. +// +// Grammar (from the FBOSS proposed syntax): +// ... community-list community (create/select) +// ... community-list community description +// ... community-list community type +// ... community-list community value +class BgpCommunityListCommunityConfig + : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpCommunityListCommunityConfig(std::vector v); + const std::string& communityName() const { + return communityName_; + } + const std::string& attr() const { + return attr_; + } + const std::vector& values() const { + return values_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string communityName_; + std::string attr_; // matched dispatch key ("" = bare create) + std::vector values_; +}; + +// The community (member) level of the community-list family as its own CLI11 +// subcommand; the parent's parsed args arrive through the ancestor-args tuple, +// mirroring CmdConfigProtocolBgpPolicyAsPathListEntry. +struct CmdConfigProtocolBgpPolicyCommunityListCommunityTraits + : public WriteCommandTraits { + using ParentCmd = CmdConfigProtocolBgpPolicyCommunityList; + static void addCliArg(CLI::App& cmd, std::vector& args) { + // Community has no nested subcommands; stop CLI11's parent-chain + // fallthrough from stealing a value token that spells `community`. + cmd.positionals_at_end(); + cmd.add_option("args", args, " [ ...]"); + } + using ObjectArgType = BgpCommunityListCommunityConfig; + using RetType = std::string; +}; + +class CmdConfigProtocolBgpPolicyCommunityListCommunity + : public CmdHandler< + CmdConfigProtocolBgpPolicyCommunityListCommunity, + CmdConfigProtocolBgpPolicyCommunityListCommunityTraits> { + public: + using ObjectArgType = + CmdConfigProtocolBgpPolicyCommunityListCommunityTraits::ObjectArgType; + using RetType = + CmdConfigProtocolBgpPolicyCommunityListCommunityTraits::RetType; + + RetType queryClient( + const HostInfo& hostInfo, + const BgpCommunityListConfig& listArgs, + const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionClear.cpp b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionClear.cpp index 6f130f1e79bd9..bd78275f0d69a 100644 --- a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionClear.cpp +++ b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionClear.cpp @@ -24,61 +24,27 @@ namespace facebook::fboss { CmdConfigSessionClearTraits::RetType CmdConfigSessionClear::queryClient( const HostInfo& /* hostInfo */) { - // Use static path getters to check for session files without calling - // getInstance(), which would create a session if one doesn't exist - std::string sessionConfigPath = ConfigSession::getSessionConfigPathStatic(); - std::string metadataPath = ConfigSession::getSessionMetadataPathStatic(); - std::string bgpConfigPath = ConfigSession::getBgpSessionConfigPathStatic(); - - std::error_code ec; - bool removedConfig = false; - bool removedMetadata = false; - bool removedBgpConfig = false; - - // Remove session config file (~/.fboss2/agent.conf) - if (fs::exists(sessionConfigPath)) { - fs::remove(sessionConfigPath, ec); - if (ec) { - throw std::runtime_error( - fmt::format( - "Failed to remove session config file {}: {}", - sessionConfigPath, - ec.message())); + // Remove each staged session file (agent + BGP configs and the metadata). + // stagedSessionFilePaths() is the single source of truth, so this handles + // every config domain uniformly -- including a BGP-only session -- without + // calling getInstance() (which would create a session we are trying to + // clear). Only individual files are removed; the ~/.fboss2 directory stays. + bool removedAny = false; + for (const auto& path : ConfigSession::stagedSessionFilePaths()) { + if (!fs::exists(path)) { + continue; } - removedConfig = true; - } - - // Remove metadata file (~/.fboss2/cli_metadata.json) - if (fs::exists(metadataPath)) { - ec.clear(); - fs::remove(metadataPath, ec); - if (ec) { - throw std::runtime_error( - fmt::format( - "Failed to remove metadata file {}: {}", - metadataPath, - ec.message())); - } - removedMetadata = true; - } - - // Remove staged BGP config file (~/.fboss2/bgp_config.json). BGP global edits - // are staged here (alongside any peer edits from BgpConfigSession), so a - // BGP-only session must be cleared too. - if (fs::exists(bgpConfigPath)) { - ec.clear(); - fs::remove(bgpConfigPath, ec); + std::error_code ec; + fs::remove(path, ec); if (ec) { throw std::runtime_error( fmt::format( - "Failed to remove BGP session config file {}: {}", - bgpConfigPath, - ec.message())); + "Failed to remove session file {}: {}", path, ec.message())); } - removedBgpConfig = true; + removedAny = true; } - if (removedConfig || removedMetadata || removedBgpConfig) { + if (removedAny) { return "Config session cleared successfully."; } return "No config session exists. Nothing to clear."; diff --git a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionCommit.cpp b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionCommit.cpp index 178be1c072dc6..18ffbed977b6e 100644 --- a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionCommit.cpp +++ b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionCommit.cpp @@ -59,11 +59,6 @@ CmdConfigSessionCommitTraits::RetType CmdConfigSessionCommit::queryClient( fmt::format("{} (warmboot)", serviceName)); } break; - case cli::ConfigActionLevel::BGP_RESTART: - for (const auto& serviceName : serviceNamesList) { - restartedServices.push_back(fmt::format("{} (restart)", serviceName)); - } - break; case cli::ConfigActionLevel::HITLESS: for (const auto& serviceName : serviceNamesList) { reloadedServices.push_back(serviceName); diff --git a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.cpp b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.cpp index 784af028a8ae0..7659277d3eb72 100644 --- a/fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.cpp +++ b/fboss/cli/fboss2/commands/config/session/CmdConfigSessionDiff.cpp @@ -34,37 +34,7 @@ namespace facebook::fboss { namespace { -// Git-relative paths of the two config files tracked in the /etc/coop repo. -constexpr auto kAgentGitRelPath = "cli/agent.conf"; -constexpr auto kBgpGitRelPath = "bgpcpp/bgpcpp.conf"; - -// A diffable config domain. The agent config and the BGP config are tracked in -// the same /etc/coop git repo but live in different files; `config session -// diff` shows whichever domain(s) are staged/relevant. -struct DiffDomain { - std::string name; // "Agent" / "BGP" (section header when >1 domain shown) - std::string gitRelPath; // path in the git repo (e.g. cli/agent.conf) - std::string systemPath; // current live file - std::string sessionPath; // staged session file (~/.fboss2/...) - bool staged; // a session edit is staged for this domain -}; - -std::vector allDomains(ConfigSession& session) { - return { - DiffDomain{ - "Agent", - kAgentGitRelPath, - session.getSystemConfigPath(), - session.getSessionConfigPath(), - session.sessionExists()}, - DiffDomain{ - "BGP", - kBgpGitRelPath, - session.getBgpSystemConfigPath(), - session.getBgpSessionConfigPath(), - session.bgpSessionExists()}, - }; -} +using ConfigDomain = ConfigSession::ConfigDomain; // Read a file, returning empty content (not an error) when it doesn't exist. std::string readFileOrEmpty(const std::string& path) { @@ -76,20 +46,23 @@ std::string readFileOrEmpty(const std::string& path) { // Get config content from a revision specifier for a specific domain file. // "current" reads the live system file. A path absent at the given revision // (e.g. a commit predating BGP config) is treated as empty content. +// validationPath is a file present in every commit (the agent config), used to +// distinguish a genuinely invalid revision from a domain simply absent there. std::pair getRevisionContent( const std::string& revision, - const DiffDomain& domain, + const ConfigDomain& domain, + const std::string& validationPath, Git& git) { if (revision == "current") { return {readFileOrEmpty(domain.systemPath), "current live config"}; } std::string resolvedSha = git.resolveRef(revision); // Verify the revision is real before treating a missing domain path as empty. - // cli/agent.conf is present in every commit (including the initial one), so a - // genuinely invalid revision throws here and propagates; only a path absent + // The agent config is present in every commit (including the initial one), so + // a genuinely invalid revision throws here and propagates; only a path absent // at an otherwise-valid revision (e.g. bgpcpp.conf before BGP existed) is // treated as empty. - git.fileAtRevision(resolvedSha, kAgentGitRelPath); + git.fileAtRevision(resolvedSha, validationPath); std::string content; try { content = git.fileAtRevision(resolvedSha, domain.gitRelPath); @@ -184,35 +157,35 @@ CmdConfigSessionDiffTraits::RetType CmdConfigSessionDiff::queryClient( const utils::RevisionList& revisions) { auto& session = ConfigSession::getInstance(); auto& git = session.getGit(); - auto domains = allDomains(session); + auto domains = session.configDomains(); + + // A git path present in every commit (the agent config), used to validate a + // revision in getRevisionContent(). configDomains() lists the agent first. + std::string validationPath = domains.front().gitRelPath; // Modes 1 and 2 both diff each staged domain's session file against some // "base" (current live config for mode 1; a revision for mode 2). The only // difference is how the base content+label is obtained, so share the loop. auto diffStagedDomains = [&](const std::function( - const DiffDomain&)>& getBase) { - int stagedCount = 0; + const ConfigDomain&)>& getBase) { + // Read each domain's staged content once via the shared primitive + // (nullopt == not staged), so we neither re-stat nor re-read files. + std::vector> staged; for (const auto& d : domains) { - stagedCount += d.staged ? 1 : 0; + if (auto content = session.readStagedContent(d)) { + staged.emplace_back(d, std::move(*content)); + } } std::string out; - for (const auto& d : domains) { - if (!d.staged) { - continue; - } + for (const auto& [d, sessionContent] : staged) { auto [baseContent, baseLabel] = getBase(d); - std::string sessionContent; - if (!folly::readFile(d.sessionPath.c_str(), sessionContent)) { - throw std::runtime_error( - "Failed to read session config from " + d.sessionPath); - } appendSection( out, d.name, executeDiff( baseContent, sessionContent, baseLabel, "session config"), - stagedCount > 1); + staged.size() > 1); } return out; }; @@ -222,7 +195,7 @@ CmdConfigSessionDiffTraits::RetType CmdConfigSessionDiff::queryClient( if (!session.hasActiveSession()) { return "No config session exists. Make a config change first."; } - return diffStagedDomains([&](const DiffDomain& d) { + return diffStagedDomains([&](const ConfigDomain& d) { return std::make_pair( readFileOrEmpty(d.systemPath), std::string("current live config")); }); @@ -233,8 +206,8 @@ CmdConfigSessionDiffTraits::RetType CmdConfigSessionDiff::queryClient( if (!session.hasActiveSession()) { return "No config session exists. Make a config change first."; } - return diffStagedDomains([&](const DiffDomain& d) { - return getRevisionContent(revisions[0], d, git); + return diffStagedDomains([&](const ConfigDomain& d) { + return getRevisionContent(revisions[0], d, validationPath, git); }); } @@ -245,8 +218,8 @@ CmdConfigSessionDiffTraits::RetType CmdConfigSessionDiff::queryClient( // when more than one domain is shown. std::vector> sections; // {name, body} for (const auto& d : domains) { - auto [c1, l1] = getRevisionContent(revisions[0], d, git); - auto [c2, l2] = getRevisionContent(revisions[1], d, git); + auto [c1, l1] = getRevisionContent(revisions[0], d, validationPath, git); + auto [c2, l2] = getRevisionContent(revisions[1], d, validationPath, git); if (c1.empty() && c2.empty()) { continue; // domain absent at both revisions } diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp new file mode 100644 index 0000000000000..26fbfb3f972cb --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h" +#include +#include + +#include "fboss/cli/fboss2/CmdHandler.cpp" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +CmdDeleteProtocolBgpTraits::RetType CmdDeleteProtocolBgp::queryClient( + const HostInfo& /* hostInfo */) { + return "Delete BGP configuration objects. Use subcommands: neighbor"; +} + +void CmdDeleteProtocolBgp::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +template void +CmdHandler::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h new file mode 100644 index 0000000000000..a79dfc13580fd --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/CmdDeleteProtocol.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +struct CmdDeleteProtocolBgpTraits : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocol; + static constexpr utils::ObjectArgTypeId ObjectArgTypeId = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_NONE; + using ObjectArgType = std::monostate; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgp + : public CmdHandler { + public: + using ObjectArgType = CmdDeleteProtocolBgpTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp new file mode 100644 index 0000000000000..ff337a33e0aeb --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpPeerAddr.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpNeighborConfig). +BgpNeighborRef::BgpNeighborRef(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.size() != 1) { + throw std::invalid_argument( + "Error: delete protocol bgp neighbor requires exactly one " + ""); + } + auto normalized = bgpcli::normalizeBgpPeerAddr(v[0]); + if (!normalized) { + throw std::invalid_argument( + fmt::format("Error: Invalid neighbor address '{}'", v[0])); + } + peerAddr_ = std::move(*normalized); +} + +CmdDeleteProtocolBgpNeighborTraits::RetType +CmdDeleteProtocolBgpNeighbor::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + auto it = bgpcli::findBgpPeer(cfg, args.peerAddr()); + if (it == cfg.peers()->end()) { + // Nothing is persisted for an unknown neighbor, so a typo'd delete can't + // stage an unrelated session change. + return fmt::format("Error: BGP neighbor {} not found", args.peerAddr()); + } + cfg.peers()->erase(it); + session.saveBgpConfig(); + return fmt::format( + "Successfully deleted BGP neighbor {}\nConfig saved to: {}", + args.peerAddr(), + session.getBgpSessionConfigPath()); +} + +void CmdDeleteProtocolBgpNeighbor::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdDeleteProtocolBgpNeighbor, + CmdDeleteProtocolBgpNeighborTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h new file mode 100644 index 0000000000000..fa71727255c67 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `delete protocol bgp neighbor `, validated at +// construction. The address is normalized the same way the config command +// normalizes it, so any spelling of a peer's address deletes that peer. +class BgpNeighborRef : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpNeighborRef(std::vector v); + const std::string& peerAddr() const { + return peerAddr_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string peerAddr_; +}; + +struct CmdDeleteProtocolBgpNeighborTraits : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocolBgp; + static void addCliArg(CLI::App& cmd, std::vector& args) { + cmd.add_option("args", args, ""); + } + using ObjectArgType = BgpNeighborRef; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgpNeighbor : public CmdHandler< + CmdDeleteProtocolBgpNeighbor, + CmdDeleteProtocolBgpNeighborTraits> { + public: + using ObjectArgType = CmdDeleteProtocolBgpNeighborTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpNeighborTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp new file mode 100644 index 0000000000000..7fbe569d326e1 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +// Parse + validate at construction so queryClient stays a thin dispatch. +// Throwing std::invalid_argument is how the framework surfaces arg parse +// errors (same mechanism as BgpPeerGroupConfig). +BgpPeerGroupRef::BgpPeerGroupRef(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.size() != 1) { + throw std::invalid_argument( + "Error: delete protocol bgp peer-group requires exactly one "); + } + if (v[0].empty()) { + throw std::invalid_argument("Error: peer-group name must not be empty"); + } + groupName_ = std::move(v[0]); +} + +CmdDeleteProtocolBgpPeerGroupTraits::RetType +CmdDeleteProtocolBgpPeerGroup::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + if (!cfg.peer_groups().has_value()) { + // Nothing is persisted for an unknown group, so a typo'd delete can't + // stage an unrelated session change. + return fmt::format("Error: BGP peer-group {} not found", args.groupName()); + } + auto& groups = *cfg.peer_groups(); + auto it = std::find_if(groups.begin(), groups.end(), [&](const auto& group) { + return *group.name() == args.groupName(); + }); + if (it == groups.end()) { + return fmt::format("Error: BGP peer-group {} not found", args.groupName()); + } + groups.erase(it); + session.saveBgpConfig(); + return fmt::format( + "Successfully deleted BGP peer-group {}\nConfig saved to: {}", + args.groupName(), + session.getBgpSessionConfigPath()); +} + +void CmdDeleteProtocolBgpPeerGroup::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdDeleteProtocolBgpPeerGroup, + CmdDeleteProtocolBgpPeerGroupTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h new file mode 100644 index 0000000000000..c9793226e9a24 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `delete protocol bgp peer-group `, validated at construction. +// The group name is the group's identity (an arbitrary string), matched +// exactly the same way the config command stores it. Mirrors BgpNeighborRef. +class BgpPeerGroupRef : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpPeerGroupRef(std::vector v); + const std::string& groupName() const { + return groupName_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string groupName_; +}; + +struct CmdDeleteProtocolBgpPeerGroupTraits : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocolBgp; + static void addCliArg(CLI::App& cmd, std::vector& args) { + cmd.add_option("args", args, ""); + } + using ObjectArgType = BgpPeerGroupRef; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgpPeerGroup : public CmdHandler< + CmdDeleteProtocolBgpPeerGroup, + CmdDeleteProtocolBgpPeerGroupTraits> { + public: + using ObjectArgType = CmdDeleteProtocolBgpPeerGroupTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpPeerGroupTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp new file mode 100644 index 0000000000000..bc15db0a326f4 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.cpp @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h" +#include +#include + +#include "fboss/cli/fboss2/CmdHandler.cpp" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +CmdDeleteProtocolBgpPolicyTraits::RetType +CmdDeleteProtocolBgpPolicy::queryClient(const HostInfo& /* hostInfo */) { + return "Delete BGP policy objects. Use subcommands: as-path-list"; +} + +void CmdDeleteProtocolBgpPolicy::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +template void +CmdHandler::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h new file mode 100644 index 0000000000000..d658fee78a4ba --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/CmdDeleteProtocolBgp.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Grouping node for `delete protocol bgp policy `. Holds no +// state of its own; the per-object-type delete commands are its subcommands. +struct CmdDeleteProtocolBgpPolicyTraits : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocolBgp; + static constexpr utils::ObjectArgTypeId ObjectArgTypeId = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_NONE; + using ObjectArgType = std::monostate; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgpPolicy : public CmdHandler< + CmdDeleteProtocolBgpPolicy, + CmdDeleteProtocolBgpPolicyTraits> { + public: + using ObjectArgType = CmdDeleteProtocolBgpPolicyTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpPolicyTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp new file mode 100644 index 0000000000000..b9f3bfb68dab5 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +// Parse + validate at construction so queryClient stays a thin dispatch. +BgpAsPathListRef::BgpAsPathListRef(std::vector v) + : utils::BaseObjectArgType(v) { + if (v.size() != 1) { + throw std::invalid_argument( + "Error: delete protocol bgp policy as-path-list requires exactly one " + ""); + } + if (v[0].empty()) { + throw std::invalid_argument("Error: as-path-list name must not be empty"); + } + listName_ = std::move(v[0]); +} + +CmdDeleteProtocolBgpPolicyAsPathListTraits::RetType +CmdDeleteProtocolBgpPolicyAsPathList::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + if (!cfg.policies().has_value()) { + // Nothing is persisted for an unknown list, so a typo'd delete can't stage + // an unrelated session change. + return fmt::format("Error: BGP as-path-list {} not found", args.listName()); + } + auto& lists = *cfg.policies()->aspath_lists(); + auto it = std::find_if(lists.begin(), lists.end(), [&](const auto& list) { + return *list.name() == args.listName(); + }); + if (it == lists.end()) { + return fmt::format("Error: BGP as-path-list {} not found", args.listName()); + } + lists.erase(it); + session.saveBgpConfig(); + return fmt::format( + "Successfully deleted BGP as-path-list {}\nConfig saved to: {}", + args.listName(), + session.getBgpSessionConfigPath()); +} + +void CmdDeleteProtocolBgpPolicyAsPathList::printOutput(const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdDeleteProtocolBgpPolicyAsPathList, + CmdDeleteProtocolBgpPolicyAsPathListTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h new file mode 100644 index 0000000000000..4249bdd3546a4 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `delete protocol bgp policy as-path-list `, validated at +// construction. The name is the list's identity, matched exactly the same way +// the config command stores it. Mirrors BgpPeerGroupRef. +class BgpAsPathListRef : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpAsPathListRef(std::vector v); + const std::string& listName() const { + return listName_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string listName_; +}; + +struct CmdDeleteProtocolBgpPolicyAsPathListTraits : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocolBgpPolicy; + static void addCliArg(CLI::App& cmd, std::vector& args) { + cmd.add_option("args", args, ""); + } + using ObjectArgType = BgpAsPathListRef; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgpPolicyAsPathList + : public CmdHandler< + CmdDeleteProtocolBgpPolicyAsPathList, + CmdDeleteProtocolBgpPolicyAsPathListTraits> { + public: + using ObjectArgType = + CmdDeleteProtocolBgpPolicyAsPathListTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpPolicyAsPathListTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp new file mode 100644 index 0000000000000..7788aa590c96f --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h" + +#include "fboss/cli/fboss2/CmdHandler.cpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpCliValueParsers.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" +#include "fmt/format.h" + +namespace facebook::fboss { + +namespace { +// CLI keyword selecting the nested community member, matching the config +// command's grammar. +constexpr std::string_view kObjectName = "community-list"; +constexpr std::string_view kCommunityKeyword = "community"; +} // namespace + +// Parse + validate at construction so queryClient stays a thin dispatch. +BgpCommunityListRef::BgpCommunityListRef(std::vector v) + : utils::BaseObjectArgType(v) { + auto selector = bgpcli::parseListMemberSelector( + v, + kObjectName, + kCommunityKeyword, + "Error: delete protocol bgp policy community-list requires , " + "optionally followed by `community `"); + // Unlike the config grammar, nothing may follow the parsed prefix: there + // are no attributes to delete through this command. + if (selector.restStart < v.size()) { + throw std::invalid_argument( + selector.memberName + ? fmt::format( + "Error: unexpected token '{}' after community ", + v[selector.restStart]) + : fmt::format( + "Error: unexpected token '{}'. Usage: delete protocol bgp " + "policy community-list [community ]", + v[selector.restStart])); + } + listName_ = std::move(selector.listName); + if (selector.memberName) { + hasCommunity_ = true; + communityName_ = std::move(*selector.memberName); + } +} + +CmdDeleteProtocolBgpPolicyCommunityListTraits::RetType +CmdDeleteProtocolBgpPolicyCommunityList::queryClient( + const HostInfo& /* hostInfo */, + const ObjectArgType& args) { + auto& session = ConfigSession::getInstance(); + auto& cfg = session.getBgpConfig(); + if (!cfg.policies().has_value()) { + // Nothing is persisted for an unknown list, so a typo'd delete can't stage + // an unrelated session change. + return fmt::format( + "Error: BGP community-list {} not found", args.listName()); + } + auto& lists = *cfg.policies()->community_lists(); + auto it = std::find_if(lists.begin(), lists.end(), [&](const auto& list) { + return *list.name() == args.listName(); + }); + if (it == lists.end()) { + return fmt::format( + "Error: BGP community-list {} not found", args.listName()); + } + if (args.hasCommunity()) { + // Delete a single inline member; the list itself stays. + auto& list = *it; + if (list.members().has_value()) { + auto& members = *list.members(); + auto memberIt = + std::find_if(members.begin(), members.end(), [&](const auto& member) { + return member.community_ref().has_value() && + *member.community_ref()->name() == args.communityName(); + }); + if (memberIt != members.end()) { + members.erase(memberIt); + if (members.empty()) { + // Leave the list looking like one that never had members, so a + // later `community ` add starts from the same shape. + list.members().reset(); + } + session.saveBgpConfig(); + return fmt::format( + "Successfully deleted BGP community-list {} community {}\n" + "Config saved to: {}", + args.listName(), + args.communityName(), + session.getBgpSessionConfigPath()); + } + } + return fmt::format( + "Error: BGP community-list {} community {} not found", + args.listName(), + args.communityName()); + } + lists.erase(it); + session.saveBgpConfig(); + return fmt::format( + "Successfully deleted BGP community-list {}\nConfig saved to: {}", + args.listName(), + session.getBgpSessionConfigPath()); +} + +void CmdDeleteProtocolBgpPolicyCommunityList::printOutput( + const RetType& output) { + std::cout << output << std::endl; +} + +// Explicit template instantiation +template void CmdHandler< + CmdDeleteProtocolBgpPolicyCommunityList, + CmdDeleteProtocolBgpPolicyCommunityListTraits>::run(); + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h new file mode 100644 index 0000000000000..127ea9d6e8e74 --- /dev/null +++ b/fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2004-present, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD-style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + * + */ + +#pragma once + +#include +#include +#include "CLI/App.hpp" +#include "fboss/cli/fboss2/CmdHandler.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/CmdDeleteProtocolBgpPolicy.h" +#include "fboss/cli/fboss2/utils/CmdUtilsCommon.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +namespace facebook::fboss { + +// Parsed `delete protocol bgp policy community-list +// [community ]`, validated at construction. The names are the list's +// and member's identity, matched exactly the same way the config command +// stores them. Without the `community` selector the whole list is deleted; +// with it, only that inline member. Mirrors BgpAsPathListRef. +class BgpCommunityListRef : public utils::BaseObjectArgType { + public: + // NOLINTNEXTLINE(google-explicit-constructor) + /* implicit */ BgpCommunityListRef(std::vector v); + const std::string& listName() const { + return listName_; + } + bool hasCommunity() const { + return hasCommunity_; + } + const std::string& communityName() const { + return communityName_; + } + const static utils::ObjectArgTypeId id = + utils::ObjectArgTypeId::OBJECT_ARG_TYPE_ID_MESSAGE; + + private: + std::string listName_; + bool hasCommunity_{false}; + std::string communityName_; +}; + +struct CmdDeleteProtocolBgpPolicyCommunityListTraits + : public WriteCommandTraits { + using ParentCmd = CmdDeleteProtocolBgpPolicy; + static void addCliArg(CLI::App& cmd, std::vector& args) { + cmd.add_option("args", args, " [community ]"); + } + using ObjectArgType = BgpCommunityListRef; + using RetType = std::string; +}; + +class CmdDeleteProtocolBgpPolicyCommunityList + : public CmdHandler< + CmdDeleteProtocolBgpPolicyCommunityList, + CmdDeleteProtocolBgpPolicyCommunityListTraits> { + public: + using ObjectArgType = + CmdDeleteProtocolBgpPolicyCommunityListTraits::ObjectArgType; + using RetType = CmdDeleteProtocolBgpPolicyCommunityListTraits::RetType; + + RetType queryClient(const HostInfo& hostInfo, const ObjectArgType& args); + + void printOutput(const RetType& output); +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/commands/show/acl/BUILD.bazel b/fboss/cli/fboss2/commands/show/acl/BUILD.bazel new file mode 100644 index 0000000000000..209cdc16db225 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/acl/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/acl/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowAcl.cpp"], + hdrs = ["CmdShowAcl.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/agent/BUILD.bazel b/fboss/cli/fboss2/commands/show/agent/BUILD.bazel new file mode 100644 index 0000000000000..46d5971c1c02f --- /dev/null +++ b/fboss/cli/fboss2/commands/show/agent/BUILD.bazel @@ -0,0 +1,122 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/agent/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowAgentBootType.cpp", + "CmdShowAgentFirmware.cpp", + "CmdShowAgentSsl.cpp", + ], + hdrs = [ + "CmdShowAgentBootType.h", + "CmdShowAgentFirmware.h", + "CmdShowAgentSsl.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/aggregateport/BUILD.bazel b/fboss/cli/fboss2/commands/show/aggregateport/BUILD.bazel new file mode 100644 index 0000000000000..9d3a62816cde1 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/aggregateport/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/aggregateport/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowAggregatePort.cpp"], + hdrs = ["CmdShowAggregatePort.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/arp/BUILD.bazel b/fboss/cli/fboss2/commands/show/arp/BUILD.bazel new file mode 100644 index 0000000000000..ae20828c79dec --- /dev/null +++ b/fboss/cli/fboss2/commands/show/arp/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/arp/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowArp.cpp"], + hdrs = ["CmdShowArp.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/bgp/summary/BUILD.bazel b/fboss/cli/fboss2/commands/show/bgp/summary/BUILD.bazel new file mode 100644 index 0000000000000..167c56031a07c --- /dev/null +++ b/fboss/cli/fboss2/commands/show/bgp/summary/BUILD.bazel @@ -0,0 +1,118 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/bgp/summary/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "bgp_summary", + thrift_srcs = ["bgp_summary.thrift"], + thrift_cpp2_options = "json", + deps = ["//neteng/fboss/bgp/if:bgp_thrift"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["egress/CmdShowBgpSummaryEgress.cpp"], + hdrs = [ + "CmdShowBgpSummary.h", + "egress/CmdShowBgpSummaryEgress.h", + ], + deps = [ + ":bgp_summary", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/bgp/table/BUILD.bazel b/fboss/cli/fboss2/commands/show/bgp/table/BUILD.bazel new file mode 100644 index 0000000000000..8f46432164d5d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/bgp/table/BUILD.bazel @@ -0,0 +1,129 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/bgp/table/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "bgp_table_summary", + thrift_srcs = ["bgp_table_summary.thrift"], + thrift_cpp2_options = "json", + deps = ["//neteng/fboss/bgp/if:bgp_thrift"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowBgpTable.cpp", + "CmdShowBgpTableCommunity.cpp", + "CmdShowBgpTableDetail.cpp", + "CmdShowBgpTableMoreSpecifics.cpp", + "CmdShowBgpTablePrefix.cpp", + ], + hdrs = [ + "CmdShowBgpTable.h", + "CmdShowBgpTableCommunity.h", + "CmdShowBgpTableDetail.h", + "CmdShowBgpTableMoreSpecifics.h", + "CmdShowBgpTablePrefix.h", + "CmdShowBgpTableSummary.h", + ], + deps = [ + ":bgp_table_summary", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/bgp/updategroup/BUILD.bazel b/fboss/cli/fboss2/commands/show/bgp/updategroup/BUILD.bazel new file mode 100644 index 0000000000000..248470d98903d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/bgp/updategroup/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/bgp/updategroup/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "bgp_update_group", + thrift_srcs = ["bgp_update_group.thrift"], + thrift_cpp2_options = "json", + deps = ["//neteng/fboss/bgp/if:bgp_thrift"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowBgpUpdateGroup.cpp"], + hdrs = ["CmdShowBgpUpdateGroup.h"], + deps = [ + ":bgp_update_group", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/cpuport/BUILD.bazel b/fboss/cli/fboss2/commands/show/cpuport/BUILD.bazel new file mode 100644 index 0000000000000..11f0a5970a170 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/cpuport/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/cpuport/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowCpuPort.cpp"], + hdrs = ["CmdShowCpuPort.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/dsf/subscription/BUILD.bazel b/fboss/cli/fboss2/commands/show/dsf/subscription/BUILD.bazel new file mode 100644 index 0000000000000..c657d5845e639 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/dsf/subscription/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/dsf/subscription/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowDsfSubscription.cpp"], + hdrs = ["CmdShowDsfSubscription.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/dsfnodes/BUILD.bazel b/fboss/cli/fboss2/commands/show/dsfnodes/BUILD.bazel new file mode 100644 index 0000000000000..5648c54f0b828 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/dsfnodes/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/dsfnodes/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowDsfNodes.cpp"], + hdrs = ["CmdShowDsfNodes.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/example/BUILD.bazel b/fboss/cli/fboss2/commands/show/example/BUILD.bazel new file mode 100644 index 0000000000000..a3b5089fa697c --- /dev/null +++ b/fboss/cli/fboss2/commands/show/example/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/example/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowExample.cpp"], + hdrs = ["CmdShowExample.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/fabric/BUILD.bazel b/fboss/cli/fboss2/commands/show/fabric/BUILD.bazel new file mode 100644 index 0000000000000..e3a51f1294e80 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/fabric/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/fabric/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowFabric.cpp"], + hdrs = ["CmdShowFabric.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/fabric/inputbalance/BUILD.bazel b/fboss/cli/fboss2/commands/show/fabric/inputbalance/BUILD.bazel new file mode 100644 index 0000000000000..e2f9bbd97e2f6 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/fabric/inputbalance/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/fabric/inputbalance/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowFabricInputBalance.cpp"], + hdrs = ["CmdShowFabricInputBalance.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/fabric/monitoring/BUILD.bazel b/fboss/cli/fboss2/commands/show/fabric/monitoring/BUILD.bazel new file mode 100644 index 0000000000000..a9bda2131a62d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/fabric/monitoring/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/fabric/monitoring/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowFabricMonitoringCounters.cpp", + "CmdShowFabricMonitoringDetails.cpp", + ], + hdrs = [ + "CmdShowFabricMonitoringCounters.h", + "CmdShowFabricMonitoringDetails.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/fabric/reachability/BUILD.bazel b/fboss/cli/fboss2/commands/show/fabric/reachability/BUILD.bazel new file mode 100644 index 0000000000000..fa5f5975d36b2 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/fabric/reachability/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/fabric/reachability/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowFabricReachability.cpp", + "uncached/CmdShowFabricReachabilityUncached.cpp", + ], + hdrs = [ + "CmdShowFabricReachability.h", + "uncached/CmdShowFabricReachabilityUncached.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/fabric/topology/BUILD.bazel b/fboss/cli/fboss2/commands/show/fabric/topology/BUILD.bazel new file mode 100644 index 0000000000000..7b00e9e71d5b4 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/fabric/topology/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/fabric/topology/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowFabricTopology.cpp"], + hdrs = ["CmdShowFabricTopology.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/flowlet/BUILD.bazel b/fboss/cli/fboss2/commands/show/flowlet/BUILD.bazel new file mode 100644 index 0000000000000..248206c55eaaf --- /dev/null +++ b/fboss/cli/fboss2/commands/show/flowlet/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/flowlet/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowFlowlet.cpp"], + hdrs = ["CmdShowFlowlet.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/hardware/BUILD.bazel b/fboss/cli/fboss2/commands/show/hardware/BUILD.bazel new file mode 100644 index 0000000000000..19dcf2f1206e3 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/hardware/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/hardware/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowHardware.cpp"], + hdrs = ["CmdShowHardware.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/host/BUILD.bazel b/fboss/cli/fboss2/commands/show/host/BUILD.bazel new file mode 100644 index 0000000000000..d295d7e2ccc21 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/host/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/host/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowHost.cpp"], + hdrs = ["CmdShowHost.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/hwagent/BUILD.bazel b/fboss/cli/fboss2/commands/show/hwagent/BUILD.bazel new file mode 100644 index 0000000000000..ac0fc20b51241 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/hwagent/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/hwagent/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowHwAgentStatus.cpp"], + hdrs = ["CmdShowHwAgentStatus.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/BUILD.bazel new file mode 100644 index 0000000000000..7889a65a8e005 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/BUILD.bazel @@ -0,0 +1,121 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/agent:switch_config"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowInterface.cpp", + "prbs/CmdShowInterfacePrbs.cpp", + ], + hdrs = [ + "CmdShowInterface.h", + "prbs/CmdShowInterfacePrbs.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/capabilities/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/capabilities/BUILD.bazel new file mode 100644 index 0000000000000..eaac7a023c546 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/capabilities/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/capabilities/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/agent:switch_config"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCapabilities.cpp"], + hdrs = ["CmdShowInterfaceCapabilities.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/BUILD.bazel new file mode 100644 index 0000000000000..15423084bd88a --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowInterfaceCounters.cpp", + "fec/CmdShowInterfaceCountersFec.cpp", + ], + hdrs = [ + "CmdShowInterfaceCounters.h", + "fec/CmdShowInterfaceCountersFec.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/fec/ber/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/fec/ber/BUILD.bazel new file mode 100644 index 0000000000000..dc3c0e66bbdf9 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/fec/ber/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/fec/ber/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCountersFecBer.cpp"], + hdrs = ["CmdShowInterfaceCountersFecBer.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/fec/histogram/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/fec/histogram/BUILD.bazel new file mode 100644 index 0000000000000..b2f63ca879c1b --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/fec/histogram/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/fec/histogram/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCountersFecHistogram.cpp"], + hdrs = ["CmdShowInterfaceCountersFecHistogram.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/fec/tail/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/fec/tail/BUILD.bazel new file mode 100644 index 0000000000000..f38566fa579df --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/fec/tail/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/fec/tail/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCountersFecTail.cpp"], + hdrs = ["CmdShowInterfaceCountersFecTail.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable/BUILD.bazel new file mode 100644 index 0000000000000..411b9d7bde49b --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCountersFecUncorrectable.cpp"], + hdrs = ["CmdShowInterfaceCountersFecUncorrectable.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/counters/mka/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/counters/mka/BUILD.bazel new file mode 100644 index 0000000000000..271be5d3b8113 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/counters/mka/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/counters/mka/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/agent/hw:hardware_stats"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceCountersMKA.cpp"], + hdrs = ["CmdShowInterfaceCountersMKA.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/errors/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/errors/BUILD.bazel new file mode 100644 index 0000000000000..2f77127aaf75b --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/errors/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/errors/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceErrors.cpp"], + hdrs = ["CmdShowInterfaceErrors.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/flaps/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/flaps/BUILD.bazel new file mode 100644 index 0000000000000..0724d9356e04d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/flaps/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/flaps/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceFlaps.cpp"], + hdrs = ["CmdShowInterfaceFlaps.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/phy/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/phy/BUILD.bazel new file mode 100644 index 0000000000000..dc449d975bb2e --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/phy/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/phy/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfacePhy.cpp"], + hdrs = ["CmdShowInterfacePhy.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/phymap/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/phymap/BUILD.bazel new file mode 100644 index 0000000000000..51a6e785dddb0 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/phymap/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/phymap/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/mka_service/if:mka_structs"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfacePhymap.cpp"], + hdrs = ["CmdShowInterfacePhymap.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/prbs/capabilities/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/prbs/capabilities/BUILD.bazel new file mode 100644 index 0000000000000..13d1224968998 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/prbs/capabilities/BUILD.bazel @@ -0,0 +1,118 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/prbs/capabilities/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = [ + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfacePrbsCapabilities.cpp"], + hdrs = ["CmdShowInterfacePrbsCapabilities.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/prbs/state/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/prbs/state/BUILD.bazel new file mode 100644 index 0000000000000..3705bf4843bba --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/prbs/state/BUILD.bazel @@ -0,0 +1,118 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/prbs/state/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = [ + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfacePrbsState.cpp"], + hdrs = ["CmdShowInterfacePrbsState.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/prbs/stats/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/prbs/stats/BUILD.bazel new file mode 100644 index 0000000000000..6bc068eb99bf3 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/prbs/stats/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/prbs/stats/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/lib/phy:phy"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfacePrbsStats.cpp"], + hdrs = ["CmdShowInterfacePrbsStats.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/status/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/status/BUILD.bazel new file mode 100644 index 0000000000000..9177191c29c1b --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/status/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/status/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceStatus.cpp"], + hdrs = ["CmdShowInterfaceStatus.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/interface/traffic/BUILD.bazel b/fboss/cli/fboss2/commands/show/interface/traffic/BUILD.bazel new file mode 100644 index 0000000000000..131b0a3e062c0 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/interface/traffic/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/interface/traffic/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowInterfaceTraffic.cpp"], + hdrs = ["CmdShowInterfaceTraffic.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/lldp/BUILD.bazel b/fboss/cli/fboss2/commands/show/lldp/BUILD.bazel new file mode 100644 index 0000000000000..a034361315408 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/lldp/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/lldp/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowLldp.cpp"], + hdrs = ["CmdShowLldp.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/mac/BUILD.bazel b/fboss/cli/fboss2/commands/show/mac/BUILD.bazel new file mode 100644 index 0000000000000..7e34c2db42746 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/mac/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/mac/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowMacAddrToBlock.cpp", + "CmdShowMacDetails.cpp", + ], + hdrs = [ + "CmdShowMacAddrToBlock.h", + "CmdShowMacDetails.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/mirror/BUILD.bazel b/fboss/cli/fboss2/commands/show/mirror/BUILD.bazel new file mode 100644 index 0000000000000..1518fa90af824 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/mirror/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/mirror/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowMirror.cpp"], + hdrs = ["CmdShowMirror.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/mpls/BUILD.bazel b/fboss/cli/fboss2/commands/show/mpls/BUILD.bazel new file mode 100644 index 0000000000000..593ad209c20f3 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/mpls/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/mpls/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/cli/fboss2/commands/show/route:model"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowMplsRoute.cpp"], + hdrs = ["CmdShowMplsRoute.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/mysid/BUILD.bazel b/fboss/cli/fboss2/commands/show/mysid/BUILD.bazel new file mode 100644 index 0000000000000..016a5befdeec1 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/mysid/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/mysid/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowMySid.cpp"], + hdrs = ["CmdShowMySid.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/ndp/BUILD.bazel b/fboss/cli/fboss2/commands/show/ndp/BUILD.bazel new file mode 100644 index 0000000000000..0d048767cad3b --- /dev/null +++ b/fboss/cli/fboss2/commands/show/ndp/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/ndp/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowNdp.cpp"], + hdrs = ["CmdShowNdp.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/nexthopgroups/BUILD.bazel b/fboss/cli/fboss2/commands/show/nexthopgroups/BUILD.bazel new file mode 100644 index 0000000000000..0cf6189e9f296 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/nexthopgroups/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/nexthopgroups/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowNextHopGroups.cpp"], + hdrs = ["CmdShowNextHopGroups.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/port/BUILD.bazel b/fboss/cli/fboss2/commands/show/port/BUILD.bazel new file mode 100644 index 0000000000000..01dcb8111f88e --- /dev/null +++ b/fboss/cli/fboss2/commands/show/port/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/port/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowPort.cpp", + "CmdShowPortQueue.cpp", + ], + hdrs = [ + "CmdShowPort.h", + "CmdShowPortQueue.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/product/BUILD.bazel b/fboss/cli/fboss2/commands/show/product/BUILD.bazel new file mode 100644 index 0000000000000..cf3878db023ad --- /dev/null +++ b/fboss/cli/fboss2/commands/show/product/BUILD.bazel @@ -0,0 +1,120 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/product/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowProduct.cpp", + "CmdShowProductDetails.cpp", + ], + hdrs = [ + "CmdShowProduct.h", + "CmdShowProductDetails.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/rif/BUILD.bazel b/fboss/cli/fboss2/commands/show/rif/BUILD.bazel new file mode 100644 index 0000000000000..0fcbe9837523d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/rif/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/rif/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowRif.cpp"], + hdrs = ["CmdShowRif.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/route/BUILD.bazel b/fboss/cli/fboss2/commands/show/route/BUILD.bazel new file mode 100644 index 0000000000000..89a3c17ce7cf7 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/route/BUILD.bazel @@ -0,0 +1,125 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/route/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/agent/if:common"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowRoute.cpp", + "CmdShowRouteDetails.cpp", + "CmdShowRouteSummary.cpp", + "utils.cpp", + ], + hdrs = [ + "CmdShowRoute.h", + "CmdShowRouteDetails.h", + "CmdShowRouteSummary.h", + "utils.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/systemport/BUILD.bazel b/fboss/cli/fboss2/commands/show/systemport/BUILD.bazel new file mode 100644 index 0000000000000..8b179c4ae0b2d --- /dev/null +++ b/fboss/cli/fboss2/commands/show/systemport/BUILD.bazel @@ -0,0 +1,114 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/systemport/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowSystemPort.cpp"], + hdrs = ["CmdShowSystemPort.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/teflow/BUILD.bazel b/fboss/cli/fboss2/commands/show/teflow/BUILD.bazel new file mode 100644 index 0000000000000..bcd27dde0f960 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/teflow/BUILD.bazel @@ -0,0 +1,115 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/teflow/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/cli/fboss2/commands/show/route:model"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = ["CmdShowTeFlow.cpp"], + hdrs = ["CmdShowTeFlow.h"], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/commands/show/transceiver/BUILD.bazel b/fboss/cli/fboss2/commands/show/transceiver/BUILD.bazel new file mode 100644 index 0000000000000..ecdab5b864083 --- /dev/null +++ b/fboss/cli/fboss2/commands/show/transceiver/BUILD.bazel @@ -0,0 +1,125 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/commands/show/transceiver/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_library") +load("//fboss/build_defs:thrift_library.bzl", "fboss_thrift_library") + +fboss_thrift_library( + name = "model", + thrift_srcs = ["model.thrift"], + thrift_cpp2_options = "json", + deps = ["//fboss/qsfp_service/if:transceiver"], + visibility = ["//visibility:public"], +) + +cc_library( + name = "_impl", + srcs = [ + "CmdShowTransceiver.cpp", + "eeprom/CmdShowTransceiverEeprom.cpp", + "eeprom/CmdShowTransceiverEepromDump.cpp", + "loopback/CmdShowTransceiverLoopback.cpp", + ], + hdrs = [ + "CmdShowTransceiver.h", + "eeprom/CmdShowTransceiverEeprom.h", + "eeprom/CmdShowTransceiverEepromDump.h", + "loopback/CmdShowTransceiverLoopback.h", + ], + deps = [ + ":model", + "//fboss/agent/hw:hardware_stats", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent/if:fboss", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:address_utils", + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:switch_config", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/bgp/updategroup:bgp_update_group", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/dsf/subscription:model", + "//fboss/cli/fboss2/commands/show/dsfnodes:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/fabric/inputbalance:model", + "//fboss/cli/fboss2/commands/show/fabric/monitoring:model", + "//fboss/cli/fboss2/commands/show/fabric/reachability:model", + "//fboss/cli/fboss2/commands/show/fabric/topology:model", + "//fboss/cli/fboss2/commands/show/fabric:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/ber:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/tail:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/uncorrectable:model", + "//fboss/cli/fboss2/commands/show/interface/counters/mka:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/phy:model", + "//fboss/cli/fboss2/commands/show/interface/phymap:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/capabilities:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/state:model", + "//fboss/cli/fboss2/commands/show/interface/prbs/stats:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mac:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/mpls:model", + "//fboss/cli/fboss2/commands/show/mysid:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/nexthopgroups:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/rif:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/fsdb/if:fsdb", + "//fboss/fsdb/if:fsdb_common", + "//fboss/fsdb/if:fsdb_model", + "//fboss/fsdb/if:fsdb_oper", + "//fboss/fsdb/oper/instantiations:fsdb_path_converter", + "//fboss/led_service/if:led_service", + "//fboss/lib/inputbalance:input_balance_util", + "//fboss/lib/phy:phy", + "//fboss/lib/phy:prbs", + "//fboss/mka_service/if:mka_structs", + "//fboss/platform/data_corral_service/if:data_corral_service", + "//fboss/platform/fan_service/if:fan_service", + "//fboss/platform/rackmon/if:rackmonsvc", + "//fboss/platform/sensor_service/if:sensor_service", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-handler", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:safety-prompt-utils", + "//fboss/cli/fboss2:table-utils", + "@CLI11//:CLI11", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@glog//:glog", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/docs/BGP_CLI_TEST_PLAN.md b/fboss/cli/fboss2/docs/BGP_CLI_TEST_PLAN.md index 65cb71b350d0c..37a64fd61426b 100644 --- a/fboss/cli/fboss2/docs/BGP_CLI_TEST_PLAN.md +++ b/fboss/cli/fboss2/docs/BGP_CLI_TEST_PLAN.md @@ -79,10 +79,10 @@ fboss2 config protocol bgp peer-group RSW-FSW-V6 timers keepalive 10 fboss2 config protocol bgp peer-group RSW-RTSW-V6 disable-ipv4-afi true # Peer configuration (with explicit disable_ipv4_afi: false preserved) -fboss2 config protocol bgp peer 2401:db00:501c::/64 remote-asn 65000 -fboss2 config protocol bgp peer 2401:db00:501c::/64 local-addr 2401:db00:501c::a -fboss2 config protocol bgp peer 2401:db00:501c::/64 passive true -fboss2 config protocol bgp peer 2401:db00:501c::/64 disable-ipv4-afi false +fboss2 config protocol bgp neighbor 2401:db00:501c::/64 remote-asn 65000 +fboss2 config protocol bgp neighbor 2401:db00:501c::/64 bind-addr address 2401:db00:501c::a +fboss2 config protocol bgp neighbor 2401:db00:501c::/64 connect-mode PASSIVE +fboss2 config protocol bgp neighbor 2401:db00:501c::/64 afi disable-ipv4-afi false ``` ### Step 5: Execute Script @@ -136,12 +136,13 @@ diff <(jq -S . /tmp/rsw_bgp_nao.txt) <(jq -S . ~/.fboss2/bgp_config.json) | Peer Group | `config protocol bgp peer-group timers hold-time ` | Set hold time | | Peer Group | `config protocol bgp peer-group timers keepalive ` | Set keepalive interval | | Peer Group | `config protocol bgp peer-group max-routes ` | Set max routes | -| Peer | `config protocol bgp peer remote-asn ` | Set remote AS | -| Peer | `config protocol bgp peer peer-group ` | Assign to peer group | -| Peer | `config protocol bgp peer local-addr ` | Set local address | -| Peer | `config protocol bgp peer passive ` | Set passive mode | -| Peer | `config protocol bgp peer disable-ipv4-afi ` | Disable IPv4 AFI | -| Peer | `config protocol bgp peer link-bandwidth ` | Set link bandwidth | +| Neighbor | `config protocol bgp neighbor remote-asn ` | Set remote AS | +| Neighbor | `config protocol bgp neighbor peer-group ` | Assign to peer group | +| Neighbor | `config protocol bgp neighbor bind-addr address ` | Set local address | +| Neighbor | `config protocol bgp neighbor connect-mode ` | Set connect mode | +| Neighbor | `delete protocol bgp neighbor ` | Delete a neighbor | +| Neighbor | `config protocol bgp neighbor afi disable-ipv4-afi ` | Disable IPv4 AFI | +| Neighbor | `config protocol bgp neighbor link-bandwidth ` | Set link bandwidth | ## Automated Test Script diff --git a/fboss/cli/fboss2/session/ConfigSession.cpp b/fboss/cli/fboss2/session/ConfigSession.cpp index aea3bcfc941dc..7d837eac51a99 100644 --- a/fboss/cli/fboss2/session/ConfigSession.cpp +++ b/fboss/cli/fboss2/session/ConfigSession.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -40,13 +41,10 @@ #include "fboss/agent/AgentDirectoryUtil.h" #include "fboss/agent/gen-cpp2/agent_config_types.h" #include "fboss/agent/gen-cpp2/switch_config_types.h" -#include "fboss/agent/if/gen-cpp2/FbossCtrl.h" -#include "fboss/agent/if/gen-cpp2/FbossCtrlAsyncClient.h" #include "fboss/cli/fboss2/gen-cpp2/cli_metadata_types.h" #include "fboss/cli/fboss2/session/FbossServiceUtil.h" #include "fboss/cli/fboss2/session/Git.h" #include "fboss/cli/fboss2/utils/CmdClientUtils.h" -#include "fboss/cli/fboss2/utils/CmdClientUtilsCommon.h" #include "fboss/cli/fboss2/utils/HostInfo.h" #include "fboss/cli/fboss2/utils/PortMap.h" @@ -321,6 +319,10 @@ ConfigSession::ConfigSession( // and tests don't need git initialization or config file copying } +// Out-of-line so the unique_ptr members' (forward-declared) types are complete +// here where they are destroyed. +ConfigSession::~ConfigSession() = default; + namespace { std::unique_ptr& getInstancePtr() { static std::unique_ptr instance; @@ -361,6 +363,17 @@ std::string ConfigSession::getBgpSessionConfigPathStatic() { return getSessionDir() + "/bgp_config.json"; } +std::vector ConfigSession::stagedSessionFilePaths() { + // Per-domain staged config files plus the session metadata. Keep this in sync + // with configDomains() (the sessionPath of each domain); a new domain adds + // one line here. + return { + getSessionConfigPathStatic(), // agent: ~/.fboss2/agent.conf + getBgpSessionConfigPathStatic(), // bgp: ~/.fboss2/bgp_config.json + getSessionMetadataPathStatic(), // shared: ~/.fboss2/cli_metadata.json + }; +} + std::string ConfigSession::fileAtRevisionOrEmpty( const std::string& revision, const std::string& gitRelPath) const { @@ -389,6 +402,149 @@ std::string ConfigSession::getCliConfigPath() const { return systemConfigDir_ + "/cli/agent.conf"; } +std::vector ConfigSession::configDomains() const { + return { + ConfigDomain{ + cli::ServiceType::AGENT, + "Agent", + getSessionConfigPath(), // ~/.fboss2/agent.conf + kAgentGitRelPath, // cli/agent.conf + getCliConfigPath(), // /etc/coop/cli/agent.conf (promoted) + getSystemConfigPath(), // /etc/coop/agent.conf (symlink, live read) + getSystemConfigPath(), // symlink IS the system path for the agent + kAgentGitRelPath, // symlink -> cli/agent.conf + cli::ConfigActionLevel::HITLESS, // rollback reloads the agent + }, + ConfigDomain{ + cli::ServiceType::BGP, + "BGP", + getBgpSessionConfigPath(), // ~/.fboss2/bgp_config.json + kBgpGitRelPath, // bgpcpp/bgpcpp.conf + getBgpSystemConfigPath(), // /etc/coop/bgpcpp/bgpcpp.conf (promoted) + getBgpSystemConfigPath(), // the promoted file is also the live read + getBgpSystemConfigLinkPath(), // /etc/coop/bgpcpp.conf (symlink) + kBgpGitRelPath, // symlink -> bgpcpp/bgpcpp.conf + cli::ConfigActionLevel::AGENT_WARMBOOT, // rollback restarts bgpd + }, + }; +} + +std::optional ConfigSession::readStagedContent( + const ConfigDomain& domain) const { + if (!fs::exists(domain.sessionPath)) { + return std::nullopt; + } + std::string content; + if (!folly::readFile(domain.sessionPath.c_str(), content)) { + throw std::runtime_error( + fmt::format( + "Failed to read session config from {}", domain.sessionPath)); + } + return content; +} + +std::string ConfigSession::readPromotedContent( + const ConfigDomain& domain) const { + std::string content; + if (fs::exists(domain.promotedPath)) { + if (!folly::readFile(domain.promotedPath.c_str(), content)) { + throw std::runtime_error( + fmt::format( + "Failed to read current config from {}", domain.promotedPath)); + } + } + return content; +} + +void ConfigSession::promoteDomain( + const ConfigDomain& domain, + const std::string& content, + std::vector& commitFiles) const { + ensureDirectoryExists(fs::path(domain.promotedPath).parent_path().string()); + folly::writeFileAtomic( + domain.promotedPath, content, 0644, folly::SyncType::WITH_SYNC); + commitFiles.push_back(domain.promotedPath); + // Keep the daemon-facing path a symlink into the CLI-managed dir so the + // daemon needs no per-device --config override. The symlink is git-tracked + // alongside the config so a rollback restores it. + atomicSymlinkUpdate(domain.symlinkPath, domain.symlinkTarget); + commitFiles.push_back(domain.symlinkPath); +} + +void ConfigSession::restorePromotedDomain( + const ConfigDomain& domain, + const std::string& oldContent, + bool existed) const { + if (existed) { + folly::writeFileAtomic( + domain.promotedPath, oldContent, 0644, folly::SyncType::WITH_SYNC); + } else { + std::error_code rmEc; + fs::remove(domain.promotedPath, rmEc); + } +} + +void ConfigSession::clearStagedDomain(const ConfigDomain& domain) { + std::error_code ec; + fs::remove(domain.sessionPath, ec); + if (ec) { + LOG(WARNING) << fmt::format( + "Failed to remove session config {}: {}", + domain.sessionPath, + ec.message()); + } + // Drop the in-memory cache (null == not loaded) so the next access re-seeds + // from the promoted config. + switch (domain.service) { + case cli::ServiceType::AGENT: + agentConfig_.reset(); + break; + case cli::ServiceType::BGP: + bgpConfig_.reset(); + break; + } +} + +bool ConfigSession::domainContentEqual( + const ConfigDomain& domain, + const std::string& a, + const std::string& b) const { + // Empty (missing) content cannot be parsed as a struct; compare bytes. Both + // empty -> equal; empty vs non-empty -> changed. + if (a.empty() || b.empty()) { + return a == b; + } + try { + switch (domain.service) { + case cli::ServiceType::AGENT: { + cfg::AgentConfig sa, sb; + apache::thrift::SimpleJSONSerializer::deserialize( + a, sa); + apache::thrift::SimpleJSONSerializer::deserialize( + b, sb); + return sa == sb; + } + case cli::ServiceType::BGP: { + bgp::thrift::BgpConfig sa, sb; + apache::thrift::SimpleJSONSerializer::deserialize< + bgp::thrift::BgpConfig>(a, sa); + apache::thrift::SimpleJSONSerializer::deserialize< + bgp::thrift::BgpConfig>(b, sb); + return sa == sb; + } + } + } catch (const std::exception& ex) { + // Malformed JSON on either side: fall back to a byte comparison rather than + // crashing the commit/rollback. Differing bytes are then treated as a + // change (the safe, conservative outcome). + LOG(WARNING) << "Semantic config comparison for " << domain.name + << " failed to parse; falling back to byte comparison: " + << ex.what(); + return a == b; + } + return a == b; // unreachable: switch above is exhaustive +} + bool ConfigSession::sessionExists() const { return fs::exists(getSessionConfigPath()); } @@ -397,34 +553,35 @@ bool ConfigSession::hasActiveSession() const { // An agent config session (agent.conf) OR a protocol session staged outside // agent.conf. BGP is the latter: a staged ~/.fboss2/bgp_config.json (written // by either the typed global config here or BgpConfigSession's peer edits) - // with a recorded BGP_RESTART action, but never touching agent.conf. + // with a recorded restart (AGENT_WARMBOOT) action, but never touching + // agent.conf. return sessionExists() || bgpSessionExists(); } cfg::AgentConfig& ConfigSession::getAgentConfig() { - if (!configLoaded_) { + if (!agentConfig_) { loadConfig(); } - return agentConfig_; + return *agentConfig_; } const cfg::AgentConfig& ConfigSession::getAgentConfig() const { - if (!configLoaded_) { + if (!agentConfig_) { throw std::runtime_error( "Config not loaded yet. Call getAgentConfig() (non-const) first."); } - return agentConfig_; + return *agentConfig_; } utils::PortMap& ConfigSession::getPortMap() { - if (!configLoaded_) { + if (!agentConfig_) { loadConfig(); } return *portMap_; } const utils::PortMap& ConfigSession::getPortMap() const { - if (!configLoaded_) { + if (!agentConfig_) { throw std::runtime_error( "Config not loaded yet. Call getPortMap() (non-const) first."); } @@ -432,59 +589,57 @@ const utils::PortMap& ConfigSession::getPortMap() const { } void ConfigSession::rebuildPortMap() { - if (!configLoaded_) { + if (!agentConfig_) { loadConfig(); } - portMap_ = std::make_unique(agentConfig_); + portMap_ = std::make_unique(*agentConfig_); } void ConfigSession::saveConfig( cli::ServiceType service, cli::ConfigActionLevel actionLevel) { - if (!configLoaded_) { - throw std::runtime_error("No config loaded to save"); + // Serialize whichever typed config this service owns and stage it to that + // domain's session file. The round-trip through serialize -> parse -> + // toPrettyJson is needed because SimpleJSONSerializer emits Thrift maps with + // integer keys (e.g. clientIdToAdminDistance) as string keys; going through + // facebook::thrift::to_dynamic() directly would keep integer keys and make + // folly::toPrettyJson() fail (JSON object keys must be strings). + std::string prettyJson; + std::string sessionPath; + switch (service) { + case cli::ServiceType::AGENT: { + if (!agentConfig_) { + throw std::runtime_error("No config loaded to save"); + } + auto json = apache::thrift::SimpleJSONSerializer::serialize( + *agentConfig_); + prettyJson = folly::toPrettyJson(folly::parseJson(json)); + sessionPath = getSessionConfigPath(); + break; + } + case cli::ServiceType::BGP: { + if (!bgpConfig_) { + loadBgpConfig(); + } + auto json = apache::thrift::SimpleJSONSerializer::serialize( + *bgpConfig_); + prettyJson = folly::toPrettyJson(folly::parseJson(json)); + sessionPath = getBgpSessionConfigPath(); + break; + } } - // We need to do a round-trip through serialize -> parse -> toPrettyJson - // because SimpleJSONSerializer handles Thrift maps with integer keys - // (like clientIdToAdminDistance) by converting them to strings. - // If we use facebook::thrift::to_dynamic() directly, the integer keys - // are preserved as integers in the folly::dynamic object, which causes - // folly::toPrettyJson() to fail because JSON objects requires string keys. - std::string json = - apache::thrift::SimpleJSONSerializer::serialize( - agentConfig_); - std::string prettyJson = folly::toPrettyJson(folly::parseJson(json)); - // Use folly::writeFileAtomic with sync to avoid race conditions when multiple // threads/processes write to the same session file. WITH_SYNC ensures data // is flushed to disk before the atomic rename, preventing readers from // seeing partial/corrupted data. folly::writeFileAtomic( - getSessionConfigPath(), prettyJson, 0644, folly::SyncType::WITH_SYNC); - - // Automatically record the command from /proc/self/cmdline. - // This ensures all config commands are tracked without requiring manual - // instrumentation in each command implementation. - // Note: When running CLI commands directly (e.g., in tests), - // /proc/self/cmdline may not contain the CLI command, so we gracefully skip - // command tracking. - std::string rawCmd = readCommandLineFromProc(); - // Only record if this is a config command and not already the last one - // recorded as that'd be idempotent anyway. Strip any leading flags. - auto pos = rawCmd.find("config "); - if (pos != std::string::npos) { - std::string cmd = rawCmd.substr(pos); - if (commands_.empty() || commands_.back() != cmd) { - commands_.push_back(cmd); - } - } - - // Update the required action metadata for this service - updateRequiredAction(service, actionLevel); + sessionPath, prettyJson, 0644, folly::SyncType::WITH_SYNC); - // Save command history and action levels to metadata - saveMetadata(); + // Record the command from /proc/self/cmdline and bump this service's required + // action level + metadata. Shared with recordServiceAction() so command + // tracking and action bookkeeping are identical for every service. + recordServiceAction(service, actionLevel); } void ConfigSession::saveConfig() { @@ -533,7 +688,7 @@ bool ConfigSession::bgpSessionExists() const { } void ConfigSession::loadBgpConfig() { - if (bgpConfigLoaded_) { + if (bgpConfig_) { return; } @@ -556,52 +711,40 @@ void ConfigSession::loadBgpConfig() { } } - bgpConfig_ = bgp::thrift::BgpConfig(); + bgpConfig_ = std::make_unique(); if (!content.empty()) { try { apache::thrift::SimpleJSONSerializer::deserialize( - content, bgpConfig_); + content, *bgpConfig_); } catch (const std::exception& ex) { LOG(WARNING) << "Failed to parse BGP config, starting from defaults: " << ex.what(); - bgpConfig_ = bgp::thrift::BgpConfig(); + *bgpConfig_ = bgp::thrift::BgpConfig(); } } - bgpConfigLoaded_ = true; } bgp::thrift::BgpConfig& ConfigSession::getBgpConfig() { - if (!bgpConfigLoaded_) { + if (!bgpConfig_) { loadBgpConfig(); } - return bgpConfig_; + return *bgpConfig_; } const bgp::thrift::BgpConfig& ConfigSession::getBgpConfig() const { - if (!bgpConfigLoaded_) { + if (!bgpConfig_) { throw std::runtime_error( "BGP config not loaded yet. Call getBgpConfig() (non-const) first."); } - return bgpConfig_; + return *bgpConfig_; } void ConfigSession::saveBgpConfig() { - if (!bgpConfigLoaded_) { - loadBgpConfig(); - } - - // Serialize the entire typed config (round-tripped through parse so integer - // map keys become string keys, mirroring saveConfig() for the agent). - auto json = - apache::thrift::SimpleJSONSerializer::serialize(bgpConfig_); - std::string prettyJson = folly::toPrettyJson(folly::parseJson(json)); - folly::writeFileAtomic( - getBgpSessionConfigPath(), prettyJson, 0644, folly::SyncType::WITH_SYNC); - - // Record the command (mirrors saveConfig) and that bgpd must be restarted - // for this change to take effect on a subsequent `config session commit`. - recordServiceAction( - cli::ServiceType::BGP, cli::ConfigActionLevel::BGP_RESTART); + // Convenience wrapper over the generic saveConfig(), mirroring the no-arg + // saveConfig() for the agent. bgpd has no hitless reload, so a staged BGP + // change always requires a bgpd restart (AGENT_WARMBOOT) on the next + // `config session commit`. + saveConfig(cli::ServiceType::BGP, cli::ConfigActionLevel::AGENT_WARMBOOT); } Git& ConfigSession::getGit() { @@ -763,7 +906,6 @@ ConfigSession::applyServiceActions( switch (level) { case cli::ConfigActionLevel::AGENT_COLDBOOT: case cli::ConfigActionLevel::AGENT_WARMBOOT: - case cli::ConfigActionLevel::BGP_RESTART: serviceNames[service] = fbossServiceUtil_->restartService(service, level); break; @@ -790,16 +932,16 @@ void ConfigSession::loadConfig() { fmt::format("Failed to read config file: {}", sessionConfigPath)); } + agentConfig_ = std::make_unique(); apache::thrift::SimpleJSONSerializer::deserialize( - configJson, agentConfig_); + configJson, *agentConfig_); // Handle the legacy case where config might be a bare SwitchConfig - if (*agentConfig_.sw() == cfg::SwitchConfig()) { + if (*agentConfig_->sw() == cfg::SwitchConfig()) { apache::thrift::SimpleJSONSerializer::deserialize( - configJson, *agentConfig_.sw()); + configJson, *agentConfig_->sw()); } - portMap_ = std::make_unique(agentConfig_); - configLoaded_ = true; + portMap_ = std::make_unique(*agentConfig_); } void ConfigSession::initializeSession() { @@ -807,15 +949,15 @@ void ConfigSession::initializeSession() { // Resume an existing session if EITHER an agent (agent.conf) or a BGP // (bgp_config.json) session is staged. Keying only on the agent session file // would misdetect a BGP-only session as fresh and clear its recorded - // BGP_RESTART action on the next (separate-process) CLI invocation, - // silently dropping the staged change at commit time. + // restart (AGENT_WARMBOOT) action on the next (separate-process) CLI + // invocation, silently dropping the staged change at commit time. if (!hasActiveSession()) { // Starting a new session - reset all state to ensure we don't carry over // stale data from a previous session (e.g., if the singleton persisted // in memory but the session files were deleted). commands_.clear(); requiredActions_.clear(); - configLoaded_ = false; + agentConfig_.reset(); // Ensure the session config directory exists ensureDirectoryExists(sessionConfigDir_); @@ -924,9 +1066,6 @@ void ConfigSession::copySystemConfigToSession() const { } ConfigSession::CommitResult ConfigSession::commit(const HostInfo& hostInfo) { - // A BGP-only session stages bgp_config.json but never agent.conf, so the - // agent-config file operations below are guarded on hasAgentSession. - const bool hasAgentSession = sessionExists(); if (!hasActiveSession()) { throw std::runtime_error( "No config session exists. Make a config change first."); @@ -951,205 +1090,106 @@ ConfigSession::CommitResult ConfigSession::commit(const HostInfo& hostInfo) { Git::shortSha1(currentHead))); } - std::string cliConfigDir = getCliConfigDir(); - std::string cliConfigPath = getCliConfigPath(); - std::string sessionConfigPath = getSessionConfigPath(); - std::string systemConfigPath = getSystemConfigPath(); + ensureDirectoryExists(getCliConfigDir()); - ensureDirectoryExists(cliConfigDir); - - // Read the staged agent config (only present for an agent config session; a - // BGP-only session never writes agent.conf). oldConfigData is read for - // rollback if needed. - std::string sessionConfigData; - std::string oldConfigData; - if (hasAgentSession) { - if (!folly::readFile(sessionConfigPath.c_str(), sessionConfigData)) { - throw std::runtime_error( - fmt::format( - "Failed to read session config from {}", sessionConfigPath)); - } - if (fs::exists(cliConfigPath)) { - if (!folly::readFile(cliConfigPath.c_str(), oldConfigData)) { - throw std::runtime_error( - fmt::format("Failed to read CLI config from {}", cliConfigPath)); - } - } - } - - // Capture the running BGP system config up front: it tells us whether the - // staged BGP config actually changed (so we can skip a needless bgpd - // restart) and is the snapshot we restore if the commit fails partway. - const std::string bgpSystemPath = getBgpSystemConfigPath(); - const bool bgpSystemConfigExisted = fs::exists(bgpSystemPath); - std::string bgpOldData; - if (bgpSystemConfigExisted) { - // Check the read: a silently-failed read would leave bgpOldData empty and - // make the restore-on-failure path below write an empty bgpcpp.conf, - // corrupting the running config (mirrors the guard in rollback()). - if (!folly::readFile(bgpSystemPath.c_str(), bgpOldData)) { - throw std::runtime_error( - fmt::format( - "Failed to read current BGP config from {}", bgpSystemPath)); + // Per-domain staged/changed analysis, applied uniformly to agent and BGP. + // A domain is "staged" when a session edit exists; it is "pending" (needs + // promotion + a service action) only when the staged content differs from + // what is already promoted. This skip-when-unchanged rule is the same for + // both domains, so re-committing an unchanged config is a true no-op: no git + // revision, no symlink churn, and no reloadConfig()/bgpd restart. + struct Pending { + ConfigDomain domain; + std::string staged; + std::string oldPromoted; + bool promotedExisted; + }; + std::vector stagedDomains; + std::vector pending; + // actions ends up holding exactly the pending domains' required action levels + // (returned in CommitResult and passed to applyServiceActions). + auto actions = requiredActions_; + for (const auto& domain : configDomains()) { + auto staged = readStagedContent(domain); + if (!staged) { + actions.erase(domain.service); // nothing staged for this domain + continue; } - } - - // saveBgpConfig() records BGP_RESTART unconditionally, so re-committing an - // unchanged BGP config would otherwise still bounce bgpd (a disruptive, - // traffic-affecting restart for no effective change). Treat BGP as changed - // only when the staged config differs from what is running. - bool bgpConfigChanged = false; - if (requiredActions_.count(cli::ServiceType::BGP) > 0 && bgpSessionExists()) { - std::string stagedBgpData; - if (!folly::readFile(getBgpSessionConfigPath().c_str(), stagedBgpData)) { - throw std::runtime_error( - fmt::format( - "Failed to read staged BGP config from {}", - getBgpSessionConfigPath())); + stagedDomains.push_back(domain); + std::string oldPromoted = readPromotedContent(domain); + if (domainContentEqual(domain, *staged, oldPromoted)) { + actions.erase(domain.service); // unchanged -> no promote, no action + continue; } - bgpConfigChanged = (stagedBgpData != bgpOldData); + pending.push_back( + {domain, + std::move(*staged), + std::move(oldPromoted), + fs::exists(domain.promotedPath)}); } - // Copy requiredActions_ before we reset it (returned in CommitResult) and - // drop BGP when the BGP config is unchanged, so an unchanged BGP commit - // neither promotes the config nor restarts bgpd. - auto actions = requiredActions_; - if (!bgpConfigChanged) { - actions.erase(cli::ServiceType::BGP); - } - - // Early return if there are no changes to commit. - const bool agentConfigChanged = - hasAgentSession && sessionConfigData != oldConfigData; - if (!agentConfigChanged && actions.empty()) { + // Nothing that is staged actually changed -> no-op. + if (pending.empty()) { return CommitResult{"", {}, {}}; } - // Write the metadata file alongside the config revision. - // This is required for rollback functionality. - // Use folly::writeFileAtomic instead of fs::copy_file so that we only write - // file content without calling fchmod() on the destination — fchmod fails - // with EPERM when the target is owned by a different user (e.g. root) even - // if the caller has group-write permission on the file. + // Write the metadata file alongside the config revision (required for + // rollback). Use folly::writeFileAtomic rather than fs::copy_file so we only + // write content without fchmod()ing a differently-owned destination (EPERM). + // Nothing has been promoted yet, so a failure here simply aborts. std::string metadataPath = getMetadataPath(); - std::string targetMetadataPath = - fmt::format("{}/cli_metadata.json", cliConfigDir); + std::string targetMetadataPath = getSystemMetadataPath(); std::string metadataContent; if (!folly::readFile(metadataPath.c_str(), metadataContent)) { LOG(WARNING) << "Failed to read session metadata from " << metadataPath << "; committing empty metadata"; metadataContent = "{}"; } - try { - folly::writeFileAtomic( - targetMetadataPath, metadataContent, 0664, folly::SyncType::WITH_SYNC); - } catch (const std::exception& e) { - if (!oldConfigData.empty()) { - folly::writeFileAtomic( - cliConfigPath, oldConfigData, 0644, folly::SyncType::WITH_SYNC); - } - throw std::runtime_error( - fmt::format( - "Failed to copy metadata to {}: {}", targetMetadataPath, e.what())); - } + folly::writeFileAtomic( + targetMetadataPath, metadataContent, 0664, folly::SyncType::WITH_SYNC); - // Files to include in the git commit. The metadata file is always part of a - // commit; agent.conf and its symlink are added only when an agent config - // session was staged. BGP config (if staged this session) is added below; it - // lives under /etc/coop/bgpcpp/ so it's versioned by this same /etc/coop - // repo. std::vector commitFiles = {targetMetadataPath}; - - if (hasAgentSession) { - // Atomically write the session config to the CLI config path - folly::writeFileAtomic( - cliConfigPath, sessionConfigData, 0644, folly::SyncType::WITH_SYNC); - - // Ensure the system config symlink points to the CLI config - atomicSymlinkUpdate(systemConfigPath, "cli/agent.conf"); - - commitFiles.push_back(cliConfigPath); - commitFiles.push_back(systemConfigPath); - } - - // Apply the config based on the required action level std::string commitSha; std::map> serviceNames; - // stagingBgp reflects the trimmed action set: false when the BGP config was - // unchanged, so we neither promote bgpcpp.conf nor restart bgpd below. The - // prior BGP config (bgpOldData / bgpSystemConfigExisted, captured above) is - // the snapshot restored if the commit fails partway. - const bool stagingBgp = actions.count(cli::ServiceType::BGP) > 0; - std::string bgpConfPath; - try { - // If this session staged BGP config changes, promote the staged - // bgp_config.json to /etc/coop/bgpcpp/bgpcpp.conf BEFORE bgpd is - // restarted below, so the restart picks up the new config. The promoted - // file is committed as part of this commit's git operation. The staged - // session file is left in place until the whole commit succeeds, so a - // failure here can be rolled back and retried. - if (stagingBgp && bgpSessionExists()) { - std::string staged; - if (!folly::readFile(getBgpSessionConfigPath().c_str(), staged)) { - throw std::runtime_error( - fmt::format( - "Failed to read staged BGP config from {}", - getBgpSessionConfigPath())); + // Promote every changed domain (staged -> git-tracked file + daemon + // symlink) BEFORE applying its service action, so the reload/restart picks + // up the new config. Session files are left in place until the whole commit + // succeeds, so a failure here can be rolled back and retried. + for (const auto& p : pending) { + promoteDomain(p.domain, p.staged, commitFiles); + } + // Track every other domain's running config in this commit too, so a later + // rollback has a snapshot to restore instead of wiping it (e.g. a + // bgpcpp.conf present on disk but not yet committed). git dedups unchanged + // content, so re-adding an already-tracked file is a no-op. + std::set pendingServices; + for (const auto& p : pending) { + pendingServices.insert(p.domain.service); + } + for (const auto& domain : configDomains()) { + if (pendingServices.count(domain.service) == 0 && + fs::exists(domain.promotedPath)) { + commitFiles.push_back(domain.promotedPath); } - ensureDirectoryExists(getBgpSystemConfigDir()); - folly::writeFileAtomic( - getBgpSystemConfigPath(), staged, 0644, folly::SyncType::WITH_SYNC); - bgpConfPath = getBgpSystemConfigPath(); - commitFiles.push_back(bgpConfPath); - // Keep the daemon-facing path (/etc/coop/bgpcpp.conf) a symlink into the - // CLI-managed bgpcpp/ subdir, mirroring agent.conf -> cli/agent.conf. - // bgpd reads its provisioned --config /etc/coop/bgpcpp.conf and follows - // the symlink, so no per-device systemd --config override is needed. The - // symlink is git-tracked alongside the config so a rollback restores it. - atomicSymlinkUpdate(getBgpSystemConfigLinkPath(), kBgpGitRelPath); - commitFiles.push_back(getBgpSystemConfigLinkPath()); - } else if (bgpSystemConfigExisted) { - // Agent-only commit: still track the running bgpd config so a later - // rollback has a snapshot to restore instead of wiping it. No restart — - // the file is already the running config. - commitFiles.push_back(bgpSystemPath); } serviceNames = applyServiceActions(actions, hostInfo); - // Create a Git commit with all changed files: - // - cli/agent.conf (the config file) - // - cli/cli_metadata.json (the metadata file) - // - agent.conf (the symlink, in case it was updated) - // - bgpcpp/bgpcpp.conf (the bgp config, if staged this session) std::string commitMessage = fmt::format("Config commit by {}", username_); commitSha = git_->commit(commitFiles, commitMessage, username_, ""); LOG(INFO) << "Config committed as " << Git::shortSha1(commitSha); } catch (const std::exception& ex) { - // Rollback: restore the old config, then re-apply actions - // on the old config so services pick up the previous configuration + // Restore each promoted domain to its prior state, then re-apply actions on + // the old config so services pick up the previous configuration. Staged + // session files are left intact so the user can retry. try { - if (!oldConfigData.empty()) { - folly::writeFileAtomic( - cliConfigPath, oldConfigData, 0644, folly::SyncType::WITH_SYNC); - } - // Restore the BGP system config to its pre-commit state. The staged - // session file is left intact, so the user can retry after the failure - // is resolved. - if (stagingBgp && !bgpConfPath.empty()) { - if (bgpSystemConfigExisted) { - folly::writeFileAtomic( - bgpConfPath, bgpOldData, 0644, folly::SyncType::WITH_SYNC); - } else { - std::error_code rmEc; - fs::remove(bgpConfPath, rmEc); - } + for (const auto& p : pending) { + restorePromotedDomain(p.domain, p.oldPromoted, p.promotedExisted); } applyServiceActions(actions, hostInfo); } catch (const std::exception& rollbackEx) { - // If rollback also fails, include both errors in the message throw std::runtime_error( fmt::format( "Failed to apply config: {}. Additionally, failed to rollback the config: {}", @@ -1162,35 +1202,17 @@ ConfigSession::CommitResult ConfigSession::commit(const HostInfo& hostInfo) { ex.what())); } - // Now that the commit has fully succeeded, clear the staged BGP session file - // (it was deliberately left in place for rollback). Force a re-seed from the - // newly promoted system config on next access. - if (stagingBgp) { - std::error_code rmEc; - fs::remove(getBgpSessionConfigPath(), rmEc); - bgpConfigLoaded_ = false; - } - - // Only remove the agent session config after everything succeeded. - if (hasAgentSession) { - std::error_code ec; - fs::remove(sessionConfigPath, ec); - if (ec) { - // Log warning but don't fail - the commit succeeded - LOG(WARNING) << fmt::format( - "Failed to remove session config {}: {}", - sessionConfigPath, - ec.message()); - } - } - - // Reset action level for all services after successful commit - for (const auto& [service, level] : actions) { - resetRequiredAction(service); + // The commit fully succeeded: the session is consumed, so clear every staged + // domain's session file and reset its recorded action level. + for (const auto& domain : stagedDomains) { + clearStagedDomain(domain); + resetRequiredAction(domain.service); } base_ = commitSha; - // Force config reload from system config on next access - configLoaded_ = false; + // Force a reload from the promoted config on next access (null == not + // loaded). + agentConfig_.reset(); + bgpConfig_.reset(); return CommitResult{commitSha, actions, serviceNames}; } @@ -1278,12 +1300,13 @@ void ConfigSession::rebase() { base_ = currentHead; saveMetadata(); - // Reload in-memory state for whichever domains were rebased. + // Reload in-memory state for whichever domains were rebased (null == reload + // on next access). if (agentMerged) { loadConfig(); } if (bgpMerged) { - bgpConfigLoaded_ = false; + bgpConfig_.reset(); } } @@ -1306,36 +1329,16 @@ std::string ConfigSession::rollback(const HostInfo& hostInfo) { std::string ConfigSession::rollback( const HostInfo& hostInfo, const std::string& commitSha) { - std::string cliConfigDir = getCliConfigDir(); - std::string cliConfigPath = getCliConfigPath(); - std::string systemConfigPath = getSystemConfigPath(); - - ensureDirectoryExists(cliConfigDir); + ensureDirectoryExists(getCliConfigDir()); // Resolve the commit SHA (in case it's a short SHA or ref) std::string resolvedSha = git_->resolveRef(commitSha); - // Get the config and metadata content from the target commit - // The paths in git are relative to the repo root - std::string targetConfigData = - git_->fileAtRevision(resolvedSha, "cli/agent.conf"); + // Read the target metadata; this is present in every commit, so it also + // validates the revision (a bad ref throws here and propagates). + std::string metadataPath = getSystemMetadataPath(); std::string targetMetadataData = git_->fileAtRevision(resolvedSha, "cli/cli_metadata.json"); - std::string metadataPath = fmt::format("{}/cli_metadata.json", cliConfigDir); - - // Target BGP config at that revision ("" if the commit predates BGP config). - std::string bgpSystemPath = getBgpSystemConfigPath(); - std::string targetBgpData = - fileAtRevisionOrEmpty(resolvedSha, kBgpGitRelPath); - - // Read the current config for rollback if needed - std::string oldConfigData; - if (fs::exists(cliConfigPath)) { - if (!folly::readFile(cliConfigPath.c_str(), oldConfigData)) { - throw std::runtime_error( - fmt::format("Failed to read current config from {}", cliConfigPath)); - } - } std::string oldMetadataData; if (fs::exists(metadataPath)) { if (!folly::readFile(metadataPath.c_str(), oldMetadataData)) { @@ -1343,51 +1346,51 @@ std::string ConfigSession::rollback( fmt::format("Failed to read current metadata from {}", metadataPath)); } } - std::string oldBgpData; - const bool bgpSystemExisted = fs::exists(bgpSystemPath); - if (bgpSystemExisted) { - if (!folly::readFile(bgpSystemPath.c_str(), oldBgpData)) { - // Don't proceed: a failed read here would make the restore-on-failure - // path below write an empty bgpcpp.conf, corrupting the running config. - throw std::runtime_error( - fmt::format( - "Failed to read current BGP config from {}", bgpSystemPath)); - } - } - - // Only act on a service whose config actually changes in this rollback. A - // BGP-only commit leaves cli/agent.conf identical, and vice versa. - const bool agentChanged = targetConfigData != oldConfigData; - const bool bgpChanged = targetBgpData != oldBgpData; - // Always restore the metadata (it records the new rollback base). Only - // rewrite the agent config + symlink when it actually changed, to avoid - // needless writes and symlink churn on a BGP-only rollback. + // Per-domain: target content at the revision vs the currently-promoted + // content. A rollback only acts on a domain whose config actually changes + // (a BGP-only commit leaves cli/agent.conf identical, and vice versa). + struct DomainRollback { + ConfigDomain domain; + std::string target; + std::string oldPromoted; + bool promotedExisted; + bool changed; + }; + std::vector doms; + for (const auto& domain : configDomains()) { + // fileAtRevisionOrEmpty: a path absent at the revision (e.g. bgpcpp.conf + // before BGP existed) is treated as empty content -> remove on rollback. + std::string target = fileAtRevisionOrEmpty(resolvedSha, domain.gitRelPath); + std::string oldPromoted = readPromotedContent(domain); + bool existed = fs::exists(domain.promotedPath); + bool changed = !domainContentEqual(domain, target, oldPromoted); + doms.push_back( + {domain, std::move(target), std::move(oldPromoted), existed, changed}); + } + + // Always restore the metadata (it records the new rollback base). Promote + // each changed domain to its target (or remove its file if the domain didn't + // exist at that revision), leaving unchanged domains untouched to avoid + // needless writes and symlink churn. folly::writeFileAtomic( metadataPath, targetMetadataData, 0644, folly::SyncType::WITH_SYNC); - if (agentChanged) { - folly::writeFileAtomic( - cliConfigPath, targetConfigData, 0644, folly::SyncType::WITH_SYNC); - atomicSymlinkUpdate(systemConfigPath, "cli/agent.conf"); - } - - // Promote the target BGP config (if it changed) so bgpd picks it up when - // restarted below. An empty target means BGP didn't exist at that revision, - // so remove the running config file. - if (bgpChanged) { - if (!targetBgpData.empty()) { - ensureDirectoryExists(getBgpSystemConfigDir()); - folly::writeFileAtomic( - bgpSystemPath, targetBgpData, 0644, folly::SyncType::WITH_SYNC); - } else if (bgpSystemExisted) { + std::vector rollbackFiles = {metadataPath}; + for (const auto& dr : doms) { + if (!dr.changed) { + continue; + } + if (!dr.target.empty()) { + promoteDomain(dr.domain, dr.target, rollbackFiles); + } else if (dr.promotedExisted) { std::error_code rmEc; - fs::remove(bgpSystemPath, rmEc); + fs::remove(dr.domain.promotedPath, rmEc); if (rmEc) { throw std::runtime_error( fmt::format( - "Failed to remove BGP config {} while rolling back to a " - "pre-BGP revision: {}", - bgpSystemPath, + "Failed to remove {} while rolling back to a revision that " + "predates it: {}", + dr.domain.promotedPath, rmEc.message())); } } @@ -1396,53 +1399,31 @@ std::string ConfigSession::rollback( // Apply the rolled-back config - if this fails, restore prior state. std::string newCommitSha; try { - // Reload the agent only if its config changed. - if (agentChanged) { - auto client = utils::createClient< - apache::thrift::Client>(hostInfo); - client->sync_reloadConfig(); - } - // Restart bgpd only if its config changed. - if (bgpChanged) { - ensureFbossServiceUtil(hostInfo); - fbossServiceUtil_->restartService( - cli::ServiceType::BGP, cli::ConfigActionLevel::BGP_RESTART); + // Reload/restart only the services whose config changed, each at its + // domain's rollback action level (agent -> HITLESS reload, bgpd -> + // restart). + std::map actions; + for (const auto& dr : doms) { + if (dr.changed) { + actions[dr.domain.service] = dr.domain.rollbackActionLevel; + } } + applyServiceActions(actions, hostInfo); - // Create a Git commit for the rollback. Metadata always changes; the agent - // config + symlink are included only when they were actually rewritten - // above (a BGP-only rollback leaves them untouched, so committing them - // could capture unrelated on-disk drift into the rollback commit). - std::vector rollbackFiles = {metadataPath}; - if (agentChanged) { - rollbackFiles.push_back(cliConfigPath); - rollbackFiles.push_back(systemConfigPath); - } - if (bgpChanged && !targetBgpData.empty()) { - rollbackFiles.push_back(bgpSystemPath); - } std::string commitMessage = fmt::format( "Rollback to {} by {}", Git::shortSha1(resolvedSha), username_); newCommitSha = git_->commit(rollbackFiles, commitMessage, username_, ""); LOG(INFO) << "Rollback committed as " << Git::shortSha1(newCommitSha); } catch (const std::exception& ex) { - // Rollback: restore the old config, metadata, and BGP config. + // Restore the old metadata and each changed domain's config. try { - if (!oldConfigData.empty()) { - folly::writeFileAtomic( - cliConfigPath, oldConfigData, 0644, folly::SyncType::WITH_SYNC); - } if (!oldMetadataData.empty()) { folly::writeFileAtomic( metadataPath, oldMetadataData, 0644, folly::SyncType::WITH_SYNC); } - if (bgpChanged) { - if (bgpSystemExisted) { - folly::writeFileAtomic( - bgpSystemPath, oldBgpData, 0644, folly::SyncType::WITH_SYNC); - } else { - std::error_code rmEc; - fs::remove(bgpSystemPath, rmEc); + for (const auto& dr : doms) { + if (dr.changed) { + restorePromotedDomain(dr.domain, dr.oldPromoted, dr.promotedExisted); } } } catch (const std::exception& rollbackEx) { @@ -1460,9 +1441,10 @@ std::string ConfigSession::rollback( } // The on-disk config changed underneath any cached in-memory state; force a - // reload on next access regardless of whether the session is clean. - configLoaded_ = false; - bgpConfigLoaded_ = false; + // reload on next access (null == not loaded) regardless of session + // cleanliness. + agentConfig_.reset(); + bgpConfig_.reset(); // Update the session state after rollback // Check if the current session is clean (no pending changes) @@ -1475,23 +1457,16 @@ std::string ConfigSession::rollback( // from its own rolled-back data. Unconditionally writing the agent session // file would materialize a phantom agent session after a BGP-only rollback // (and leave the BGP session file stale); keep the two domains symmetric. - if (sessionExists()) { - folly::writeFileAtomic( - getSessionConfigPath(), - targetConfigData, - 0644, - folly::SyncType::WITH_SYNC); - } - if (bgpSessionExists()) { - if (!targetBgpData.empty()) { + for (const auto& dr : doms) { + if (!fs::exists(dr.domain.sessionPath)) { + continue; + } + if (!dr.target.empty()) { folly::writeFileAtomic( - getBgpSessionConfigPath(), - targetBgpData, - 0644, - folly::SyncType::WITH_SYNC); + dr.domain.sessionPath, dr.target, 0644, folly::SyncType::WITH_SYNC); } else { std::error_code rmEc; - fs::remove(getBgpSessionConfigPath(), rmEc); + fs::remove(dr.domain.sessionPath, rmEc); } } diff --git a/fboss/cli/fboss2/session/ConfigSession.h b/fboss/cli/fboss2/session/ConfigSession.h index 8283f67ce824c..0d36a5b34ec8e 100644 --- a/fboss/cli/fboss2/session/ConfigSession.h +++ b/fboss/cli/fboss2/session/ConfigSession.h @@ -9,12 +9,16 @@ #pragma once +// Forward-declaration-only headers for the typed configs; the full generated +// types are heavy and are only needed in ConfigSession.cpp (agentConfig_ and +// bgpConfig_ are held by unique_ptr, so an incomplete type suffices here). +#include #include #include +#include #include #include -#include "configerator/structs/neteng/fboss/bgp/gen-cpp2/bgp_config_types.h" -#include "fboss/agent/gen-cpp2/agent_config_types.h" +#include "fboss/agent/gen-cpp2/agent_config_types_fwd.h" #include "fboss/cli/fboss2/gen-cpp2/cli_metadata_types.h" #include "fboss/cli/fboss2/session/FbossServiceUtil.h" #include "fboss/cli/fboss2/session/Git.h" @@ -86,7 +90,8 @@ namespace facebook::fboss { class ConfigSession { public: ConfigSession(); - virtual ~ConfigSession() = default; + + virtual ~ConfigSession(); // Get or create the current config session // If no session exists, copies /etc/coop/agent.conf to ~/.fboss2/agent.conf @@ -107,6 +112,13 @@ class ConfigSession { // clear` without instantiating a session). static std::string getBgpSessionConfigPathStatic(); + // All per-session staged files under ~/.fboss2 that `config session clear` + // should remove: every config domain's staged file plus the session + // metadata. Static so callers can clear a session without getInstance() + // (which would create one). A new config domain adds one entry here rather + // than a new block in the clear command. + static std::vector stagedSessionFilePaths(); + // Get the path to the session config file (~/.fboss2/agent.conf) std::string getSessionConfigPath() const; @@ -130,6 +142,38 @@ class ConfigSession { std::map> serviceNames; }; + // Describes one config "domain" managed by a session. The agent config and + // the BGP config are two such domains: both are staged in ~/.fboss2, promoted + // to a git-tracked file under /etc/coop, exposed to their daemon via a stable + // symlink, and applied via a service action. commit(), rollback() and `config + // session diff` iterate configDomains() so the two are handled uniformly; the + // per-domain differences (paths, service, how a rollback applies) live here + // rather than as branches in each routine. + struct ConfigDomain { + cli::ServiceType service; // AGENT / BGP -- feeds applyServiceActions() + std::string name; // "Agent" / "BGP" (diff section headers, logs) + std::string sessionPath; // staged edits (~/.fboss2/...) + std::string gitRelPath; // path within the /etc/coop git repo + std::string promotedPath; // absolute git-tracked file that is written + std::string systemPath; // live file to read for diff (agent: the symlink) + std::string symlinkPath; // daemon-facing stable path (a symlink) + std::string symlinkTarget; // relative target of symlinkPath + // Action used when a rollback changes this domain (no recorded action is + // available then): HITLESS reloads the agent; AGENT_WARMBOOT restarts bgpd. + cli::ConfigActionLevel rollbackActionLevel; + }; + + // The config domains this session manages (agent + BGP), in a stable order + // (agent first). Public so `config session diff` can share the same list. + std::vector configDomains() const; + + // Staged content for a domain, or nullopt if no session edit is staged. + // Throws if the session file exists but cannot be read. Public so `config + // session diff` shares the same "is it staged + its content" primitive that + // commit()/rollback() use. + std::optional readStagedContent( + const ConfigDomain& domain) const; + // Atomically commit the session to /etc/coop/cli/agent.conf and create a git // commit. For HITLESS changes, also calls reloadConfig() on the agent. // For AGENT_RESTART changes, restarts the agent via systemd. @@ -172,10 +216,10 @@ class ConfigSession { // subsequent getPortMap() lookups reflect the change. void rebuildPortMap(); - // Save the configuration back to the session file. - // Also updates the required action level for the specified service - // (if the new level is higher than the current one). - // This combines saving the config and updating its associated metadata. + // Serialize the given service's typed config (AGENT -> agentConfig_, + // BGP -> bgpConfig_) to that domain's staged session file, and record the + // command + bump the service's required action level (if the new level is + // higher than the current one). One generic entry point for every service. void saveConfig(cli::ServiceType service, cli::ConfigActionLevel actionLevel); // Save the configuration for AGENT service with HITLESS action level. void saveConfig(); @@ -205,9 +249,10 @@ class ConfigSession { bgp::thrift::BgpConfig& getBgpConfig(); const bgp::thrift::BgpConfig& getBgpConfig() const; - // Persist the typed BGP config back to ~/.fboss2/bgp_config.json and record - // that bgpd must be restarted for this change to take effect on a - // subsequent `config session commit`. Mirrors saveConfig() for the agent. + // Convenience wrapper over saveConfig(BGP, AGENT_WARMBOOT): persists the + // typed BGP config to ~/.fboss2/bgp_config.json and records that bgpd must be + // restarted on the next `config session commit`. Mirrors the no-arg + // saveConfig() for the agent. void saveBgpConfig(); // ~/.fboss2/bgp_config.json (staged BGP edits) @@ -282,15 +327,15 @@ class ConfigSession { // Git instance for version control operations std::unique_ptr git_; - // Lazy-initialized configuration and port map - cfg::AgentConfig agentConfig_; + // Lazy-initialized configuration and port map. agentConfig_ is null until + // loadConfig() populates it (null == "not loaded"), which is why it is a + // pointer -- that also keeps the heavy generated type out of this header. + std::unique_ptr agentConfig_; std::unique_ptr portMap_; - bool configLoaded_ = false; - // Typed view of the entire BGP config (lazily loaded), mirroring - // agentConfig_. - bgp::thrift::BgpConfig bgpConfig_; - bool bgpConfigLoaded_ = false; + // Typed view of the entire BGP config, mirroring agentConfig_: null until + // loadBgpConfig() populates it. + std::unique_ptr bgpConfig_; // /etc/coop/bgpcpp (directory holding the bgpd daemon's config) std::string getBgpSystemConfigDir() const; @@ -303,8 +348,46 @@ class ConfigSession { // defaults). Mirrors loadConfig() for the agent. void loadBgpConfig(); + // ==================== Per-domain primitives ==================== + // Shared building blocks used by commit()/rollback() so both the agent and + // BGP domains go through identical logic (see ConfigDomain / + // configDomains()). readStagedContent() is declared public above. + + // Currently-promoted (git-tracked) content, or "" if the file does not exist. + // Throws if the file exists but cannot be read (so a silent read failure + // never masquerades as "no config", which a later restore would write back + // empty). + std::string readPromotedContent(const ConfigDomain& domain) const; + // Promote staged content to the domain's git-tracked file and refresh its + // daemon-facing symlink, appending both to commitFiles for the git commit. + void promoteDomain( + const ConfigDomain& domain, + const std::string& content, + std::vector& commitFiles) const; + // Restore a domain's promoted file to prior content (or remove it if it did + // not previously exist). Used by the commit/rollback failure paths. + void restorePromotedDomain( + const ConfigDomain& domain, + const std::string& oldContent, + bool existed) const; + // Remove a domain's staged session file and drop its in-memory cache so the + // next access re-seeds from disk. Called after a successful commit. + void clearStagedDomain(const ConfigDomain& domain); + // Compare two serialized configs for a domain by deserializing each into its + // typed thrift struct (cfg::AgentConfig / bgp::thrift::BgpConfig) and using + // struct equality. This is a SEMANTIC comparison, so formatting-only + // differences (whitespace, key ordering, integer-vs-string map keys, a + // raw-seeded file vs a round-tripped one) do not count as a change. Falls + // back to a byte comparison when either side is empty or fails to parse. + bool domainContentEqual( + const ConfigDomain& domain, + const std::string& a, + const std::string& b) const; + // git relative path of the bgpd config tracked in the /etc/coop repo. static constexpr auto kBgpGitRelPath = "bgpcpp/bgpcpp.conf"; + // git relative path of the agent config tracked in the /etc/coop repo. + static constexpr auto kAgentGitRelPath = "cli/agent.conf"; // Like Git::fileAtRevision but returns "" instead of throwing when the path // does not exist at that revision (e.g. a pre-BGP commit). Used by // rebase/rollback/diff so a missing bgpcpp.conf is treated as empty. diff --git a/fboss/cli/fboss2/session/FbossServiceUtil.cpp b/fboss/cli/fboss2/session/FbossServiceUtil.cpp index 060d1a886bde4..c178555e0ece9 100644 --- a/fboss/cli/fboss2/session/FbossServiceUtil.cpp +++ b/fboss/cli/fboss2/session/FbossServiceUtil.cpp @@ -159,7 +159,7 @@ std::vector FbossServiceUtil::reloadConfig( } case cli::ServiceType::BGP: // bgpd has no hitless reloadConfig() RPC; config changes are applied by - // restarting the service (BGP_RESTART), so this path is never taken. + // restarting the service (AGENT_WARMBOOT), so this path is never taken. throw std::runtime_error( "bgpd does not support config reload; it must be restarted"); } @@ -177,9 +177,6 @@ std::vector FbossServiceUtil::restartService( case cli::ConfigActionLevel::AGENT_WARMBOOT: restartType = "warmboot"; break; - case cli::ConfigActionLevel::BGP_RESTART: - restartType = "restart"; - break; case cli::ConfigActionLevel::HITLESS: // Not expected: HITLESS is applied via reloadConfig(), not restart. restartType = "reload"; diff --git a/fboss/cli/fboss2/test/BUILD.bazel b/fboss/cli/fboss2/test/BUILD.bazel new file mode 100644 index 0000000000000..8224f81ea87bb --- /dev/null +++ b/fboss/cli/fboss2/test/BUILD.bazel @@ -0,0 +1,255 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/test/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") + +cc_test( + name = "framework_test", + srcs = [ + "AggregationParsingTest.cpp", + "CmdArgsTest.cpp", + "CmdSubCommandsTest.cpp", + "CmdBgpTestUtils.h", + "CmdHandlerTestBase.h", + "CmdShowConfigTestUtils.h", + "MockClients.h", + "TestableConfigSession.h", + ], + deps = [ + "//fboss/cli/fboss2:cli", + "//fboss/cli/fboss2:cli-parser-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:cmd-list-header", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:fboss2-lib", + "//fboss/cli/fboss2:ops-utils", + ":cmd_test_utils", + "@CLI11//:CLI11", + "@fbthrift//:fbthrift", + "@googletest//:googletest", + "//fboss/util/oss:test_main", + ], + visibility = ["//visibility:public"], +) + +cc_test( + name = "cmd_test", + srcs = [ + "CanonicalRibResolverTest.cpp", + "CmdConfigSessionClearTest.cpp", + "CmdGetPcapTest.cpp", + "CmdListConfigTest.cpp", + "CmdSetPortStateTest.cpp", + "CmdShowAclTest.cpp", + "CmdShowAgentBootTypeTest.cpp", + "CmdShowAgentSslTest.cpp", + "CmdShowAggregatePortTest.cpp", + "CmdShowArpTest.cpp", + "CmdShowBgpChangelistTest.cpp", + "CmdShowBgpNeighborsAdvertisedPostPolicyTest.cpp", + "CmdShowBgpNeighborsAdvertisedPrePolicyTest.cpp", + "CmdShowBgpNeighborsAdvertisedRejectedTest.cpp", + "CmdShowBgpNeighborsReceivedPostPolicyTest.cpp", + "CmdShowBgpNeighborsReceivedPrePolicyTest.cpp", + "CmdShowBgpNeighborsReceivedRejectedTest.cpp", + "CmdShowBgpNeighborsTest.cpp", + "CmdShowBgpOriginatedRoutesTest.cpp", + "CmdShowBgpShadowRibTest.cpp", + "CmdShowBgpStatsAttrsTest.cpp", + "CmdShowBgpStatsEntriesTest.cpp", + "CmdShowBgpStatsPolicyTest.cpp", + "CmdShowBgpStreamSubscriberTest.cpp", + "CmdShowBgpStreamSummaryTest.cpp", + "CmdShowBgpSummaryEgressTest.cpp", + "CmdShowBgpSummaryTest.cpp", + "CmdShowBgpTableCommunityTest.cpp", + "CmdShowBgpTableDetailTest.cpp", + "CmdShowBgpTableMoreSpecificsTest.cpp", + "CmdShowBgpTablePrefixTest.cpp", + "CmdShowBgpTableSummaryTest.cpp", + "CmdShowBgpTableTest.cpp", + "CmdShowConfigRunningTest.cpp", + "CmdShowCpuPortTest.cpp", + "CmdShowEnvironmentFanTest.cpp", + "CmdShowExampleTest.cpp", + "CmdShowFlowletTest.cpp", + "CmdShowFsdbTest.cpp", + "CmdShowHostTest.cpp", + "CmdShowHwAgentStatusTest.cpp", + "CmdShowHwObjectTest.cpp", + "CmdShowInterfaceCountersFecHistogramTest.cpp", + "CmdShowInterfaceCountersTest.cpp", + "CmdShowInterfaceErrorsTest.cpp", + "CmdShowInterfaceStatusTest.cpp", + "CmdShowInterfaceTest.cpp", + "CmdShowInterfaceTrafficTest.cpp", + "CmdShowL2Test.cpp", + "CmdShowLldpTest.cpp", + "CmdShowMirrorTest.cpp", + "CmdShowNdpTest.cpp", + "CmdShowPortTest.cpp", + "CmdShowProductDetailsTest.cpp", + "CmdShowProductTest.cpp", + "CmdShowRouteDetailsTest.cpp", + "CmdShowRouteSummaryTest.cpp", + "CmdShowSystemPortTest.cpp", + "CmdShowTeFlowTest.cpp", + "CmdStartPcapTest.cpp", + "CmdStartPortCableLengthMeasurementTest.cpp", + "CmdStopPcapTest.cpp", + "GitTest.cpp", + "InterfaceListTest.cpp", + "PortMapTest.cpp", + "CmdBgpTestUtils.h", + "CmdHandlerTestBase.h", + "CmdShowConfigTestUtils.h", + "MockClients.h", + "TestableConfigSession.h", + ], + deps = [ + "//common/network/if:if", + "//fboss/agent/if:common", + "//fboss/agent/if:ctrl", + "//fboss/agent:address_utils", + "//fboss/cli/fboss2/commands/show/acl:model", + "//fboss/cli/fboss2/commands/show/agent:model", + "//fboss/cli/fboss2/commands/show/aggregateport:model", + "//fboss/cli/fboss2/commands/show/arp:model", + "//fboss/cli/fboss2/commands/show/bgp/summary:bgp_summary", + "//fboss/cli/fboss2/commands/show/cpuport:model", + "//fboss/cli/fboss2/commands/show/example:model", + "//fboss/cli/fboss2/commands/show/flowlet:model", + "//fboss/cli/fboss2/commands/show/hardware:model", + "//fboss/cli/fboss2/commands/show/host:model", + "//fboss/cli/fboss2/commands/show/hwagent:model", + "//fboss/cli/fboss2/commands/show/interface/counters/fec/histogram:model", + "//fboss/cli/fboss2/commands/show/interface/counters:model", + "//fboss/cli/fboss2/commands/show/interface/errors:model", + "//fboss/cli/fboss2/commands/show/interface/flaps:model", + "//fboss/cli/fboss2/commands/show/interface/status:model", + "//fboss/cli/fboss2/commands/show/interface/traffic:model", + "//fboss/cli/fboss2/commands/show/interface:model", + "//fboss/cli/fboss2/commands/show/lldp:model", + "//fboss/cli/fboss2/commands/show/mirror:model", + "//fboss/cli/fboss2/commands/show/ndp:model", + "//fboss/cli/fboss2/commands/show/port:model", + "//fboss/cli/fboss2/commands/show/product:model", + "//fboss/cli/fboss2/commands/show/route:model", + "//fboss/cli/fboss2/commands/show/systemport:model", + "//fboss/cli/fboss2/commands/show/teflow:model", + "//fboss/cli/fboss2/commands/show/transceiver:model", + "//fboss/cli/fboss2:cmd-list-header", + "//fboss/cli/fboss2:cmd-local-options", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:fboss2-config-lib", + "//fboss/cli/fboss2:fboss2-lib", + "//fboss/platform/fan_service/if:fan_service", + "//neteng/fboss/bgp/if:bgp_thrift", + ":bgp_test_utils", + ":cmd_test_utils", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@googletest//:googletest", + "//fboss/util/oss:test_main", + ], + data = ["//fboss/oss/link_test_configs:link_test_configs"], + visibility = ["//visibility:public"], +) + +cc_binary( + name = "thrift_latency_test", + srcs = ["thrift_latency_test.cpp"], + deps = [ + "//fboss/agent/if:ctrl", + "//fboss/lib:thrift_service_utils", + "//fboss/lib:thrift_service_utils_oss", + "@fbthrift//:fbthrift", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "cmd_test_utils", + hdrs = [ + "CmdHandlerTestBase.h", + "MockClients.h", + "TestableConfigSession.h", + "CmdBgpTestUtils.h", + "CmdShowConfigTestUtils.h", + ], + deps = [ + "//fboss/agent/if:ctrl", + "//fboss/agent/if:hw_ctrl", + "//fboss/agent:switch_state", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-global-options", + "//fboss/cli/fboss2:commands-show-bgp", + "//fboss/cli/fboss2:fboss2-config-lib", + "//fboss/cli/fboss2:fboss2-lib", + "//fboss/cli/fboss2:options", + "//fboss/fsdb/if:fsdb", + "//fboss/lib:thrift_service_utils", + "//fboss/qsfp_service/if:qsfp", + "//fboss/qsfp_service/if:transceiver", + "//neteng/fboss/bgp/if:bgp_thrift", + ":bgp_mock_client", + "@fbthrift//:fbthrift", + "@folly//:folly", + "@googletest//:googletest", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "bgp_test_utils", + srcs = ["CmdBgpTestUtils.cpp"], + hdrs = [ + "CmdBgpTestUtils.h", + "CmdHandlerTestBase.h", + "CmdShowConfigTestUtils.h", + "MockClients.h", + "TestableConfigSession.h", + ], + deps = [ + "//fboss/agent:address_utils", + "//neteng/fboss/bgp/if:bgp_thrift", + "@boost//:boost", + "@folly//:folly", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "bgp_mock_client", + hdrs = [ + "bgp/MockBgpClient.h", + "CmdBgpTestUtils.h", + "CmdHandlerTestBase.h", + "CmdShowConfigTestUtils.h", + "MockClients.h", + "TestableConfigSession.h", + ], + deps = [ + "//neteng/fboss/bgp/if:bgp_thrift", + "@googletest//:googletest", + ], + visibility = ["//visibility:public"], +) + +cc_library( + name = "config_test_utils", + srcs = ["CmdShowConfigTestUtils.cpp"], + hdrs = [ + "CmdShowConfigTestUtils.h", + "CmdBgpTestUtils.h", + "CmdHandlerTestBase.h", + "MockClients.h", + "TestableConfigSession.h", + ], + deps = ["@folly//:folly"], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/test/config/BUCK b/fboss/cli/fboss2/test/config/BUCK index 8b1cdf4944511..79086977b929e 100644 --- a/fboss/cli/fboss2/test/config/BUCK +++ b/fboss/cli/fboss2/test/config/BUCK @@ -11,6 +11,12 @@ cpp_unittest( "CmdConfigAdminDistanceTest.cpp", "CmdConfigAppliedInfoTest.cpp", "CmdConfigArpTest.cpp", + "CmdConfigBgpNeighborTest.cpp", + "CmdConfigBgpPeerGroupTest.cpp", + "CmdConfigBgpPolicyAsPathListEntryTest.cpp", + "CmdConfigBgpPolicyAsPathListTest.cpp", + "CmdConfigBgpPolicyCommunityListCommunityTest.cpp", + "CmdConfigBgpPolicyCommunityListTest.cpp", "CmdConfigCoppTest.cpp", "CmdConfigDhcpTest.cpp", "CmdConfigHistoryTest.cpp", @@ -40,6 +46,7 @@ cpp_unittest( "CmdConfigVlanStaticMacTest.cpp", "CmdDeleteAclRuleTest.cpp", "CmdDeleteArpTest.cpp", + "CmdDeleteBgpNeighborTest.cpp", "CmdDeleteConfigInterfaceTest.cpp", "CmdDeleteDhcpTest.cpp", "CmdDeleteInterfaceIpv6NdpTest.cpp", @@ -49,6 +56,9 @@ cpp_unittest( "CmdDeleteTunnelIpInIpTest.cpp", "CmdDeleteVlanTest.cpp", "ConfigSessionSystemdTest.cpp", + "CmdDeleteBgpPeerGroupTest.cpp", + "CmdDeleteBgpPolicyAsPathListTest.cpp", + "CmdDeleteBgpPolicyCommunityListTest.cpp", "ProfileValidationTest.cpp", ], headers = [ diff --git a/fboss/cli/fboss2/test/config/BUILD.bazel b/fboss/cli/fboss2/test/config/BUILD.bazel new file mode 100644 index 0000000000000..ed9de0e52a50d --- /dev/null +++ b/fboss/cli/fboss2/test/config/BUILD.bazel @@ -0,0 +1,90 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/test/config/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_test") + +cc_test( + name = "cmd_config_test", + srcs = [ + "CmdConfigAclRuleTest.cpp", + "CmdConfigAdminDistanceTest.cpp", + "CmdConfigAppliedInfoTest.cpp", + "CmdConfigArpTest.cpp", + "CmdConfigBgpNeighborTest.cpp", + "CmdConfigBgpPeerGroupTest.cpp", + "CmdConfigBgpPolicyAsPathListEntryTest.cpp", + "CmdConfigBgpPolicyAsPathListTest.cpp", + "CmdConfigBgpPolicyCommunityListCommunityTest.cpp", + "CmdConfigBgpPolicyCommunityListTest.cpp", + "CmdConfigBgpPolicyPrefixListEntryTest.cpp", + "CmdConfigBgpPolicyPrefixListTest.cpp", + "CmdConfigBgpPolicyRoutingPolicyTest.cpp", + "CmdConfigCoppTest.cpp", + "CmdConfigDhcpTest.cpp", + "CmdConfigHistoryTest.cpp", + "CmdConfigHostnameTest.cpp", + "CmdConfigIcmpV4UnavailableSrcAddrTest.cpp", + "CmdConfigInterfaceIpv6NdpTest.cpp", + "CmdConfigInterfaceSwitchportAccessVlanTest.cpp", + "CmdConfigInterfaceSwitchportTrunkAllowedVlanTest.cpp", + "CmdConfigInterfaceTest.cpp", + "CmdConfigIpRouteTest.cpp", + "CmdConfigL2LearningModeTest.cpp", + "CmdConfigLoadBalancingTest.cpp", + "CmdConfigMacAgingTimeTest.cpp", + "CmdConfigPtpTransparentClockTest.cpp", + "CmdConfigQosBufferPoolTest.cpp", + "CmdConfigQosDefaultQueueConfigTest.cpp", + "CmdConfigReloadTest.cpp", + "CmdConfigSessionCommitTest.cpp", + "CmdConfigSessionDiffTest.cpp", + "CmdConfigSessionTest.cpp", + "CmdConfigTestBase.cpp", + "CmdConfigTunnelIpInIpTest.cpp", + "CmdConfigVlanDefaultTest.cpp", + "CmdConfigVlanManagerTest.cpp", + "CmdConfigVlanPortTaggingModeTest.cpp", + "CmdConfigVlanStaticMacTest.cpp", + "CmdConfigVlanTest.cpp", + "CmdDeleteAclRuleTest.cpp", + "CmdDeleteArpTest.cpp", + "CmdDeleteBgpNeighborTest.cpp", + "CmdDeleteConfigInterfaceTest.cpp", + "CmdDeleteDhcpTest.cpp", + "CmdDeleteVlanTest.cpp", + "CmdDeleteInterfaceIpv6NdpTest.cpp", + "CmdDeleteInterfaceTest.cpp", + "CmdDeleteTunnelIpInIpTest.cpp", + "ConfigSessionSystemdTest.cpp", + "CmdDeleteBgpPeerGroupTest.cpp", + "CmdDeleteBgpPolicyAsPathListTest.cpp", + "CmdDeleteBgpPolicyCommunityListTest.cpp", + "CmdDeleteBgpPolicyPrefixListTest.cpp", + "CmdDeleteBgpPolicyRoutingPolicyTest.cpp", + "CmdDeleteCoppCpuTrafficPolicyMatchActionTest.cpp", + "CmdDeleteQosDefaultQueueConfigTest.cpp", + "ProfileValidationTest.cpp", + "CmdConfigTestBase.h", + "MockFbossServiceUtil.h", + "MockSystemdInterface.h", + ], + deps = [ + "//fboss/agent:agent_config", + "//fboss/agent:fboss-error", + "//fboss/agent:fboss-types", + "//fboss/agent:platform_config", + "//fboss/agent:switch_config", + "//fboss/cli/fboss2/test:cmd_test_utils", + "//fboss/cli/fboss2:cli_metadata", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:fboss2-config-lib", + "//fboss/cli/fboss2:fboss2-lib", + "@boost//:boost", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@googletest//:googletest", + "//fboss/util/oss:test_main", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/test/config/BgpConfigSessionTest.cpp b/fboss/cli/fboss2/test/config/BgpConfigSessionTest.cpp index efaa968b47704..e2d6d848d3310 100644 --- a/fboss/cli/fboss2/test/config/BgpConfigSessionTest.cpp +++ b/fboss/cli/fboss2/test/config/BgpConfigSessionTest.cpp @@ -2,11 +2,11 @@ #include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" -#include // NOLINT(misc-include-cleaner) #include #include #include +#include #include "fboss/cli/fboss2/commands/config/protocol/bgp/BgpConfigSession.h" @@ -75,14 +75,6 @@ TEST_F(BgpConfigSessionTest, setConfedAsn) { EXPECT_EQ(config["local_confed_as_4_byte"].asInt(), 65100); } -TEST_F(BgpConfigSessionTest, setClusterId) { - session_->setClusterId("1.2.3.4"); - EXPECT_EQ(session_->getClusterId(), "1.2.3.4"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ(config["cluster_id"].asString(), "1.2.3.4"); -} - TEST_F(BgpConfigSessionTest, setListenAddress) { session_->setListenAddress("0.0.0.0"); EXPECT_EQ(session_->getListenAddress(), "0.0.0.0"); @@ -207,160 +199,6 @@ TEST_F(BgpConfigSessionTest, addMultipleNetworks6) { EXPECT_FALSE(config["networks6"][1]["install_to_fib"].asBool()); } -// ==================== Peer Configuration Tests ==================== - -TEST_F(BgpConfigSessionTest, createPeerAndSetRemoteAsn) { - session_->createPeer("2001:db8::1"); - session_->setPeerRemoteAsn("2001:db8::1", 65001); - - auto& config = session_->getBgpConfig(); - ASSERT_TRUE(config.count("peers")); - ASSERT_EQ(config["peers"].size(), 1); - - auto& peer = config["peers"][0]; - EXPECT_EQ(peer["peer_addr"].asString(), "2001:db8::1"); - EXPECT_EQ(peer["remote_as_4_byte"].asInt(), 65001); -} - -TEST_F(BgpConfigSessionTest, setPeerDescription) { - session_->createPeer("10.0.0.1"); - session_->setPeerDescription("10.0.0.1", "Test peer description"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ( - config["peers"][0]["description"].asString(), "Test peer description"); -} - -TEST_F(BgpConfigSessionTest, setPeerPeerGroupName) { - session_->createPeer("2001:db8::1"); - session_->setPeerGroupName("2001:db8::1", "RSW-FSW-V6"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ(config["peers"][0]["peer_group_name"].asString(), "RSW-FSW-V6"); -} - -TEST_F(BgpConfigSessionTest, setPeerDisableIpv4AfiTrue) { - session_->createPeer("2001:db8::1"); - session_->setPeerDisableIpv4Afi("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["disable_ipv4_afi"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerDisableIpv4AfiFalse) { - // Critical test: Verify that disable_ipv4_afi: false is preserved - session_->createPeer("2001:db8::1"); - session_->setPeerDisableIpv4Afi("2001:db8::1", false); - - auto& config = session_->getBgpConfig(); - // Must be explicitly set to false, not omitted - ASSERT_TRUE(config["peers"][0].count("disable_ipv4_afi")); - EXPECT_FALSE(config["peers"][0]["disable_ipv4_afi"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerNextHopSelf) { - session_->createPeer("2001:db8::1"); - session_->setPeerNextHopSelf("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["next_hop_self"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerConfedPeer) { - session_->createPeer("2001:db8::1"); - session_->setPeerConfedPeer("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["is_confed_peer"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerPassive) { - session_->createPeer("2001:db8::1"); - session_->setPeerPassive("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["is_passive"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerRrClient) { - session_->createPeer("2001:db8::1"); - session_->setPeerRrClient("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["is_rr_client"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerTimers) { - session_->createPeer("2001:db8::1"); - session_->setPeerHoldTime("2001:db8::1", 90); - session_->setPeerKeepalive("2001:db8::1", 30); - session_->setPeerOutDelay("2001:db8::1", 5); - - auto& config = session_->getBgpConfig(); - ASSERT_TRUE(config["peers"][0].count("bgp_peer_timers")); - - auto& timers = config["peers"][0]["bgp_peer_timers"]; - EXPECT_EQ(timers["hold_time_seconds"].asInt(), 90); - EXPECT_EQ(timers["keep_alive_seconds"].asInt(), 30); - EXPECT_EQ(timers["out_delay_seconds"].asInt(), 5); -} - -TEST_F(BgpConfigSessionTest, setPeerPolicies) { - session_->createPeer("2001:db8::1"); - session_->setPeerIngressPolicy("2001:db8::1", "INGRESS_POLICY"); - session_->setPeerEgressPolicy("2001:db8::1", "EGRESS_POLICY"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ( - config["peers"][0]["ingress_policy_name"].asString(), "INGRESS_POLICY"); - EXPECT_EQ( - config["peers"][0]["egress_policy_name"].asString(), "EGRESS_POLICY"); -} - -TEST_F(BgpConfigSessionTest, setPeerPreFilterMaxRoutes) { - session_->createPeer("2001:db8::1"); - session_->setPeerPreFilterMaxRoutes("2001:db8::1", 1000); - - auto& config = session_->getBgpConfig(); - ASSERT_TRUE(config["peers"][0].count("pre_filter")); - EXPECT_EQ(config["peers"][0]["pre_filter"]["max_routes"].asInt(), 1000); -} - -TEST_F(BgpConfigSessionTest, setPeerLinkBandwidth) { - session_->createPeer("2001:db8::1"); - session_->setPeerAdvertiseLbw("2001:db8::1", true); - session_->setPeerLbwValue("2001:db8::1", 10000000000); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["advertise_link_bandwidth"].asBool()); - EXPECT_EQ(config["peers"][0]["link_bandwidth_bps"].asInt(), 10000000000); -} - -TEST_F(BgpConfigSessionTest, setPeerIpv4OverIpv6Nh) { - session_->createPeer("2001:db8::1"); - session_->setPeerIpv4OverIpv6Nh("2001:db8::1", true); - - auto& config = session_->getBgpConfig(); - EXPECT_TRUE(config["peers"][0]["v4_over_v6_nexthop"].asBool()); -} - -TEST_F(BgpConfigSessionTest, setPeerPeerId) { - session_->createPeer("2001:db8::1"); - session_->setPeerPeerId("2001:db8::1", "fsw001.p001.f01.qzd1:v6:1"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ( - config["peers"][0]["peer_id"].asString(), "fsw001.p001.f01.qzd1:v6:1"); -} - -TEST_F(BgpConfigSessionTest, setPeerType) { - session_->createPeer("2001:db8::1"); - session_->setPeerType("2001:db8::1", "FSW"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ(config["peers"][0]["type"].asString(), "FSW"); -} - // ==================== Peer Group Configuration Tests ==================== TEST_F(BgpConfigSessionTest, createPeerGroupAndSetDescription) { @@ -488,14 +326,6 @@ TEST_F(BgpConfigSessionTest, fullRswConfigurationWorkflow) { session_->createPeerGroup("RSW-RTSW-V6"); session_->setPeerGroupDisableIpv4Afi("RSW-RTSW-V6", true); - // Create peer with peer_group_name - session_->createPeer("2401:db00:e50e:1300::20"); - session_->setPeerRemoteAsn("2401:db00:e50e:1300::20", 65000); - session_->setPeerGroupName("2401:db00:e50e:1300::20", "RSW-FSW-V6"); - session_->setPeerDisableIpv4Afi("2401:db00:e50e:1300::20", false); - session_->setPeerPeerId( - "2401:db00:e50e:1300::20", "fsw001.p001.f01.qzd1:v6:1"); - // Verify the complete configuration auto& config = session_->getBgpConfig(); @@ -541,17 +371,6 @@ TEST_F(BgpConfigSessionTest, fullRswConfigurationWorkflow) { } EXPECT_TRUE(foundFswGroup); EXPECT_TRUE(foundRtswGroup); - - // Verify peer - ASSERT_EQ(config["peers"].size(), 1); - auto& peer = config["peers"][0]; - EXPECT_EQ(peer["peer_addr"].asString(), "2401:db00:e50e:1300::20"); - EXPECT_EQ(peer["remote_as_4_byte"].asInt(), 65000); - EXPECT_EQ(peer["peer_group_name"].asString(), "RSW-FSW-V6"); - // Critical: disable_ipv4_afi: false must be preserved - ASSERT_TRUE(peer.count("disable_ipv4_afi")); - EXPECT_FALSE(peer["disable_ipv4_afi"].asBool()); - EXPECT_EQ(peer["peer_id"].asString(), "fsw001.p001.f01.qzd1:v6:1"); } TEST_F(BgpConfigSessionTest, exportConfigProducesValidJson) { @@ -559,8 +378,6 @@ TEST_F(BgpConfigSessionTest, exportConfigProducesValidJson) { session_->setLocalAsn(65000); session_->addNetwork6("2001:db8::/32", "TEST_POLICY", true, 0); session_->createPeerGroup("TEST-GROUP"); - session_->createPeer("2001:db8::1"); - session_->setPeerRemoteAsn("2001:db8::1", 65001); std::string jsonStr = session_->exportConfig(); @@ -571,41 +388,6 @@ TEST_F(BgpConfigSessionTest, exportConfigProducesValidJson) { EXPECT_EQ(parsed["local_as_4_byte"].asInt(), 65000); EXPECT_EQ(parsed["networks6"].size(), 1); EXPECT_EQ(parsed["peer_groups"].size(), 1); - EXPECT_EQ(parsed["peers"].size(), 1); -} - -TEST_F(BgpConfigSessionTest, multiplePeersWithDifferentConfigs) { - // Create multiple peers with different configurations - session_->createPeer("2001:db8::1"); - session_->setPeerRemoteAsn("2001:db8::1", 65001); - session_->setPeerDisableIpv4Afi("2001:db8::1", true); - session_->setPeerNextHopSelf("2001:db8::1", true); - - session_->createPeer("2001:db8::2"); - session_->setPeerRemoteAsn("2001:db8::2", 65002); - session_->setPeerDisableIpv4Afi("2001:db8::2", false); - session_->setPeerPassive("2001:db8::2", true); - - session_->createPeer("10.0.0.1"); - session_->setPeerRemoteAsn("10.0.0.1", 65003); - session_->setPeerRrClient("10.0.0.1", true); - - auto& config = session_->getBgpConfig(); - ASSERT_EQ(config["peers"].size(), 3); - - // Find each peer and verify its config - for (const auto& peer : config["peers"]) { - std::string addr = peer["peer_addr"].asString(); - if (addr == "2001:db8::1") { - EXPECT_TRUE(peer["disable_ipv4_afi"].asBool()); - EXPECT_TRUE(peer["next_hop_self"].asBool()); - } else if (addr == "2001:db8::2") { - EXPECT_FALSE(peer["disable_ipv4_afi"].asBool()); - EXPECT_TRUE(peer["is_passive"].asBool()); - } else if (addr == "10.0.0.1") { - EXPECT_TRUE(peer["is_rr_client"].asBool()); - } - } } TEST_F(BgpConfigSessionTest, stubModePreventsSave) { @@ -623,7 +405,6 @@ TEST_F(BgpConfigSessionTest, stubModeCanClearSession) { // In stub mode, clearSession() should not throw // The actual clearing behavior depends on implementation details session_->setRouterId("10.0.0.1"); - session_->createPeer("2001:db8::1"); EXPECT_EQ(session_->getRouterId(), "10.0.0.1"); @@ -633,24 +414,6 @@ TEST_F(BgpConfigSessionTest, stubModeCanClearSession) { // ==================== Edge Case Tests ==================== -TEST_F(BgpConfigSessionTest, updateExistingPeer) { - // Create peer and set initial values - session_->createPeer("2001:db8::1"); - session_->setPeerRemoteAsn("2001:db8::1", 65001); - session_->setPeerDescription("2001:db8::1", "Initial description"); - - // Update the same peer - session_->setPeerRemoteAsn("2001:db8::1", 65002); - session_->setPeerDescription("2001:db8::1", "Updated description"); - - auto& config = session_->getBgpConfig(); - // Should still only have one peer - ASSERT_EQ(config["peers"].size(), 1); - EXPECT_EQ(config["peers"][0]["remote_as_4_byte"].asInt(), 65002); - EXPECT_EQ( - config["peers"][0]["description"].asString(), "Updated description"); -} - TEST_F(BgpConfigSessionTest, updateExistingPeerGroup) { session_->createPeerGroup("TEST-GROUP"); session_->setPeerGroupDescription("TEST-GROUP", "Initial"); @@ -662,39 +425,10 @@ TEST_F(BgpConfigSessionTest, updateExistingPeerGroup) { EXPECT_EQ(config["peer_groups"][0]["description"].asString(), "Updated"); } -TEST_F(BgpConfigSessionTest, ipv4PeerAddress) { - // Test with IPv4 peer address - session_->createPeer("192.168.1.1"); - session_->setPeerRemoteAsn("192.168.1.1", 65000); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ(config["peers"][0]["peer_addr"].asString(), "192.168.1.1"); -} - -TEST_F(BgpConfigSessionTest, specialCharactersInDescription) { - session_->createPeer("2001:db8::1"); - session_->setPeerDescription( - "2001:db8::1", "Test \"quotes\" and 'apostrophes' and special: !@#$%"); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ( - config["peers"][0]["description"].asString(), - "Test \"quotes\" and 'apostrophes' and special: !@#$%"); -} - TEST_F(BgpConfigSessionTest, largeAsnNumber) { // Test with 4-byte ASN session_->setLocalAsn(4200000000); EXPECT_EQ(session_->getLocalAsn(), 4200000000); } -TEST_F(BgpConfigSessionTest, largeLinkBandwidth) { - // Test with 100G bandwidth - session_->createPeer("2001:db8::1"); - session_->setPeerLbwValue("2001:db8::1", 100000000000); - - auto& config = session_->getBgpConfig(); - EXPECT_EQ(config["peers"][0]["link_bandwidth_bps"].asInt(), 100000000000); -} - } // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpNeighborTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpNeighborTest.cpp new file mode 100644 index 0000000000000..49b0cc9d552f7 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpNeighborTest.cpp @@ -0,0 +1,316 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/fboss/bgp/if/gen-cpp2/bgp_attr_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; +using facebook::neteng::fboss::bgp_attr::AddPath; + +namespace facebook::fboss { + +// The neighbor dispatcher only touches the BGP side of ConfigSession, which +// seeds from thrift schema defaults when neither a staged session nor a +// system bgpcpp.conf exists — so no seed agent config is needed (mirrors +// BgpConfigSessionTest). +class CmdConfigBgpNeighborTestFixture : public CmdConfigTestBase { + public: + CmdConfigBgpNeighborTestFixture() + : CmdConfigTestBase("bgp_neighbor_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string run(const std::vector& tokens) { + CmdConfigProtocolBgpNeighbor cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpNeighborConfig(tokens)); + } + + const std::vector& peers() { + return *ConfigSession::getInstance().getBgpConfig().peers(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpNeighborConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpNeighborTestFixture, argValidation) { + // Bare create. + EXPECT_EQ(BgpNeighborConfig({"10.0.0.1"}).peerAddr(), "10.0.0.1"); + EXPECT_TRUE(BgpNeighborConfig({"10.0.0.1"}).attr().empty()); + + // Address normalization. + EXPECT_EQ(BgpNeighborConfig({"2001:DB8::1"}).peerAddr(), "2001:db8::1"); + + // Prefix notation (passive listening sessions). + EXPECT_EQ(BgpNeighborConfig({"2001:db8::/64"}).peerAddr(), "2001:db8::/64"); + + // Single-token attribute. + auto singleTok = BgpNeighborConfig({"10.0.0.1", "remote-asn", "65000"}); + EXPECT_EQ(singleTok.attr(), "remote-asn"); + EXPECT_EQ(singleTok.values(), std::vector({"65000"})); + + // Two-token attribute wins longest-prefix match. + auto twoTok = BgpNeighborConfig({"10.0.0.1", "timers", "hold-time", "30"}); + EXPECT_EQ(twoTok.attr(), "timers hold-time"); + EXPECT_EQ(twoTok.values(), std::vector({"30"})); + + // Invalid: empty, bad address, unknown attribute, incomplete group. + EXPECT_THROW(BgpNeighborConfig({}), std::invalid_argument); + EXPECT_THROW(BgpNeighborConfig({"not-an-ip"}), std::invalid_argument); + EXPECT_THROW( + BgpNeighborConfig({"10.0.0.1", "no-such-attr", "1"}), + std::invalid_argument); + EXPECT_THROW( + BgpNeighborConfig({"10.0.0.1", "timers"}), std::invalid_argument); +} + +// ============================================================================== +// Attribute handlers +// ============================================================================== + +TEST_F(CmdConfigBgpNeighborTestFixture, bareCreate) { + auto result = run({"10.0.0.1"}); + EXPECT_THAT(result, HasSubstr("Successfully created BGP neighbor 10.0.0.1")); + ASSERT_EQ(peers().size(), 1); + EXPECT_EQ(*peers()[0].peer_addr(), "10.0.0.1"); + // bgpd aborts at config load on unparseable (empty) address fields, so a + // new peer must be born with parseable any-addresses of the right family. + EXPECT_EQ(*peers()[0].local_addr(), "0.0.0.0"); + EXPECT_EQ(*peers()[0].next_hop4(), "0.0.0.0"); + EXPECT_EQ(*peers()[0].next_hop6(), "::"); + EXPECT_TRUE(sessionFileExists()); + + run({"2001:db8::1"}); + ASSERT_EQ(peers().size(), 2); + EXPECT_EQ(*peers()[1].local_addr(), "::"); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, setRemoteAsn) { + auto result = run({"10.0.0.1", "remote-asn", "65000"}); + EXPECT_THAT(result, HasSubstr("65000")); + ASSERT_EQ(peers().size(), 1); + EXPECT_EQ(peers()[0].remote_as_4_byte().value_or(0), 65000); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, timersAccumulate) { + run({"10.0.0.1", "timers", "hold-time", "90"}); + run({"10.0.0.1", "timers", "keepalive", "30"}); + run({"10.0.0.1", "graceful-restart", "restart-time", "120"}); + ASSERT_EQ(peers().size(), 1); + const auto& timers = *peers()[0].bgp_peer_timers(); + EXPECT_EQ(*timers.hold_time_seconds(), 90); + EXPECT_EQ(*timers.keep_alive_seconds(), 30); + EXPECT_EQ(timers.graceful_restart_seconds().value_or(0), 120); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, addPathMerge) { + run({"10.0.0.1", "add-path", "receive", "true"}); + EXPECT_EQ(peers()[0].add_path().value_or(AddPath(0)), AddPath::RECEIVE); + + run({"10.0.0.1", "add-path", "send", "true"}); + EXPECT_EQ(peers()[0].add_path().value_or(AddPath(0)), AddPath::BOTH); + + run({"10.0.0.1", "add-path", "receive", "false"}); + EXPECT_EQ(peers()[0].add_path().value_or(AddPath(0)), AddPath::SEND); + + run({"10.0.0.1", "add-path", "send", "false"}); + EXPECT_FALSE(peers()[0].add_path().has_value()); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, connectMode) { + run({"10.0.0.1", "connect-mode", "PASSIVE"}); + EXPECT_TRUE(peers()[0].is_passive().value_or(false)); + + run({"10.0.0.1", "connect-mode", "ACTIVE"}); + EXPECT_FALSE(peers()[0].is_passive().value_or(true)); + + // BOTH has no thrift representation and must be rejected, leaving the + // previous value intact and nothing new persisted. + auto result = run({"10.0.0.1", "connect-mode", "BOTH"}); + EXPECT_THAT(result, HasSubstr("Error")); + EXPECT_FALSE(peers()[0].is_passive().value_or(true)); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, boolAndStringAttributes) { + run({"10.0.0.1", "rr-client", "true"}); + run({"10.0.0.1", "confed-peer", "false"}); + run({"10.0.0.1", "redistribute-peer", "true"}); + run({"10.0.0.1", "enhanced-route-refresh", "true"}); + run({"10.0.0.1", "afi", "disable-ipv4-afi", "true"}); + run({"10.0.0.1", "afi", "disable-ipv6-afi", "false"}); + run({"10.0.0.1", "afi", "ipv4-over-ipv6-nh", "true"}); + run({"10.0.0.1", "graceful-restart", "stateful-ha", "true"}); + run({"10.0.0.1", "peer-group", "MY-GROUP"}); + run({"10.0.0.1", "peer-tag", "FSW"}); + run({"10.0.0.1", "ingress-policy", "IN_POLICY"}); + run({"10.0.0.1", "egress-policy", "OUT_POLICY"}); + run({"10.0.0.1", "bind-addr", "address", "10.0.0.2"}); + run({"10.0.0.1", "local-asn", "64512"}); + run({"10.0.0.1", "description", "spine", "peer"}); + + ASSERT_EQ(peers().size(), 1); + const auto& peer = peers()[0]; + EXPECT_TRUE(peer.is_rr_client().value_or(false)); + EXPECT_FALSE(peer.is_confed_peer().value_or(true)); + EXPECT_TRUE(peer.is_redistribute_peer().value_or(false)); + EXPECT_TRUE(peer.enhanced_route_refresh().value_or(false)); + EXPECT_TRUE(peer.disable_ipv4_afi().value_or(false)); + EXPECT_FALSE(peer.disable_ipv6_afi().value_or(true)); + EXPECT_TRUE(peer.v4_over_v6_nexthop().value_or(false)); + EXPECT_TRUE(peer.enable_stateful_ha().value_or(false)); + EXPECT_EQ(peer.peer_group_name().value_or(""), "MY-GROUP"); + EXPECT_EQ(peer.peer_tag().value_or(""), "FSW"); + EXPECT_EQ(peer.ingress_policy_name().value_or(""), "IN_POLICY"); + EXPECT_EQ(peer.egress_policy_name().value_or(""), "OUT_POLICY"); + EXPECT_EQ(*peer.local_addr(), "10.0.0.2"); + EXPECT_EQ(peer.local_as_4_byte().value_or(0), 64512); + // Multi-token description is re-joined. + EXPECT_EQ(peer.description().value_or(""), "spine peer"); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, parityAttributes) { + // Attributes carried over from the deleted per-attribute peer commands. + run({"10.0.0.1", "next-hop4", "10.1.1.1"}); + run({"10.0.0.1", "next-hop6", "2001:db8::a"}); + run({"10.0.0.1", "next-hop-self", "true"}); + run({"10.0.0.1", "peer-id", "test-peer:v6:1"}); + run({"10.0.0.1", "type", "BGP_MONITOR"}); + run({"10.0.0.1", "link-bandwidth", "100G"}); + run({"10.0.0.1", "advertise-lbw", "1"}); + run({"10.0.0.1", "receive-lbw", "ACCEPT"}); // enum value name accepted + run( + {"10.0.0.1", + "advertise-lbw", + "true"}); // bool alias (old peer cmd compat) + run({"10.0.0.1", "timers", "withdraw-unprog-delay", "5"}); + run({"10.0.0.1", "max-route", "pre-warning-threshold", "100"}); + run({"10.0.0.1", "max-route", "pre-warning-only", "true"}); + run({"10.0.0.1", "max-route", "post-warning-only", "false"}); + + ASSERT_EQ(peers().size(), 1); + const auto& peer = peers()[0]; + EXPECT_EQ(*peer.next_hop4(), "10.1.1.1"); + EXPECT_EQ(*peer.next_hop6(), "2001:db8::a"); + EXPECT_TRUE(peer.next_hop_self().value_or(false)); + EXPECT_EQ(peer.peer_id().value_or(""), "test-peer:v6:1"); + EXPECT_EQ(peer.type().value_or(""), "BGP_MONITOR"); + EXPECT_EQ(peer.link_bandwidth_bps().value_or(""), "100G"); + EXPECT_EQ( + static_cast(peer.advertise_link_bandwidth().value_or( + facebook::neteng::fboss::bgp_attr::AdvertiseLinkBandwidth::DISABLE)), + 1); + EXPECT_EQ( + static_cast(peer.receive_link_bandwidth().value_or( + facebook::neteng::fboss::bgp_attr::ReceiveLinkBandwidth::DISABLE)), + 1); + EXPECT_EQ(*peer.bgp_peer_timers()->withdraw_unprog_delay_seconds(), 5); + EXPECT_EQ(*peer.pre_filter()->warning_limit(), 100); + EXPECT_TRUE(*peer.pre_filter()->warning_only()); + EXPECT_FALSE(*peer.post_filter()->warning_only()); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, valueValidation) { + // ASN must fit in 4 bytes (RFC 6793). + EXPECT_THAT( + run({"10.0.0.1", "remote-asn", "4294967296"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"10.0.0.1", "local-asn", "18446744073709551615"}), + HasSubstr("Invalid")); + // IP-valued attributes validate the address and its family. + EXPECT_THAT( + run({"10.0.0.1", "bind-addr", "address", "not-an-ip"}), + HasSubstr("Invalid")); + EXPECT_THAT(run({"10.0.0.1", "next-hop4", "2001:db8::a"}), HasSubstr("IPv4")); + EXPECT_THAT(run({"10.0.0.1", "next-hop6", "10.1.1.1"}), HasSubstr("IPv6")); + // Enum-valued attributes reject non-member modes but accept value names + // and true/false aliases (compat with the replaced boolean peer commands). + EXPECT_THAT( + run({"10.0.0.1", "advertise-lbw", "99"}), HasSubstr("not a valid mode")); + // link-bandwidth must be digits with an optional K/M/G suffix. + EXPECT_THAT(run({"10.0.0.1", "link-bandwidth", "10Q"}), HasSubstr("Invalid")); + EXPECT_THAT(run({"10.0.0.1", "link-bandwidth", "G10"}), HasSubstr("Invalid")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F(CmdConfigBgpNeighborTestFixture, routeLimits) { + run({"10.0.0.1", "max-route", "pre-filter", "45000"}); + run({"10.0.0.1", "max-route", "post-filter", "50000"}); + run({"10.0.0.1", "max-route", "post-warning-threshold", "48000"}); + const auto& peer = peers()[0]; + EXPECT_EQ(*peer.pre_filter()->max_routes(), 45000); + EXPECT_EQ(*peer.post_filter()->max_routes(), 50000); + EXPECT_EQ(*peer.post_filter()->warning_limit(), 48000); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, normalizedAddressesShareOnePeer) { + run({"2001:DB8::1", "remote-asn", "65000"}); + run({"2001:db8:0:0::1", "timers", "hold-time", "30"}); + ASSERT_EQ(peers().size(), 1); + EXPECT_EQ(*peers()[0].peer_addr(), "2001:db8::1"); +} + +TEST_F(CmdConfigBgpNeighborTestFixture, distinctAddressesCreateDistinctPeers) { + run({"10.0.0.1", "remote-asn", "65000"}); + run({"10.0.0.2", "remote-asn", "65001"}); + EXPECT_EQ(peers().size(), 2); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F(CmdConfigBgpNeighborTestFixture, invalidValuesRejected) { + EXPECT_THAT(run({"10.0.0.1", "rr-client", "maybe"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"10.0.0.1", "timers", "hold-time", "-1"}), + HasSubstr("non-negative")); + EXPECT_THAT( + run({"10.0.0.1", "remote-asn", "not-a-number"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"10.0.0.1", "max-route", "pre-filter", "-5"}), + HasSubstr("non-negative")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F(CmdConfigBgpNeighborTestFixture, unsupportedAttributesRejected) { + // No thrift representation (or not per-neighbor) — refuse instead of + // persisting dead config. + EXPECT_THAT( + run({"10.0.0.1", "peer-port", "1179"}), HasSubstr("not supported")); + EXPECT_THAT( + run({"10.0.0.1", "bind-addr", "port", "1179"}), + HasSubstr("not supported")); + EXPECT_THAT( + run({"10.0.0.1", "afi", "ipv4-labeled-unicast", "true"}), + HasSubstr("not supported")); + EXPECT_THAT( + run({"10.0.0.1", "afi", "ipv6-labeled-unicast", "true"}), + HasSubstr("not supported")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpPeerGroupTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpPeerGroupTest.cpp new file mode 100644 index 0000000000000..1585e6e683dcb --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpPeerGroupTest.cpp @@ -0,0 +1,247 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/fboss/bgp/if/gen-cpp2/bgp_attr_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; +using facebook::neteng::fboss::bgp_attr::AddPath; + +namespace facebook::fboss { + +// The peer-group dispatcher only touches the BGP side of ConfigSession, which +// seeds from thrift schema defaults when neither a staged session nor a +// system bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpNeighborTest). +class CmdConfigBgpPeerGroupTestFixture : public CmdConfigTestBase { + public: + CmdConfigBgpPeerGroupTestFixture() + : CmdConfigTestBase("bgp_peer_group_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string run(const std::vector& tokens) { + CmdConfigProtocolBgpPeerGroup cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpPeerGroupConfig(tokens)); + } + + const std::vector& groups() { + return ConfigSession::getInstance().getBgpConfig().peer_groups().ensure(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpPeerGroupConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpPeerGroupTestFixture, argValidation) { + // Bare create. + EXPECT_EQ(BgpPeerGroupConfig({"SPINE"}).groupName(), "SPINE"); + EXPECT_TRUE(BgpPeerGroupConfig({"SPINE"}).attr().empty()); + + // Single-token attribute. + auto singleTok = BgpPeerGroupConfig({"SPINE", "remote-asn", "65000"}); + EXPECT_EQ(singleTok.attr(), "remote-asn"); + EXPECT_EQ(singleTok.values(), std::vector({"65000"})); + + // Two-token attribute wins longest-prefix match. + auto twoTok = BgpPeerGroupConfig({"SPINE", "timers", "hold-time", "30"}); + EXPECT_EQ(twoTok.attr(), "timers hold-time"); + EXPECT_EQ(twoTok.values(), std::vector({"30"})); + + // Invalid: empty, empty name, unknown attribute, incomplete group. + EXPECT_THROW(BgpPeerGroupConfig({}), std::invalid_argument); + EXPECT_THROW(BgpPeerGroupConfig({""}), std::invalid_argument); + EXPECT_THROW( + BgpPeerGroupConfig({"SPINE", "no-such-attr", "1"}), + std::invalid_argument); + EXPECT_THROW(BgpPeerGroupConfig({"SPINE", "timers"}), std::invalid_argument); +} + +// ============================================================================== +// Attribute handlers +// ============================================================================== + +TEST_F(CmdConfigBgpPeerGroupTestFixture, bareCreate) { + auto result = run({"SPINE"}); + EXPECT_THAT(result, HasSubstr("Successfully created BGP peer-group SPINE")); + ASSERT_EQ(groups().size(), 1); + EXPECT_EQ(*groups()[0].name(), "SPINE"); + // PeerGroup's only non-optional field is `name`; nothing else is seeded. + EXPECT_FALSE(groups()[0].local_addr().has_value()); + EXPECT_TRUE(sessionFileExists()); + + run({"LEAF"}); + ASSERT_EQ(groups().size(), 2); + EXPECT_EQ(*groups()[1].name(), "LEAF"); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, setRemoteAsn) { + auto result = run({"SPINE", "remote-asn", "65000"}); + EXPECT_THAT(result, HasSubstr("65000")); + ASSERT_EQ(groups().size(), 1); + EXPECT_EQ(groups()[0].remote_as_4_byte().value_or(0), 65000); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, timersAccumulate) { + run({"SPINE", "timers", "hold-time", "90"}); + run({"SPINE", "timers", "keepalive", "30"}); + run({"SPINE", "graceful-restart", "restart-time", "120"}); + ASSERT_EQ(groups().size(), 1); + const auto& timers = *groups()[0].bgp_peer_timers(); + EXPECT_EQ(*timers.hold_time_seconds(), 90); + EXPECT_EQ(*timers.keep_alive_seconds(), 30); + EXPECT_EQ(timers.graceful_restart_seconds().value_or(0), 120); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, addPathMerge) { + run({"SPINE", "add-path", "receive", "true"}); + EXPECT_EQ(groups()[0].add_path().value_or(AddPath(0)), AddPath::RECEIVE); + + run({"SPINE", "add-path", "send", "true"}); + EXPECT_EQ(groups()[0].add_path().value_or(AddPath(0)), AddPath::BOTH); + + run({"SPINE", "add-path", "receive", "false"}); + EXPECT_EQ(groups()[0].add_path().value_or(AddPath(0)), AddPath::SEND); + + run({"SPINE", "add-path", "send", "false"}); + EXPECT_FALSE(groups()[0].add_path().has_value()); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, connectMode) { + run({"SPINE", "connect-mode", "PASSIVE"}); + EXPECT_TRUE(groups()[0].is_passive().value_or(false)); + + run({"SPINE", "connect-mode", "ACTIVE"}); + EXPECT_FALSE(groups()[0].is_passive().value_or(true)); + + // BOTH has no thrift representation and must be rejected, leaving the + // previous value intact and nothing new persisted. + auto result = run({"SPINE", "connect-mode", "BOTH"}); + EXPECT_THAT(result, HasSubstr("Error")); + EXPECT_FALSE(groups()[0].is_passive().value_or(true)); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, boolAndStringAttributes) { + run({"SPINE", "rr-client", "true"}); + run({"SPINE", "confed-peer", "false"}); + run({"SPINE", "redistribute-peer", "true"}); + run({"SPINE", "enhanced-route-refresh", "true"}); + run({"SPINE", "afi", "disable-ipv4-afi", "true"}); + run({"SPINE", "afi", "disable-ipv6-afi", "false"}); + run({"SPINE", "afi", "ipv4-over-ipv6-nh", "true"}); + run({"SPINE", "graceful-restart", "stateful-ha", "true"}); + run({"SPINE", "peer-tag", "FSW"}); + run({"SPINE", "ingress-policy", "IN_POLICY"}); + run({"SPINE", "egress-policy", "OUT_POLICY"}); + run({"SPINE", "local-asn", "64512"}); + run({"SPINE", "next-hop-self", "true"}); + run({"SPINE", "description", "spine", "group"}); + + ASSERT_EQ(groups().size(), 1); + const auto& group = groups()[0]; + EXPECT_TRUE(group.is_rr_client().value_or(false)); + EXPECT_FALSE(group.is_confed_peer().value_or(true)); + EXPECT_TRUE(group.is_redistribute_peer().value_or(false)); + EXPECT_TRUE(group.enhanced_route_refresh().value_or(false)); + EXPECT_TRUE(group.disable_ipv4_afi().value_or(false)); + EXPECT_FALSE(group.disable_ipv6_afi().value_or(true)); + EXPECT_TRUE(group.v4_over_v6_nexthop().value_or(false)); + EXPECT_TRUE(group.enable_stateful_ha().value_or(false)); + EXPECT_EQ(group.peer_tag().value_or(""), "FSW"); + EXPECT_EQ(group.ingress_policy_name().value_or(""), "IN_POLICY"); + EXPECT_EQ(group.egress_policy_name().value_or(""), "OUT_POLICY"); + EXPECT_EQ(group.local_as_4_byte().value_or(0), 64512); + EXPECT_TRUE(group.next_hop_self().value_or(false)); + // Multi-token description is re-joined. + EXPECT_EQ(group.description().value_or(""), "spine group"); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, routeLimits) { + run({"SPINE", "max-route", "pre-filter", "45000"}); + run({"SPINE", "max-route", "post-filter", "50000"}); + run({"SPINE", "max-route", "post-warning-threshold", "48000"}); + // Parity attributes carried over from the deleted per-attribute commands. + run({"SPINE", "max-route", "pre-warning-threshold", "40000"}); + run({"SPINE", "max-route", "pre-warning-only", "true"}); + run({"SPINE", "max-route", "post-warning-only", "false"}); + const auto& group = groups()[0]; + EXPECT_EQ(*group.pre_filter()->max_routes(), 45000); + EXPECT_EQ(*group.post_filter()->max_routes(), 50000); + EXPECT_EQ(*group.post_filter()->warning_limit(), 48000); + EXPECT_EQ(*group.pre_filter()->warning_limit(), 40000); + EXPECT_TRUE(*group.pre_filter()->warning_only()); + EXPECT_FALSE(*group.post_filter()->warning_only()); +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, valueValidation) { + // ASN must fit in 4 bytes (RFC 6793). + EXPECT_THAT(run({"SPINE", "remote-asn", "4294967296"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"SPINE", "local-asn", "18446744073709551615"}), + HasSubstr("Invalid")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, namedGroupsAreDistinct) { + run({"SPINE", "remote-asn", "65000"}); + run({"LEAF", "remote-asn", "65001"}); + ASSERT_EQ(groups().size(), 2); + // Re-referencing an existing group by name updates it, not appends. + run({"SPINE", "local-asn", "64512"}); + EXPECT_EQ(groups().size(), 2); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F(CmdConfigBgpPeerGroupTestFixture, invalidValuesRejected) { + EXPECT_THAT(run({"SPINE", "rr-client", "maybe"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"SPINE", "timers", "hold-time", "-1"}), HasSubstr("non-negative")); + EXPECT_THAT( + run({"SPINE", "remote-asn", "not-a-number"}), HasSubstr("Invalid")); + EXPECT_THAT( + run({"SPINE", "max-route", "pre-filter", "-5"}), + HasSubstr("non-negative")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F(CmdConfigBgpPeerGroupTestFixture, unsupportedAttributesRejected) { + // These attributes have no per-peer-group thrift field, so they are not in + // the dispatch table and are refused at parse time as unknown attributes. + EXPECT_THROW(run({"SPINE", "peer-port", "1179"}), std::invalid_argument); + EXPECT_THROW( + run({"SPINE", "afi", "ipv4-labeled-unicast", "true"}), + std::invalid_argument); + EXPECT_THROW( + run({"SPINE", "afi", "ipv6-labeled-unicast", "true"}), + std::invalid_argument); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListEntryTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListEntryTest.cpp new file mode 100644 index 0000000000000..85fa203e819b8 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListEntryTest.cpp @@ -0,0 +1,210 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/routing_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/entry/CmdConfigProtocolBgpPolicyAsPathListEntry.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; +using facebook::bgp::routing_policy::MatchValueLogicOperator; + +namespace facebook::fboss { + +// The entry dispatcher only touches the BGP side of ConfigSession, which seeds +// from thrift schema defaults when neither a staged session nor a system +// bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPolicyAsPathListTest). +class CmdConfigBgpPolicyAsPathListEntryTestFixture : public CmdConfigTestBase { + public: + CmdConfigBgpPolicyAsPathListEntryTestFixture() + : CmdConfigTestBase("bgp_aspath_list_entry_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + // Invoke the entry handler the way the framework does: the parent's parsed + // args plus the entry's own tokens. + std::string runEntry( + const std::vector& listTokens, + const std::vector& entryTokens) { + CmdConfigProtocolBgpPolicyAsPathListEntry cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient( + hostInfo, + BgpAsPathListConfig(listTokens), + BgpAsPathListEntryConfig(entryTokens)); + } + + std::string runList(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyAsPathList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpAsPathListConfig(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .aspath_lists(); + } + + const std::vector& entries(size_t listIdx) { + return *lists()[listIdx].as_path_list(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpAsPathListEntryConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyAsPathListEntryTestFixture, argValidation) { + // Bare create. + auto bare = BgpAsPathListEntryConfig({"10"}); + EXPECT_EQ(bare.seqNum(), 10); + EXPECT_TRUE(bare.attr().empty()); + + // Attribute with values. + auto attr = BgpAsPathListEntryConfig({"10", "asn-regexp", "^65000_"}); + EXPECT_EQ(attr.seqNum(), 10); + EXPECT_EQ(attr.attr(), "asn-regexp"); + EXPECT_EQ(attr.values(), std::vector({"^65000_"})); + + // Invalid: empty, non-numeric or negative seq-num, unknown attribute. + EXPECT_THROW(BgpAsPathListEntryConfig({}), std::invalid_argument); + EXPECT_THROW(BgpAsPathListEntryConfig({"not-a-num"}), std::invalid_argument); + EXPECT_THROW(BgpAsPathListEntryConfig({"-1"}), std::invalid_argument); + EXPECT_THROW( + BgpAsPathListEntryConfig({"10", "no-such-attr", "1"}), + std::invalid_argument); +} + +// ============================================================================== +// Entry-level handlers +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyAsPathListEntryTestFixture, bareCreateEntry) { + auto result = runEntry({"AS100"}, {"10"}); + EXPECT_THAT( + result, + HasSubstr("Successfully created BGP as-path-list AS100 entry 10")); + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(entries(0).size(), 1); + EXPECT_EQ(*entries(0)[0].sequence_number(), 10); +} + +TEST_F(CmdConfigBgpPolicyAsPathListEntryTestFixture, setEntryAttributes) { + runEntry({"AS100"}, {"10", "asn-regexp", "^65000_"}); + runEntry({"AS100"}, {"10", "description", "match", "65000"}); + runEntry({"AS100"}, {"10", "match-logic", "NOT_EQUAL"}); + + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(entries(0).size(), 1); + const auto& entry = entries(0)[0]; + EXPECT_EQ(*entry.sequence_number(), 10); + EXPECT_EQ(entry.as_path()->as_path_ref()->asn_regexp().value(), "^65000_"); + EXPECT_EQ(*entry.description(), "match 65000"); + EXPECT_EQ(*entry.match_logic_type(), MatchValueLogicOperator::NOT_EQUAL); +} + +TEST_F( + CmdConfigBgpPolicyAsPathListEntryTestFixture, + entriesAccumulateAndAreKeyed) { + runEntry({"AS100"}, {"10", "asn-regexp", "^65000_"}); + runEntry({"AS100"}, {"20", "asn-regexp", "^65001_"}); + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(entries(0).size(), 2); + + // Re-referencing an existing entry by seq-num updates it, not appends. + runEntry({"AS100"}, {"10", "match-logic", "EQUAL"}); + EXPECT_EQ(entries(0).size(), 2); +} + +TEST_F(CmdConfigBgpPolicyAsPathListEntryTestFixture, asnRegexpAllowsSpaces) { + // AS-path regexes separate ASNs with spaces; the pattern must survive as a + // single re-joined value. + runEntry({"AS100"}, {"10", "asn-regexp", "^65000", "65001$"}); + EXPECT_EQ( + entries(0)[0].as_path()->as_path_ref()->asn_regexp().value(), + "^65000 65001$"); +} + +TEST_F( + CmdConfigBgpPolicyAsPathListEntryTestFixture, + reReferenceReportsExisting) { + runEntry({"AS100"}, {"10"}); + EXPECT_THAT( + runEntry({"AS100"}, {"10"}), HasSubstr("entry 10 already exists")); + EXPECT_EQ(entries(0).size(), 1); +} + +TEST_F(CmdConfigBgpPolicyAsPathListEntryTestFixture, matchLogicDefaultIsEqual) { + runEntry({"AS100"}, {"10"}); + EXPECT_EQ(*entries(0)[0].match_logic_type(), MatchValueLogicOperator::EQUAL); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F( + CmdConfigBgpPolicyAsPathListEntryTestFixture, + invalidMatchLogicRejected) { + auto result = runEntry({"AS100"}, {"10", "match-logic", "MAYBE"}); + // The full message matters: the accepted-values suffix once printed garbage + // (a string_view capture dangling over a fmt::format temporary). + EXPECT_THAT( + result, + HasSubstr("Invalid match-logic value 'MAYBE'; expected EQUAL|NOT_EQUAL")); + // The rejected value must not leave a phantom list/entry behind. + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F( + CmdConfigBgpPolicyAsPathListEntryTestFixture, + rejectedEntryOnExistingListKeepsList) { + // Create the list first, then reject an entry value on it. + runList({"AS100", "description", "keep-me"}); + ASSERT_EQ(lists().size(), 1); + + auto result = runEntry({"AS100"}, {"10", "match-logic", "MAYBE"}); + EXPECT_THAT(result, HasSubstr("Invalid")); + // The pre-existing list survives; only the phantom entry is rolled back. + ASSERT_EQ(lists().size(), 1); + EXPECT_TRUE(entries(0).empty()); + EXPECT_EQ(*lists()[0].description(), "keep-me"); +} + +// A list-level attribute alongside an entry must be rejected: only the leaf +// command runs, so the list attribute would be silently dropped. +TEST_F( + CmdConfigBgpPolicyAsPathListEntryTestFixture, + listAttributeMixedWithEntryRejected) { + auto result = runEntry({"AS100", "description", "mixed"}, {"10"}); + EXPECT_THAT(result, HasSubstr("separate commands")); + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()); +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListTest.cpp new file mode 100644 index 0000000000000..c0e96f09a023d --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyAsPathListTest.cpp @@ -0,0 +1,137 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// The as-path-list dispatcher only touches the BGP side of ConfigSession, +// which seeds from thrift schema defaults when neither a staged session nor a +// system bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPeerGroupTest). +class CmdConfigBgpPolicyAsPathListTestFixture : public CmdConfigTestBase { + public: + CmdConfigBgpPolicyAsPathListTestFixture() + : CmdConfigTestBase("bgp_aspath_list_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string run(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyAsPathList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpAsPathListConfig(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .aspath_lists(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpAsPathListConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, argValidation) { + // Bare create list. + auto bareList = BgpAsPathListConfig({"AS100"}); + EXPECT_EQ(bareList.listName(), "AS100"); + EXPECT_TRUE(bareList.attr().empty()); + + // List-level attribute. + auto listAttr = BgpAsPathListConfig({"AS100", "description", "my", "list"}); + EXPECT_EQ(listAttr.attr(), "description"); + EXPECT_EQ(listAttr.values(), std::vector({"my", "list"})); + + // Invalid: empty, empty name, unknown attribute. + EXPECT_THROW(BgpAsPathListConfig({}), std::invalid_argument); + EXPECT_THROW(BgpAsPathListConfig({""}), std::invalid_argument); + EXPECT_THROW( + BgpAsPathListConfig({"AS100", "no-such-attr", "1"}), + std::invalid_argument); + // asn-regexp is an entry attribute, not a list attribute. + EXPECT_THROW( + BgpAsPathListConfig({"AS100", "asn-regexp", "^65000_"}), + std::invalid_argument); +} + +// ============================================================================== +// List-level handlers +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, bareCreateList) { + auto result = run({"AS100"}); + EXPECT_THAT(result, HasSubstr("Successfully created BGP as-path-list AS100")); + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "AS100"); + EXPECT_TRUE(lists()[0].as_path_list()->empty()); + EXPECT_TRUE(sessionFileExists()); + + run({"AS200"}); + ASSERT_EQ(lists().size(), 2); + EXPECT_EQ(*lists()[1].name(), "AS200"); +} + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, setListDescription) { + auto result = run({"AS100", "description", "spine", "as-paths"}); + EXPECT_THAT(result, HasSubstr("Successfully set description")); + ASSERT_EQ(lists().size(), 1); + // Multi-token description is re-joined. + EXPECT_EQ(*lists()[0].description(), "spine as-paths"); +} + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, namedListsAreDistinct) { + run({"AS100", "description", "one"}); + run({"AS200", "description", "two"}); + ASSERT_EQ(lists().size(), 2); + // Re-referencing an existing list by name updates it, not appends. + run({"AS100", "description", "one-updated"}); + ASSERT_EQ(lists().size(), 2); + EXPECT_EQ(*lists()[0].description(), "one-updated"); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, reReferenceReportsExisting) { + run({"AS100"}); + // A second bare reference must not claim to have created it again. + EXPECT_THAT(run({"AS100"}), HasSubstr("already exists")); + ASSERT_EQ(lists().size(), 1); +} + +TEST_F(CmdConfigBgpPolicyAsPathListTestFixture, unknownAttributeRejected) { + EXPECT_THROW(run({"AS100", "no-such-attr", "1"}), std::invalid_argument); + // The rejected command must not leave a phantom list behind. + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListCommunityTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListCommunityTest.cpp new file mode 100644 index 0000000000000..805eeae8b49f3 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListCommunityTest.cpp @@ -0,0 +1,219 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/community/CmdConfigProtocolBgpPolicyCommunityListCommunity.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// The community dispatcher only touches the BGP side of ConfigSession, which +// seeds from thrift schema defaults when neither a staged session nor a system +// bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPolicyCommunityListTest). +class CmdConfigBgpPolicyCommunityListCommunityTestFixture + : public CmdConfigTestBase { + public: + CmdConfigBgpPolicyCommunityListCommunityTestFixture() + : CmdConfigTestBase("bgp_community_list_community_test_%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + // Invoke the community handler the way the framework does: the parent's + // parsed args plus the community's own tokens. + std::string runCommunity( + const std::vector& listTokens, + const std::vector& communityTokens) { + CmdConfigProtocolBgpPolicyCommunityListCommunity cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient( + hostInfo, + BgpCommunityListConfig(listTokens), + BgpCommunityListCommunityConfig(communityTokens)); + } + + std::string runList(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyCommunityList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpCommunityListConfig(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .community_lists(); + } + + // The inline Community held by members[idx] of list[listIdx]. + const bgp::bgp_policy::Community& member(size_t listIdx, size_t idx) { + return *lists()[listIdx].members()->at(idx).community_ref(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpCommunityListCommunityConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyCommunityListCommunityTestFixture, argValidation) { + // Bare create. + auto bare = BgpCommunityListCommunityConfig({"CM1"}); + EXPECT_EQ(bare.communityName(), "CM1"); + EXPECT_TRUE(bare.attr().empty()); + + // Attribute with values. + auto attr = BgpCommunityListCommunityConfig({"CM1", "value", "65000:100"}); + EXPECT_EQ(attr.communityName(), "CM1"); + EXPECT_EQ(attr.attr(), "value"); + EXPECT_EQ(attr.values(), std::vector({"65000:100"})); + + // Invalid: empty, empty name, unknown attribute. + EXPECT_THROW(BgpCommunityListCommunityConfig({}), std::invalid_argument); + EXPECT_THROW(BgpCommunityListCommunityConfig({""}), std::invalid_argument); + EXPECT_THROW( + BgpCommunityListCommunityConfig({"CM1", "no-such-attr", "1"}), + std::invalid_argument); + // exact-match is a list attribute, not a community attribute. + EXPECT_THROW( + BgpCommunityListCommunityConfig({"CM1", "exact-match", "true"}), + std::invalid_argument); +} + +// ============================================================================== +// Community-level handlers +// ============================================================================== + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + bareCreateCommunity) { + auto result = runCommunity({"CL100"}, {"CM1"}); + EXPECT_THAT( + result, + HasSubstr("Successfully created BGP community-list CL100 community CM1")); + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(lists()[0].members()->size(), 1); + EXPECT_EQ(*member(0, 0).name(), "CM1"); +} + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + setCommunityAttributes) { + runCommunity({"CL100"}, {"CM1", "value", "65000:100"}); + runCommunity({"CL100"}, {"CM1", "type", "LARGE"}); + runCommunity({"CL100"}, {"CM1", "description", "spine", "tag"}); + + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(lists()[0].members()->size(), 1); + const auto& community = member(0, 0); + EXPECT_EQ(*community.name(), "CM1"); + EXPECT_EQ(*community.value(), "65000:100"); + EXPECT_EQ(*community.type(), bgp::bgp_policy::CommunityType::LARGE); + EXPECT_EQ(*community.description(), "spine tag"); +} + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + communitiesAccumulateAndAreKeyed) { + runCommunity({"CL100"}, {"CM1", "value", "65000:100"}); + runCommunity({"CL100"}, {"CM2", "value", "65000:200"}); + ASSERT_EQ(lists().size(), 1); + ASSERT_EQ(lists()[0].members()->size(), 2); + + // Re-referencing an existing member by name updates it, not appends. + runCommunity({"CL100"}, {"CM1", "type", "NORMAL"}); + EXPECT_EQ(lists()[0].members()->size(), 2); + EXPECT_EQ(*member(0, 0).value(), "65000:100"); + EXPECT_EQ(*member(0, 0).type(), bgp::bgp_policy::CommunityType::NORMAL); +} + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + reReferenceReportsExisting) { + runCommunity({"CL100"}, {"CM1"}); + EXPECT_THAT( + runCommunity({"CL100"}, {"CM1"}), + HasSubstr("community CM1 already exists")); + EXPECT_EQ(lists()[0].members()->size(), 1); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + invalidCommunityTypeRejected) { + auto result = runCommunity({"CL100"}, {"CM1", "type", "MEDIUM"}); + // The full message matters: the accepted-values suffix once printed garbage + // (a string_view capture dangling over a fmt::format temporary). + EXPECT_THAT( + result, + HasSubstr("Invalid type value 'MEDIUM'; expected NORMAL|EXTENDED|LARGE")); + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + rejectedCommunityOnExistingListKeepsList) { + // Create the list first, then reject a member value on it. + runList({"CL100", "description", "keep-me"}); + ASSERT_EQ(lists().size(), 1); + + auto result = runCommunity({"CL100"}, {"CM1", "type", "MEDIUM"}); + EXPECT_THAT(result, HasSubstr("Invalid")); + // The pre-existing list survives; only the phantom member is rolled back — + // including the members field itself, which was unset before. + ASSERT_EQ(lists().size(), 1); + EXPECT_FALSE(lists()[0].members().has_value()); + EXPECT_EQ(*lists()[0].description(), "keep-me"); +} + +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + rejectedCommunityKeepsExistingMembers) { + runCommunity({"CL100"}, {"CM1", "value", "65000:100"}); + ASSERT_EQ(lists()[0].members()->size(), 1); + + auto result = runCommunity({"CL100"}, {"CM2", "type", "MEDIUM"}); + EXPECT_THAT(result, HasSubstr("Invalid")); + // Only the phantom member is rolled back; the existing one survives. + ASSERT_EQ(lists()[0].members()->size(), 1); + EXPECT_EQ(*member(0, 0).name(), "CM1"); +} + +// A list-level attribute alongside a community must be rejected: only the leaf +// command runs, so the list attribute would be silently dropped. +TEST_F( + CmdConfigBgpPolicyCommunityListCommunityTestFixture, + listAttributeMixedWithCommunityRejected) { + auto result = runCommunity({"CL100", "description", "mixed"}, {"CM1"}); + EXPECT_THAT(result, HasSubstr("separate commands")); + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()); +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListTest.cpp new file mode 100644 index 0000000000000..186bce550c7ec --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdConfigBgpPolicyCommunityListTest.cpp @@ -0,0 +1,181 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/routing_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; +using facebook::bgp::routing_policy::BooleanOperator; + +namespace facebook::fboss { + +// The community-list dispatcher only touches the BGP side of ConfigSession, +// which seeds from thrift schema defaults when neither a staged session nor a +// system bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPolicyAsPathListTest). +class CmdConfigBgpPolicyCommunityListTestFixture : public CmdConfigTestBase { + public: + CmdConfigBgpPolicyCommunityListTestFixture() + : CmdConfigTestBase("bgp_community_list_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string run(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyCommunityList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpCommunityListConfig(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .community_lists(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpCommunityListConfig (arg) validation +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, argValidation) { + // Bare create list. + auto bareList = BgpCommunityListConfig({"CL100"}); + EXPECT_EQ(bareList.listName(), "CL100"); + EXPECT_TRUE(bareList.attr().empty()); + + // List-level attribute. + auto listAttr = + BgpCommunityListConfig({"CL100", "description", "my", "list"}); + EXPECT_EQ(listAttr.attr(), "description"); + EXPECT_EQ(listAttr.values(), std::vector({"my", "list"})); + + // Invalid: empty, empty name, unknown attribute. + EXPECT_THROW(BgpCommunityListConfig({}), std::invalid_argument); + EXPECT_THROW(BgpCommunityListConfig({""}), std::invalid_argument); + EXPECT_THROW( + BgpCommunityListConfig({"CL100", "no-such-attr", "1"}), + std::invalid_argument); + // value is a community attribute, not a list attribute. + EXPECT_THROW( + BgpCommunityListConfig({"CL100", "value", "65000:100"}), + std::invalid_argument); +} + +// ============================================================================== +// List-level handlers +// ============================================================================== + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, bareCreateList) { + auto result = run({"CL100"}); + EXPECT_THAT( + result, HasSubstr("Successfully created BGP community-list CL100")); + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "CL100"); + EXPECT_FALSE(lists()[0].members().has_value()); + EXPECT_TRUE(sessionFileExists()); + + run({"CL200"}); + ASSERT_EQ(lists().size(), 2); + EXPECT_EQ(*lists()[1].name(), "CL200"); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, setListDescription) { + auto result = run({"CL100", "description", "spine", "communities"}); + EXPECT_THAT(result, HasSubstr("Successfully set description")); + ASSERT_EQ(lists().size(), 1); + // Multi-token description is re-joined. + EXPECT_EQ(*lists()[0].description(), "spine communities"); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, setBooleanOperator) { + auto result = run({"CL100", "boolean-operator", "AND"}); + EXPECT_THAT(result, HasSubstr("Successfully set boolean-operator")); + EXPECT_EQ(*lists()[0].boolean_operator(), BooleanOperator::AND); + + run({"CL100", "boolean-operator", "NOT"}); + EXPECT_EQ(*lists()[0].boolean_operator(), BooleanOperator::NOT); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, booleanOperatorDefaultIsOr) { + run({"CL100"}); + EXPECT_EQ(*lists()[0].boolean_operator(), BooleanOperator::OR); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, setExactMatch) { + auto result = run({"CL100", "exact-match", "true"}); + EXPECT_THAT(result, HasSubstr("Successfully enabled exact-match")); + ASSERT_TRUE(lists()[0].exact_match().has_value()); + EXPECT_TRUE(*lists()[0].exact_match()); + + auto disabled = run({"CL100", "exact-match", "false"}); + EXPECT_THAT(disabled, HasSubstr("Successfully disabled exact-match")); + EXPECT_FALSE(*lists()[0].exact_match()); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, namedListsAreDistinct) { + run({"CL100", "description", "one"}); + run({"CL200", "description", "two"}); + ASSERT_EQ(lists().size(), 2); + // Re-referencing an existing list by name updates it, not appends. + run({"CL100", "description", "one-updated"}); + ASSERT_EQ(lists().size(), 2); + EXPECT_EQ(*lists()[0].description(), "one-updated"); +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, reReferenceReportsExisting) { + run({"CL100"}); + // A second bare reference must not claim to have created it again. + EXPECT_THAT(run({"CL100"}), HasSubstr("already exists")); + ASSERT_EQ(lists().size(), 1); +} + +// ============================================================================== +// Reject paths — the error is surfaced and nothing is persisted +// ============================================================================== + +TEST_F( + CmdConfigBgpPolicyCommunityListTestFixture, + invalidBooleanOperatorRejected) { + auto result = run({"CL100", "boolean-operator", "XOR"}); + // The full message matters: the accepted-values suffix once printed garbage + // (a string_view capture dangling over a fmt::format temporary). + EXPECT_THAT( + result, + HasSubstr("Invalid boolean-operator value 'XOR'; expected AND|OR|NOT")); + // The rejected value must not leave a phantom list behind. + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +TEST_F(CmdConfigBgpPolicyCommunityListTestFixture, invalidExactMatchRejected) { + auto result = run({"CL100", "exact-match", "maybe"}); + EXPECT_THAT(result, HasSubstr("Invalid")); + EXPECT_TRUE(lists().empty()); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected input"; +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdConfigSessionTest.cpp b/fboss/cli/fboss2/test/config/CmdConfigSessionTest.cpp index f142911167558..7fcaf01ddee55 100644 --- a/fboss/cli/fboss2/test/config/CmdConfigSessionTest.cpp +++ b/fboss/cli/fboss2/test/config/CmdConfigSessionTest.cpp @@ -955,6 +955,62 @@ TEST_F(ConfigSessionTestFixture, concurrentSessionConflict) { EXPECT_THAT(content, ::testing::Not(::testing::HasSubstr("User2 change"))); } +// BGP analog of concurrentSessionConflict: two BGP sessions start from the same +// base; once user1 commits (advancing HEAD), user2's commit must be rejected +// because its base is now stale -- one session "steps onto" the other. Only +// user1's BGP change reaches the running bgpd config. +TEST_F(ConfigSessionTestFixture, concurrentBgpSessionConflict) { + fs::path sessionDir1 = getTestHomeDir() / ".fboss2_user1"; + fs::path sessionDir2 = getTestHomeDir() / ".fboss2_user2"; + fs::path bgpSys = getTestEtcDir() / "coop" / "bgpcpp" / "bgpcpp.conf"; + + auto makeSession = [&](const fs::path& dir) { + auto s = std::make_unique( + dir.string(), (getTestEtcDir() / "coop").string()); + // BGP commits restart bgpd via systemd; mock it out. Only user1 commits, so + // no agent reload is triggered (no mocked agent server needed). + s->setMockSystemdFactory([] { + return std::make_unique<::testing::NiceMock>(); + }); + return s; + }; + + // Both users start sessions at the same base (current HEAD). + auto session1 = makeSession(sessionDir1); + auto session2 = makeSession(sessionDir2); + + // User1 stages a BGP change and commits -> HEAD advances. + session1->getBgpConfig().router_id() = "1.1.1.1"; + session1->setCommandLine("config protocol bgp global router-id 1.1.1.1"); + session1->saveBgpConfig(); + EXPECT_FALSE(session1->commit(localhost()).commitSha.empty()); + + // User2 stages a different BGP change on top of the now-stale base. + session2->getBgpConfig().router_id() = "2.2.2.2"; + session2->setCommandLine("config protocol bgp global router-id 2.2.2.2"); + session2->saveBgpConfig(); + + // User2's commit must fail because user1 already advanced HEAD. + EXPECT_THROW( + { + try { + session2->commit(localhost()); + } catch (const std::runtime_error& e) { + EXPECT_THAT( + e.what(), + ::testing::HasSubstr("system configuration has changed")); + throw; + } + }, + std::runtime_error); + + // Only user1's BGP change reached the running bgpd config. + std::string content; + ASSERT_TRUE(folly::readFile(bgpSys.string().c_str(), content)); + EXPECT_THAT(content, ::testing::HasSubstr("1.1.1.1")); + EXPECT_THAT(content, ::testing::Not(::testing::HasSubstr("2.2.2.2"))); +} + TEST_F(ConfigSessionTestFixture, rebaseSuccessNoConflict) { // Test successful rebase when user2's changes don't conflict with user1's fs::path sessionDir1 = getTestHomeDir() / ".fboss2_user1"; @@ -1087,8 +1143,12 @@ TEST_F(ConfigSessionTestFixture, threeWayMergeScenarios) { fs::path cliConfigPath = getTestEtcDir() / "coop" / "cli" / "agent.conf"; setupMockedAgentServer(); - // 5 commits: 2 in scenario 1, 2 in scenario 2, 1 in scenario 3 (rebase fails) - EXPECT_CALL(getMockAgent(), reloadConfig()).Times(5); + // Reloads happen only when a commit actually changes the promoted config + // (agent skip-when-unchanged): scenario 1 = 2 commits (both change config); + // scenario 2's session2 rebases to the SAME value session1 committed, so its + // commit is a no-op and does NOT reload -> only 1 reload there; scenario 3 = + // 1 commit (session2's rebase throws before committing). Total = 2 + 1 + 1. + EXPECT_CALL(getMockAgent(), reloadConfig()).Times(4); // Scenario 1: Only session changed, head unchanged // User1 commits, User2 changes different field - should merge cleanly @@ -1236,6 +1296,48 @@ TEST_F(ConfigSessionTestFixture, emptyCommit) { EXPECT_TRUE(session.sessionExists()); } +// Re-committing an agent config that is byte-identical to what is already +// promoted must be a no-op: no git revision and (crucially) no reloadConfig(). +// A config command records an AGENT action even when it sets a field to its +// current value, so commit() must skip based on content equality (the same +// skip-when-unchanged rule BGP uses). +TEST_F(ConfigSessionTestFixture, commitUnchangedAgentConfigIsNoOp) { + fs::path sessionDir = getTestHomeDir() / ".fboss2"; + + setupMockedAgentServer(); + // The first (real) commit reloads once; the second (unchanged) commit must + // NOT reload. + EXPECT_CALL(getMockAgent(), reloadConfig()).Times(1); + + // First commit: set a description and commit. This normalizes cli/agent.conf + // into the canonical serialized form. + { + TestableConfigSession session( + sessionDir.string(), (getTestEtcDir() / "coop").string()); + (*session.getAgentConfig().sw()->ports())[0].description() = "same_desc"; + session.setCommandLine("config interface eth1/1/1 description same_desc"); + session.saveConfig( + cli::ServiceType::AGENT, cli::ConfigActionLevel::HITLESS); + ASSERT_FALSE(session.commit(localhost()).commitSha.empty()); + } + + // Second commit: set the SAME description again -> staged config is identical + // to what is running, so the commit is a no-op (empty commitSha, no reload). + { + TestableConfigSession session( + sessionDir.string(), (getTestEtcDir() / "coop").string()); + (*session.getAgentConfig().sw()->ports())[0].description() = "same_desc"; + session.setCommandLine("config interface eth1/1/1 description same_desc"); + session.saveConfig( + cli::ServiceType::AGENT, cli::ConfigActionLevel::HITLESS); + auto result = session.commit(localhost()); + EXPECT_TRUE(result.commitSha.empty()) + << "re-committing an unchanged agent config should be a no-op (no reload)"; + EXPECT_EQ(result.actions.count(cli::ServiceType::AGENT), 0u) + << "unchanged agent config must not apply a reload"; + } +} + // Test that committing twice in a row - second commit should be empty TEST_F(ConfigSessionTestFixture, commitTwiceSecondIsEmpty) { fs::path sessionDir = getTestHomeDir() / ".fboss2"; @@ -1326,9 +1428,11 @@ TEST_F(ConfigSessionTestFixture, bgpConfigEditPreservesOtherSections) { EXPECT_EQ(saved["peer_groups"][0]["name"].asString(), "RACK"); // A BGP restart must be recorded so `config session commit` applies it. + // bgpd has no hitless reload, so the recorded level is AGENT_WARMBOOT (a + // plain service restart for BGP). EXPECT_EQ( session.getRequiredAction(cli::ServiceType::BGP), - cli::ConfigActionLevel::BGP_RESTART); + cli::ConfigActionLevel::AGENT_WARMBOOT); } // A staged BGP edit persists to disk and is seeded back by a fresh session via @@ -1450,7 +1554,7 @@ TEST_F(ConfigSessionTestFixture, rollbackBgpConfig) { // Re-committing a BGP config that is byte-identical to the running // /etc/coop/bgpcpp/bgpcpp.conf must be a no-op: no git commit and (crucially) -// no disruptive bgpd restart. saveBgpConfig() records BGP_RESTART +// no disruptive bgpd restart. saveBgpConfig() records a restart // unconditionally, so commit() compares staged vs running content. TEST_F(ConfigSessionTestFixture, commitUnchangedBgpConfigIsNoOp) { fs::path sessionDir = getTestHomeDir() / ".fboss2"; @@ -1481,7 +1585,7 @@ TEST_F(ConfigSessionTestFixture, commitUnchangedBgpConfigIsNoOp) { EXPECT_TRUE(result.commitSha.empty()) << "committing an unchanged BGP config should be a no-op (no restart)"; EXPECT_EQ(result.actions.count(cli::ServiceType::BGP), 0u) - << "unchanged BGP config must not apply BGP_RESTART"; + << "unchanged BGP config must not apply a bgpd restart"; } } @@ -1527,8 +1631,8 @@ TEST_F(ConfigSessionTestFixture, commitThrowsWhenRunningBgpConfigUnreadable) { // A BGP-only session (bgp_config.json + metadata present, agent.conf session // file absent) must RESUME on the next CLI invocation, not be misdetected as -// fresh -- otherwise requiredActions_ (BGP_RESTART) is cleared and the -// staged change is silently dropped at commit time. +// fresh -- otherwise requiredActions_ (the recorded bgpd restart) is cleared +// and the staged change is silently dropped at commit time. TEST_F(ConfigSessionTestFixture, bgpOnlySessionResumesAcrossInvocations) { fs::path sessionDir = getTestHomeDir() / ".fboss2"; fs::path agentSess = sessionDir / "agent.conf"; diff --git a/fboss/cli/fboss2/test/config/CmdDeleteBgpNeighborTest.cpp b/fboss/cli/fboss2/test/config/CmdDeleteBgpNeighborTest.cpp new file mode 100644 index 0000000000000..ad85ed75dfc17 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdDeleteBgpNeighborTest.cpp @@ -0,0 +1,116 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/neighbor/CmdConfigProtocolBgpNeighbor.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/neighbor/CmdDeleteProtocolBgpNeighbor.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// Deleting only touches the BGP side of ConfigSession, which seeds from +// thrift schema defaults when neither a staged session nor a system +// bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpNeighborTest). +class CmdDeleteBgpNeighborTestFixture : public CmdConfigTestBase { + public: + CmdDeleteBgpNeighborTestFixture() + : CmdConfigTestBase("bgp_neighbor_delete_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string configure(const std::vector& tokens) { + CmdConfigProtocolBgpNeighbor cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpNeighborConfig(tokens)); + } + + std::string del(const std::vector& tokens) { + CmdDeleteProtocolBgpNeighbor cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpNeighborRef(tokens)); + } + + const std::vector& peers() { + return *ConfigSession::getInstance().getBgpConfig().peers(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpNeighborRef (arg) validation +// ============================================================================== + +TEST_F(CmdDeleteBgpNeighborTestFixture, argValidation) { + // Address normalization mirrors the config command. + EXPECT_EQ(BgpNeighborRef({"2001:DB8::1"}).peerAddr(), "2001:db8::1"); + EXPECT_EQ(BgpNeighborRef({"2001:db8::/64"}).peerAddr(), "2001:db8::/64"); + + // Invalid: empty, extra tokens, bad address. + EXPECT_THROW(BgpNeighborRef({}), std::invalid_argument); + EXPECT_THROW(BgpNeighborRef({"10.0.0.1", "10.0.0.2"}), std::invalid_argument); + EXPECT_THROW(BgpNeighborRef({"not-an-ip"}), std::invalid_argument); +} + +// ============================================================================== +// queryClient +// ============================================================================== + +TEST_F(CmdDeleteBgpNeighborTestFixture, deleteExistingNeighbor) { + configure({"10.0.0.1", "remote-asn", "65000"}); + configure({"10.0.0.2", "remote-asn", "65001"}); + ASSERT_EQ(peers().size(), 2); + + auto result = del({"10.0.0.1"}); + EXPECT_THAT(result, HasSubstr("Successfully deleted BGP neighbor 10.0.0.1")); + // The other neighbor survives untouched. + ASSERT_EQ(peers().size(), 1); + EXPECT_EQ(*peers()[0].peer_addr(), "10.0.0.2"); + EXPECT_EQ(peers()[0].remote_as_4_byte().value_or(0), 65001); + EXPECT_TRUE(sessionFileExists()); +} + +TEST_F(CmdDeleteBgpNeighborTestFixture, deleteByAnySpelling) { + configure({"2001:db8::1", "remote-asn", "65000"}); + ASSERT_EQ(peers().size(), 1); + // A different spelling of the same address deletes the same peer. + auto result = del({"2001:DB8:0:0::1"}); + EXPECT_THAT(result, HasSubstr("Successfully deleted")); + EXPECT_TRUE(peers().empty()); +} + +TEST_F(CmdDeleteBgpNeighborTestFixture, deleteUnknownNeighborRejected) { + auto result = del({"192.0.2.99"}); + EXPECT_THAT(result, HasSubstr("Error: BGP neighbor 192.0.2.99 not found")); + // Nothing was persisted for the failed delete. + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected delete"; +} + +TEST_F(CmdDeleteBgpNeighborTestFixture, deleteUnknownLeavesOthersIntact) { + configure({"10.0.0.1", "remote-asn", "65000"}); + auto result = del({"10.0.0.99"}); + EXPECT_THAT(result, HasSubstr("not found")); + ASSERT_EQ(peers().size(), 1); + EXPECT_EQ(*peers()[0].peer_addr(), "10.0.0.1"); +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdDeleteBgpPeerGroupTest.cpp b/fboss/cli/fboss2/test/config/CmdDeleteBgpPeerGroupTest.cpp new file mode 100644 index 0000000000000..826e20c805127 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdDeleteBgpPeerGroupTest.cpp @@ -0,0 +1,106 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "fboss/cli/fboss2/commands/config/protocol/bgp/peer-group/CmdConfigProtocolBgpPeerGroup.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/peer-group/CmdDeleteProtocolBgpPeerGroup.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// Deleting only touches the BGP side of ConfigSession, which seeds from +// thrift schema defaults when neither a staged session nor a system +// bgpcpp.conf exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPeerGroupTest). +class CmdDeleteBgpPeerGroupTestFixture : public CmdConfigTestBase { + public: + CmdDeleteBgpPeerGroupTestFixture() + : CmdConfigTestBase("bgp_peer_group_delete_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string configure(const std::vector& tokens) { + CmdConfigProtocolBgpPeerGroup cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpPeerGroupConfig(tokens)); + } + + std::string del(const std::vector& tokens) { + CmdDeleteProtocolBgpPeerGroup cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpPeerGroupRef(tokens)); + } + + const std::vector& groups() { + return ConfigSession::getInstance().getBgpConfig().peer_groups().ensure(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpPeerGroupRef (arg) validation +// ============================================================================== + +TEST_F(CmdDeleteBgpPeerGroupTestFixture, argValidation) { + EXPECT_EQ(BgpPeerGroupRef({"SPINE"}).groupName(), "SPINE"); + + // Invalid: empty, empty name, extra tokens. + EXPECT_THROW(BgpPeerGroupRef({}), std::invalid_argument); + EXPECT_THROW(BgpPeerGroupRef({""}), std::invalid_argument); + EXPECT_THROW(BgpPeerGroupRef({"SPINE", "LEAF"}), std::invalid_argument); +} + +// ============================================================================== +// queryClient +// ============================================================================== + +TEST_F(CmdDeleteBgpPeerGroupTestFixture, deleteExistingGroup) { + configure({"SPINE", "remote-asn", "65000"}); + configure({"LEAF", "remote-asn", "65001"}); + ASSERT_EQ(groups().size(), 2); + + auto result = del({"SPINE"}); + EXPECT_THAT(result, HasSubstr("Successfully deleted BGP peer-group SPINE")); + // The other group survives untouched. + ASSERT_EQ(groups().size(), 1); + EXPECT_EQ(*groups()[0].name(), "LEAF"); + EXPECT_EQ(groups()[0].remote_as_4_byte().value_or(0), 65001); + EXPECT_TRUE(sessionFileExists()); +} + +TEST_F(CmdDeleteBgpPeerGroupTestFixture, deleteUnknownGroupRejected) { + auto result = del({"NO-SUCH-GROUP"}); + EXPECT_THAT( + result, HasSubstr("Error: BGP peer-group NO-SUCH-GROUP not found")); + // Nothing was persisted for the failed delete. + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected delete"; +} + +TEST_F(CmdDeleteBgpPeerGroupTestFixture, deleteUnknownLeavesOthersIntact) { + configure({"SPINE", "remote-asn", "65000"}); + auto result = del({"LEAF"}); + EXPECT_THAT(result, HasSubstr("not found")); + ASSERT_EQ(groups().size(), 1); + EXPECT_EQ(*groups()[0].name(), "SPINE"); +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyAsPathListTest.cpp b/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyAsPathListTest.cpp new file mode 100644 index 0000000000000..7c575a4dd51e0 --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyAsPathListTest.cpp @@ -0,0 +1,113 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/as-path-list/CmdConfigProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/as-path-list/CmdDeleteProtocolBgpPolicyAsPathList.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// Deleting only touches the BGP side of ConfigSession, which seeds from thrift +// schema defaults when neither a staged session nor a system bgpcpp.conf +// exists — so no seed agent config is needed (mirrors +// CmdConfigBgpPeerGroupTest). +class CmdDeleteBgpPolicyAsPathListTestFixture : public CmdConfigTestBase { + public: + CmdDeleteBgpPolicyAsPathListTestFixture() + : CmdConfigTestBase("bgp_aspath_list_delete_test_%%%%-%%%%-%%%%", "") {} + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string configure(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyAsPathList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpAsPathListConfig(tokens)); + } + + std::string del(const std::vector& tokens) { + CmdDeleteProtocolBgpPolicyAsPathList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpAsPathListRef(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .aspath_lists(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpAsPathListRef (arg) validation +// ============================================================================== + +TEST_F(CmdDeleteBgpPolicyAsPathListTestFixture, argValidation) { + EXPECT_EQ(BgpAsPathListRef({"AS100"}).listName(), "AS100"); + + // Invalid: empty, empty name, extra tokens. + EXPECT_THROW(BgpAsPathListRef({}), std::invalid_argument); + EXPECT_THROW(BgpAsPathListRef({""}), std::invalid_argument); + EXPECT_THROW(BgpAsPathListRef({"AS100", "AS200"}), std::invalid_argument); +} + +// ============================================================================== +// queryClient +// ============================================================================== + +TEST_F(CmdDeleteBgpPolicyAsPathListTestFixture, deleteExistingList) { + configure({"AS100", "description", "delete-me"}); + configure({"AS200", "description", "keep"}); + ASSERT_EQ(lists().size(), 2); + + auto result = del({"AS100"}); + EXPECT_THAT(result, HasSubstr("Successfully deleted BGP as-path-list AS100")); + // The other list survives untouched. + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "AS200"); + EXPECT_EQ(*lists()[0].description(), "keep"); + EXPECT_TRUE(sessionFileExists()); +} + +TEST_F(CmdDeleteBgpPolicyAsPathListTestFixture, deleteUnknownListRejected) { + auto result = del({"NO-SUCH-LIST"}); + EXPECT_THAT( + result, HasSubstr("Error: BGP as-path-list NO-SUCH-LIST not found")); + // Nothing was persisted for the failed delete. + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected delete"; +} + +TEST_F( + CmdDeleteBgpPolicyAsPathListTestFixture, + deleteUnknownLeavesOthersIntact) { + configure({"AS100", "description", "one"}); + auto result = del({"AS200"}); + EXPECT_THAT(result, HasSubstr("not found")); + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "AS100"); +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyCommunityListTest.cpp b/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyCommunityListTest.cpp new file mode 100644 index 0000000000000..23daff00d388f --- /dev/null +++ b/fboss/cli/fboss2/test/config/CmdDeleteBgpPolicyCommunityListTest.cpp @@ -0,0 +1,223 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#include +#include +#include + +#include +#include +#include +#include + +#include "configerator/structs/neteng/bgp_policy/thrift/gen-cpp2/bgp_policy_types.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/BgpCommunityListCliUtils.h" +#include "fboss/cli/fboss2/commands/config/protocol/bgp/policy/community-list/CmdConfigProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/commands/delete/protocol/bgp/policy/community-list/CmdDeleteProtocolBgpPolicyCommunityList.h" +#include "fboss/cli/fboss2/session/ConfigSession.h" +#include "fboss/cli/fboss2/test/config/CmdConfigTestBase.h" +#include "fboss/cli/fboss2/utils/HostInfo.h" + +using namespace ::testing; + +namespace facebook::fboss { + +// Deleting only touches the BGP side of ConfigSession, which seeds from thrift +// schema defaults when neither a staged session nor a system bgpcpp.conf +// exists — so no seed agent config is needed (mirrors +// CmdDeleteBgpPolicyAsPathListTest). +class CmdDeleteBgpPolicyCommunityListTestFixture : public CmdConfigTestBase { + public: + CmdDeleteBgpPolicyCommunityListTestFixture() + : CmdConfigTestBase("bgp_community_list_delete_test_%%%%-%%%%-%%%%", "") { + } + + void SetUp() override { + CmdConfigTestBase::SetUp(); + setupTestableConfigSession(); + } + + std::string configure(const std::vector& tokens) { + CmdConfigProtocolBgpPolicyCommunityList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpCommunityListConfig(tokens)); + } + + // Seed an inline Community member. The member level is its own subcommand + // (CmdConfigProtocolBgpPolicyCommunityListCommunity), which lands above this + // command in the stack — so stage it through the shared helpers rather than + // depending on that handler. + void configureCommunity( + const std::string& listName, + const std::string& communityName, + const std::string& value) { + auto& session = ConfigSession::getInstance(); + auto& list = + bgpcli::findOrCreateCommunityList(session.getBgpConfig(), listName); + bgpcli::findOrCreateCommunityMember(list, communityName).value() = value; + session.saveBgpConfig(); + } + + std::string del(const std::vector& tokens) { + CmdDeleteProtocolBgpPolicyCommunityList cmd; + HostInfo hostInfo("testhost"); + return cmd.queryClient(hostInfo, BgpCommunityListRef(tokens)); + } + + const std::vector& lists() { + return *ConfigSession::getInstance() + .getBgpConfig() + .policies() + .ensure() + .community_lists(); + } + + bool sessionFileExists() { + return std::filesystem::exists( + ConfigSession::getInstance().getBgpSessionConfigPath()); + } +}; + +// ============================================================================== +// BgpCommunityListRef (arg) validation +// ============================================================================== + +TEST_F(CmdDeleteBgpPolicyCommunityListTestFixture, argValidation) { + auto listOnly = BgpCommunityListRef({"CL100"}); + EXPECT_EQ(listOnly.listName(), "CL100"); + EXPECT_FALSE(listOnly.hasCommunity()); + + auto withMember = BgpCommunityListRef({"CL100", "community", "CM1"}); + EXPECT_EQ(withMember.listName(), "CL100"); + EXPECT_TRUE(withMember.hasCommunity()); + EXPECT_EQ(withMember.communityName(), "CM1"); + + // Invalid: empty, empty names, non-`community` second token, missing + // community name, extra tokens. + EXPECT_THROW(BgpCommunityListRef({}), std::invalid_argument); + EXPECT_THROW(BgpCommunityListRef({""}), std::invalid_argument); + EXPECT_THROW(BgpCommunityListRef({"CL100", "CL200"}), std::invalid_argument); + EXPECT_THROW( + BgpCommunityListRef({"CL100", "community"}), std::invalid_argument); + EXPECT_THROW( + BgpCommunityListRef({"CL100", "community", ""}), std::invalid_argument); + EXPECT_THROW( + BgpCommunityListRef({"CL100", "community", "CM1", "extra"}), + std::invalid_argument); +} + +// ============================================================================== +// queryClient +// ============================================================================== + +TEST_F(CmdDeleteBgpPolicyCommunityListTestFixture, deleteExistingList) { + configureCommunity("CL100", "CM1", "65000:100"); + configure({"CL200", "description", "keep"}); + ASSERT_EQ(lists().size(), 2); + + auto result = del({"CL100"}); + EXPECT_THAT( + result, HasSubstr("Successfully deleted BGP community-list CL100")); + // The other list survives untouched. + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "CL200"); + EXPECT_EQ(*lists()[0].description(), "keep"); + EXPECT_TRUE(sessionFileExists()); +} + +TEST_F(CmdDeleteBgpPolicyCommunityListTestFixture, deleteUnknownListRejected) { + auto result = del({"NO-SUCH-LIST"}); + EXPECT_THAT( + result, HasSubstr("Error: BGP community-list NO-SUCH-LIST not found")); + // Nothing was persisted for the failed delete. + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected delete"; +} + +TEST_F( + CmdDeleteBgpPolicyCommunityListTestFixture, + deleteUnknownLeavesOthersIntact) { + configure({"CL100", "description", "one"}); + auto result = del({"CL200"}); + EXPECT_THAT(result, HasSubstr("not found")); + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "CL100"); +} + +// ============================================================================== +// queryClient: single community member deletion +// ============================================================================== + +TEST_F(CmdDeleteBgpPolicyCommunityListTestFixture, deleteExistingCommunity) { + configureCommunity("CL100", "CM1", "65000:100"); + configureCommunity("CL100", "CM2", "65000:200"); + + auto result = del({"CL100", "community", "CM1"}); + EXPECT_THAT( + result, + HasSubstr("Successfully deleted BGP community-list CL100 community CM1")); + // The list and its other member survive. + ASSERT_EQ(lists().size(), 1); + ASSERT_TRUE(lists()[0].members().has_value()); + ASSERT_EQ(lists()[0].members()->size(), 1); + EXPECT_EQ(*(*lists()[0].members())[0].community_ref()->name(), "CM2"); + EXPECT_TRUE(sessionFileExists()); +} + +TEST_F( + CmdDeleteBgpPolicyCommunityListTestFixture, + deleteLastCommunityUnsetsMembers) { + configureCommunity("CL100", "CM1", "65000:100"); + + auto result = del({"CL100", "community", "CM1"}); + EXPECT_THAT(result, HasSubstr("Successfully deleted")); + // The list stays, shaped like one that never had members. + ASSERT_EQ(lists().size(), 1); + EXPECT_EQ(*lists()[0].name(), "CL100"); + EXPECT_FALSE(lists()[0].members().has_value()); +} + +TEST_F( + CmdDeleteBgpPolicyCommunityListTestFixture, + deleteUnknownCommunityRejected) { + configureCommunity("CL100", "CM1", "65000:100"); + // Consume the session file created by configure so we can assert the + // rejected delete does not persist anything new. + ASSERT_TRUE(sessionFileExists()); + + auto result = del({"CL100", "community", "NO-SUCH-COMMUNITY"}); + EXPECT_THAT( + result, + HasSubstr( + "Error: BGP community-list CL100 community NO-SUCH-COMMUNITY not " + "found")); + // The existing member is untouched. + ASSERT_EQ(lists().size(), 1); + ASSERT_TRUE(lists()[0].members().has_value()); + ASSERT_EQ(lists()[0].members()->size(), 1); + EXPECT_EQ(*(*lists()[0].members())[0].community_ref()->name(), "CM1"); +} + +TEST_F( + CmdDeleteBgpPolicyCommunityListTestFixture, + deleteCommunityFromMemberlessListRejected) { + configure({"CL100", "description", "no", "members"}); + + auto result = del({"CL100", "community", "CM1"}); + EXPECT_THAT( + result, + HasSubstr("Error: BGP community-list CL100 community CM1 not found")); + ASSERT_EQ(lists().size(), 1); + EXPECT_FALSE(lists()[0].members().has_value()); +} + +TEST_F( + CmdDeleteBgpPolicyCommunityListTestFixture, + deleteCommunityFromUnknownListRejected) { + auto result = del({"NO-SUCH-LIST", "community", "CM1"}); + EXPECT_THAT( + result, HasSubstr("Error: BGP community-list NO-SUCH-LIST not found")); + EXPECT_FALSE(sessionFileExists()) + << "session file should not exist after rejected delete"; +} + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/integration_test/BUCK b/fboss/cli/fboss2/test/integration_test/BUCK index 813575d0e1ed0..36c886c122d67 100644 --- a/fboss/cli/fboss2/test/integration_test/BUCK +++ b/fboss/cli/fboss2/test/integration_test/BUCK @@ -13,12 +13,21 @@ oncall("fboss_oss") # # Unlike the Python-based CLI tests, these C++ tests directly invoke the CLI # library code rather than spawning a subprocess. +# bazelify: extra_dep = //neteng/fboss/bgp/if:bgp_thrift cpp_binary( name = "fboss2_integration_test", srcs = [ "ConfigAclRuleTest.cpp", "ConfigAdminDistanceTest.cpp", "ConfigArpTest.cpp", + "ConfigBgpGlobalTest.cpp", + "ConfigBgpNeighborTest.cpp", + "ConfigBgpPeerGroupTest.cpp", + "ConfigBgpPolicyAsPathListEntryTest.cpp", + "ConfigBgpPolicyAsPathListTest.cpp", + "ConfigBgpPolicyCommunityListCommunityTest.cpp", + "ConfigBgpPolicyCommunityListTest.cpp", + "ConfigBgpSessionTest.cpp", "ConfigConcurrentSessionsTest.cpp", "ConfigCoppTest.cpp", "ConfigDhcpSourceOverrideTest.cpp", diff --git a/fboss/cli/fboss2/test/integration_test/BUILD.bazel b/fboss/cli/fboss2/test/integration_test/BUILD.bazel new file mode 100644 index 0000000000000..964b8cf505663 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/BUILD.bazel @@ -0,0 +1,84 @@ +# AUTO-GENERATED by bazelify.py - DO NOT EDIT +# Source: fboss/cli/fboss2/test/integration_test/BUCK + +load("@rules_cc//cc:defs.bzl", "cc_binary") + +cc_binary( + name = "fboss2_integration_test", + srcs = [ + "ConfigAclRuleTest.cpp", + "ConfigAdminDistanceTest.cpp", + "ConfigArpTest.cpp", + "ConfigBgpGlobalTest.cpp", + "ConfigBgpNeighborTest.cpp", + "ConfigBgpPeerGroupTest.cpp", + "ConfigBgpPolicyAsPathListEntryTest.cpp", + "ConfigBgpPolicyAsPathListTest.cpp", + "ConfigBgpPolicyCommunityListCommunityTest.cpp", + "ConfigBgpPolicyCommunityListTest.cpp", + "ConfigBgpPolicyPrefixListEntryTest.cpp", + "ConfigBgpPolicyPrefixListTest.cpp", + "ConfigBgpPolicyRoutingPolicyTest.cpp", + "ConfigBgpSessionTest.cpp", + "ConfigConcurrentSessionsTest.cpp", + "ConfigCoppTest.cpp", + "ConfigDhcpSourceOverrideTest.cpp", + "ConfigHostnameTest.cpp", + "ConfigIcmpV4UnavailableSrcAddrTest.cpp", + "ConfigInterfaceDescriptionTest.cpp", + "ConfigInterfaceFlowControlTest.cpp", + "ConfigInterfaceIpv6NdpTest.cpp", + "ConfigInterfaceLldpExpectedValueTest.cpp", + "ConfigInterfaceLoopbackModeTest.cpp", + "ConfigInterfaceMtuTest.cpp", + "ConfigInterfaceProfileTest.cpp", + "ConfigInterfaceSwitchportTrunkAllowedVlanTest.cpp", + "ConfigInterfaceTypeTest.cpp", + "ConfigIpRouteTest.cpp", + "ConfigL2LearningModeTest.cpp", + "ConfigLoadBalancingTest.cpp", + "ConfigMacTest.cpp", + "ConfigPfcTest.cpp", + "ConfigPortQueueConfigTest.cpp", + "ConfigPtpTest.cpp", + "ConfigReloadTest.cpp", + "ConfigQosDefaultQueueConfigTest.cpp", + "ConfigQosPolicyMapTest.cpp", + "ConfigSessionClearTest.cpp", + "ConfigCoppCpuTrafficPolicyTest.cpp", + "ConfigVlanCreateTest.cpp", + "ConfigVlanDefaultTest.cpp", + "ConfigVlanPortTaggingModeTest.cpp", + "ConfigVlanStaticMacTest.cpp", + "ConfigVlanSwitchportAccessTest.cpp", + "DeleteArpTest.cpp", + "DeleteDhcpSourceOverrideTest.cpp", + "DeleteInterfaceIpv6NdpTest.cpp", + "DeleteVlanTest.cpp", + "DeleteInterfaceTest.cpp", + "Fboss2IntegrationTest.cpp", + "TunnelIpInIpTest.cpp", + ], + deps = [ + "//fboss/agent/if:ctrl", + "//fboss/agent/platforms/common:platform_mapping", + "//fboss/agent:fboss-types", + "//fboss/agent:platform_config", + "//fboss/agent:switch_config", + "//fboss/cli/fboss2:cmd-common-utils", + "//fboss/cli/fboss2:cmd-init-utils", + "//fboss/cli/fboss2:cmd-list-config-impl-oss", + "//fboss/cli/fboss2:cmd-list-header", + "//fboss/cli/fboss2:cmd-subcommands", + "//fboss/cli/fboss2:fboss2-config-lib", + "//fboss/cli/fboss2:fboss2-lib", + "//fboss/lib/config:fboss_config_utils", + "//neteng/fboss/bgp/if:bgp_thrift", + "@CLI11//:CLI11", + "@fbthrift//:fbthrift", + "@fmt//:fmt", + "@folly//:folly", + "@googletest//:googletest", + ], + visibility = ["//visibility:public"], +) diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpGlobalTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpGlobalTest.cpp new file mode 100644 index 0000000000000..a4afe16a8f35c --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpGlobalTest.cpp @@ -0,0 +1,117 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp global `. + * + * Scope: the BGP *global* tunables only. Each positive test stages the change + * AND commits it, then asserts the value landed at the correct thrift field + * path in bgpd's own running config — fetched over its getRunningConfig RPC + * (see ConfigBgpTestBase::setAndCommit) — which proves the daemon parsed and + * adopted the promoted /etc/coop/bgpcpp/bgpcpp.conf after the commit-triggered + * restart, not merely that the CLI wrote the file. Session-lifecycle behavior + * (clear / diff / rollback / commit-restart mechanics) lives in + * ConfigBgpSessionTest. + * + * - count-confeds-in-as-path-len + * -> BgpConfig.count_confeds_in_as_path_len + * - graceful-restart-time + * -> BgpConfig.graceful_restart_convergence_seconds + * - rib-allocated-path-ids + * -> BgpConfig.bgp_setting_config.enable_rib_allocated_path_id + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; + +class ConfigBgpGlobalTest : public ConfigBgpTestBase {}; + +TEST_F(ConfigBgpGlobalTest, SetCountConfedsInAsPathLenTrue) { + auto config = setAndCommit("count-confeds-in-as-path-len", "true"); + ASSERT_TRUE(config.count("count_confeds_in_as_path_len")); + EXPECT_TRUE(config["count_confeds_in_as_path_len"].asBool()); +} + +TEST_F(ConfigBgpGlobalTest, SetCountConfedsInAsPathLenFalse) { + auto config = setAndCommit("count-confeds-in-as-path-len", "false"); + ASSERT_TRUE(config.count("count_confeds_in_as_path_len")); + EXPECT_FALSE(config["count_confeds_in_as_path_len"].asBool()); +} + +TEST_F(ConfigBgpGlobalTest, SetGracefulRestartTime) { + // Stage a value that differs from the current system config: committing an + // unchanged config is a no-op that yields no SHA, and the shipped + // bgpcpp.conf already sets 120. + int64_t target = 120; + try { + auto current = readSystemBgpConfig(); + if (current.count("graceful_restart_convergence_seconds") && + current["graceful_restart_convergence_seconds"].asInt() == target) { + target = 121; + } + } catch (const std::exception&) { + // No readable system config yet — any value is a change. + } + auto config = setAndCommit("graceful-restart-time", std::to_string(target)); + ASSERT_TRUE(config.count("graceful_restart_convergence_seconds")); + EXPECT_EQ(config["graceful_restart_convergence_seconds"].asInt(), target); + // Must not write the per-peer timer field name. + EXPECT_FALSE(config.count("graceful_restart_seconds")); +} + +TEST_F(ConfigBgpGlobalTest, SetRibAllocatedPathIdsTrue) { + auto config = setAndCommit("rib-allocated-path-ids", "true"); + ASSERT_TRUE(config.count("bgp_setting_config")); + ASSERT_TRUE( + config["bgp_setting_config"].count("enable_rib_allocated_path_id")); + EXPECT_TRUE( + config["bgp_setting_config"]["enable_rib_allocated_path_id"].asBool()); + // Must be nested, not at the top level. + EXPECT_FALSE(config.count("enable_rib_allocated_path_id")); +} + +TEST_F(ConfigBgpGlobalTest, SetRibAllocatedPathIdsFalse) { + auto config = setAndCommit("rib-allocated-path-ids", "false"); + ASSERT_TRUE(config.count("bgp_setting_config")); + ASSERT_TRUE( + config["bgp_setting_config"].count("enable_rib_allocated_path_id")); + EXPECT_FALSE( + config["bgp_setting_config"]["enable_rib_allocated_path_id"].asBool()); +} + +TEST_F(ConfigBgpGlobalTest, InvalidBoolValueRejected) { + clearBgpSession(); + auto result = runCli( + {"config", + "protocol", + "bgp", + "global", + "count-confeds-in-as-path-len", + "maybe"}); + // The handler reports the error on stdout; ensure it did not silently + // succeed and persist a bogus value. + EXPECT_THAT(result.stdout, HasSubstr("Invalid value")); + // The handler must bail out before saving, so no session file is written for + // the rejected input. + EXPECT_FALSE(std::filesystem::exists(bgpSessionPath())) + << "session file should not exist after rejected input"; +} + +TEST_F(ConfigBgpGlobalTest, NegativeGracefulRestartTimeRejected) { + clearBgpSession(); + auto result = runCli( + {"config", "protocol", "bgp", "global", "graceful-restart-time", "-1"}); + EXPECT_THAT(result.stdout, HasSubstr("non-negative")); + EXPECT_FALSE(std::filesystem::exists(bgpSessionPath())) + << "session file should not exist after rejected input"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpNeighborTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpNeighborTest.cpp new file mode 100644 index 0000000000000..be4aa208b4529 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpNeighborTest.cpp @@ -0,0 +1,130 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp neighbor + * [ ...]`. + * + * Scope: the per-neighbor attributes. Every test stages the change AND + * commits it, then asserts the value landed at the correct thrift field path + * inside the matching .peers[] entry of the promoted system config + * (/etc/coop/bgpcpp/bgpcpp.conf) and of bgpd's own running config. Stage-only + * behavior (attribute parsing, validation, rejection) is covered by the unit + * tests; an integration test that never commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only neighbor addresses, from the documentation range (RFC 3849) so +// they never collide with a real peer in the device's running BGP config. +const std::string kNeighbor = "2001:db8::1234"; +} // namespace + +class ConfigBgpNeighborTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp neighbor ` WITHOUT clearing the + // staged session, so attributes can accumulate across invocations. Returns + // the staged session JSON. + folly::dynamic stageNeighbor(const std::vector& tokens) { + std::vector args = {"config", "protocol", "bgp", "neighbor"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .peers[] entry for addr, or nullptr. + static const folly::dynamic* findPeer( + const folly::dynamic& config, + const std::string& addr) { + if (config.count("peers") == 0) { + return nullptr; + } + for (const auto& peer : config["peers"]) { + if (peer.count("peer_addr") && peer["peer_addr"].asString() == addr) { + return &peer; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpNeighborTest, SetRemoteAsnAndCommit) { + discardSession(); + clearBgpSession(); + stageNeighbor({kNeighbor, "remote-asn", "65000"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Two layers: the promoted file proves what the commit wrote; the daemon's + // getRunningConfig RPC proves bgpd parsed and adopted it after the restart. + auto config = readSystemBgpConfig(); + const auto* peer = findPeer(config, kNeighbor); + ASSERT_NE(peer, nullptr) << "committed config has no peer " << kNeighbor; + ASSERT_TRUE(peer->count("remote_as_4_byte")); + EXPECT_EQ((*peer)["remote_as_4_byte"].asInt(), 65000); + + auto running = readRunningBgpConfigViaRpc(); + const auto* runningPeer = findPeer(running, kNeighbor); + ASSERT_NE(runningPeer, nullptr) + << "bgpd's running config has no peer " << kNeighbor; + EXPECT_EQ((*runningPeer)["remote_as_4_byte"].asInt(), 65000); +} + +TEST_F(ConfigBgpNeighborTest, SetTimersHoldTimeAndCommit) { + discardSession(); + clearBgpSession(); + stageNeighbor({kNeighbor, "timers", "hold-time", "90"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Verify nested timer fields through the daemon's own view of its config. + auto running = readRunningBgpConfigViaRpc(); + const auto* peer = findPeer(running, kNeighbor); + ASSERT_NE(peer, nullptr) << "bgpd's running config has no peer " << kNeighbor; + ASSERT_TRUE(peer->count("bgp_peer_timers")); + EXPECT_EQ((*peer)["bgp_peer_timers"]["hold_time_seconds"].asInt(), 90); +} + +TEST_F(ConfigBgpNeighborTest, DeleteNeighborAndCommit) { + // Land a neighbor in the system config, then delete it through a second + // commit and verify it is gone from the promoted config. + discardSession(); + clearBgpSession(); + stageNeighbor({kNeighbor, "remote-asn", "65000"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + ASSERT_NE(findPeer(readRunningBgpConfigViaRpc(), kNeighbor), nullptr) + << "setup commit did not land the neighbor in bgpd's running config"; + + clearBgpSession(); + auto result = runCli({"delete", "protocol", "bgp", "neighbor", kNeighbor}); + EXPECT_THAT(result.stdout, HasSubstr("Successfully deleted")); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after delete commit; state=" + << bgpDaemonActiveState(); + EXPECT_EQ(findPeer(readRunningBgpConfigViaRpc(), kNeighbor), nullptr) + << "deleted neighbor still present in bgpd's running config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpPeerGroupTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpPeerGroupTest.cpp new file mode 100644 index 0000000000000..544a437efea22 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpPeerGroupTest.cpp @@ -0,0 +1,131 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp peer-group + * [ ...]`. + * + * Scope: the per-peer-group attributes. Every test stages the change AND + * commits it, then asserts the value landed at the correct thrift field path + * inside the matching .peer_groups[] entry of bgpd's running config (via + * getRunningConfig RPC). Stage-only behavior (attribute parsing, validation, + * rejection) is covered by the unit tests; an integration test that never + * commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only peer-group names, unlikely to collide with a real group in the +// device's running BGP config. +const std::string kGroup = "FBOSS2-TEST-GROUP"; +} // namespace + +class ConfigBgpPeerGroupTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp peer-group ` WITHOUT clearing the + // staged session, so attributes can accumulate across invocations. Returns + // the staged session JSON. + folly::dynamic stagePeerGroup(const std::vector& tokens) { + std::vector args = {"config", "protocol", "bgp", "peer-group"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .peer_groups[] entry named `name`, or nullptr. + static const folly::dynamic* findGroup( + const folly::dynamic& config, + const std::string& name) { + if (config.count("peer_groups") == 0) { + return nullptr; + } + for (const auto& group : config["peer_groups"]) { + if (group.count("name") && group["name"].asString() == name) { + return &group; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpPeerGroupTest, SetRemoteAsnAndCommit) { + discardSession(); + clearBgpSession(); + stagePeerGroup({kGroup, "remote-asn", "65000"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Two layers: the promoted file proves what the commit wrote; the daemon's + // getRunningConfig RPC proves bgpd parsed and adopted it after the restart. + auto config = readSystemBgpConfig(); + const auto* group = findGroup(config, kGroup); + ASSERT_NE(group, nullptr) << "committed config has no peer-group " << kGroup; + ASSERT_TRUE(group->count("remote_as_4_byte")); + EXPECT_EQ((*group)["remote_as_4_byte"].asInt(), 65000); + + auto running = readRunningBgpConfigViaRpc(); + const auto* runningGroup = findGroup(running, kGroup); + ASSERT_NE(runningGroup, nullptr) + << "bgpd's running config has no peer-group " << kGroup; + EXPECT_EQ((*runningGroup)["remote_as_4_byte"].asInt(), 65000); +} + +TEST_F(ConfigBgpPeerGroupTest, SetTimersHoldTimeAndCommit) { + discardSession(); + clearBgpSession(); + stagePeerGroup({kGroup, "timers", "hold-time", "90"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Verify nested timer fields through the daemon's own view of its config. + auto running = readRunningBgpConfigViaRpc(); + const auto* group = findGroup(running, kGroup); + ASSERT_NE(group, nullptr) + << "bgpd's running config has no peer-group " << kGroup; + ASSERT_TRUE(group->count("bgp_peer_timers")); + EXPECT_EQ((*group)["bgp_peer_timers"]["hold_time_seconds"].asInt(), 90); +} + +TEST_F(ConfigBgpPeerGroupTest, DeleteGroupAndCommit) { + // Land a peer-group in the system config, then delete it through a second + // commit and verify it is gone from bgpd's running config. + discardSession(); + clearBgpSession(); + stagePeerGroup({kGroup, "remote-asn", "65000"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + ASSERT_NE(findGroup(readRunningBgpConfigViaRpc(), kGroup), nullptr) + << "setup commit did not land the peer-group in bgpd's running config"; + + clearBgpSession(); + auto result = runCli({"delete", "protocol", "bgp", "peer-group", kGroup}); + EXPECT_THAT(result.stdout, HasSubstr("Successfully deleted")); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after delete commit; state=" + << bgpDaemonActiveState(); + EXPECT_EQ(findGroup(readRunningBgpConfigViaRpc(), kGroup), nullptr) + << "deleted peer-group still present in bgpd's running config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListEntryTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListEntryTest.cpp new file mode 100644 index 0000000000000..13c374ef60894 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListEntryTest.cpp @@ -0,0 +1,127 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp policy as-path-list + * entry [ ...]`. + * + * Scope: the entry level. Every test stages the change AND commits it, then + * asserts the value landed at the correct thrift field path inside the + * matching .policies.aspath_lists[].as_path_list[] entry of bgpd's running + * config (via getRunningConfig RPC). Stage-only behavior (attribute parsing, + * validation, rejection) is covered by the unit tests; an integration test + * that never commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only AS-path-list name, unlikely to collide with a real list in the +// device's running BGP config. +const std::string kList = "FBOSS2-TEST-ASPATH-ENTRY"; +} // namespace + +class ConfigBgpPolicyAsPathListEntryTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp policy as-path-list entry ` + // WITHOUT clearing the staged session, so attributes can accumulate across + // invocations. Returns the staged session JSON. + folly::dynamic stageEntry(const std::vector& tokens) { + std::vector args = { + "config", "protocol", "bgp", "policy", "as-path-list", kList, "entry"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .policies.aspath_lists[] entry named `name`, or nullptr. + static const folly::dynamic* findList( + const folly::dynamic& config, + const std::string& name) { + if (config.count("policies") == 0 || + config["policies"].count("aspath_lists") == 0) { + return nullptr; + } + for (const auto& list : config["policies"]["aspath_lists"]) { + if (list.count("name") && list["name"].asString() == name) { + return &list; + } + } + return nullptr; + } + + // The .as_path_list[] entry with sequence_number `seq` inside `list`, or + // nullptr. + static const folly::dynamic* findEntry( + const folly::dynamic& list, + int64_t seq) { + if (list.count("as_path_list") == 0) { + return nullptr; + } + for (const auto& entry : list["as_path_list"]) { + if (entry.count("sequence_number") && + entry["sequence_number"].asInt() == seq) { + return &entry; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpPolicyAsPathListEntryTest, SetEntryAsnRegexpAndCommit) { + discardSession(); + clearBgpSession(); + stageEntry({"10", "asn-regexp", "^65000_"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Verify the nested union path .as_path.as_path.asn_regexp through the + // daemon's own view of its config — which also confirms the entry + // subcommand's implicit creation of its parent list reaches bgpd. + auto running = readRunningBgpConfigViaRpc(); + const auto* list = findList(running, kList); + ASSERT_NE(list, nullptr) << "bgpd's running config has no as-path-list " + << kList; + const auto* entry = findEntry(*list, 10); + ASSERT_NE(entry, nullptr) << "running config has no entry 10"; + EXPECT_EQ((*entry)["as_path"]["as_path"]["asn_regexp"].asString(), "^65000_"); +} + +TEST_F(ConfigBgpPolicyAsPathListEntryTest, SetEntryMatchLogicAndCommit) { + discardSession(); + clearBgpSession(); + stageEntry({"20", "asn-regexp", "^65001_"}); + stageEntry({"20", "match-logic", "NOT_EQUAL"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + auto running = readRunningBgpConfigViaRpc(); + const auto* list = findList(running, kList); + ASSERT_NE(list, nullptr) << "bgpd's running config has no as-path-list " + << kList; + const auto* entry = findEntry(*list, 20); + ASSERT_NE(entry, nullptr) << "running config has no entry 20"; + // Enums ride the SimpleJSON wire format as integers: + // routing_policy.MatchValueLogicOperator.NOT_EQUAL = 1. + EXPECT_EQ((*entry)["match_logic_type"].asInt(), 1); +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListTest.cpp new file mode 100644 index 0000000000000..62fb1bc07cb11 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyAsPathListTest.cpp @@ -0,0 +1,118 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp policy as-path-list + * [ ...]`. + * + * Scope: the AS-path list level (its entries are covered by + * ConfigBgpPolicyAsPathListEntryTest). Every test stages the change AND + * commits it, then asserts the value landed at the correct thrift field path + * inside the matching .policies.aspath_lists[] entry of bgpd's running config + * (via getRunningConfig RPC) — which also confirms bgpd accepts and adopts a + * `.policies` blob at all. Stage-only behavior (attribute parsing, + * validation, rejection) is covered by the unit tests; an integration test + * that never commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only AS-path-list names, unlikely to collide with a real list in the +// device's running BGP config. +const std::string kList = "FBOSS2-TEST-ASPATH"; +} // namespace + +class ConfigBgpPolicyAsPathListTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp policy as-path-list ` WITHOUT + // clearing the staged session, so attributes can accumulate across + // invocations. Returns the staged session JSON. + folly::dynamic stageAsPathList(const std::vector& tokens) { + std::vector args = { + "config", "protocol", "bgp", "policy", "as-path-list"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .policies.aspath_lists[] entry named `name`, or nullptr. + static const folly::dynamic* findList( + const folly::dynamic& config, + const std::string& name) { + if (config.count("policies") == 0 || + config["policies"].count("aspath_lists") == 0) { + return nullptr; + } + for (const auto& list : config["policies"]["aspath_lists"]) { + if (list.count("name") && list["name"].asString() == name) { + return &list; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpPolicyAsPathListTest, SetListDescriptionAndCommit) { + discardSession(); + clearBgpSession(); + stageAsPathList({kList, "description", "test", "spine", "as-paths"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Two layers: the promoted file proves what the commit wrote; the daemon's + // getRunningConfig RPC proves bgpd parsed and adopted the .policies blob. + auto config = readSystemBgpConfig(); + const auto* list = findList(config, kList); + ASSERT_NE(list, nullptr) << "committed config has no as-path-list " << kList; + EXPECT_EQ((*list)["description"].asString(), "test spine as-paths"); + + auto running = readRunningBgpConfigViaRpc(); + const auto* runningList = findList(running, kList); + ASSERT_NE(runningList, nullptr) + << "bgpd's running config has no as-path-list " << kList; + EXPECT_EQ((*runningList)["description"].asString(), "test spine as-paths"); +} + +TEST_F(ConfigBgpPolicyAsPathListTest, DeleteListAndCommit) { + // Land an as-path-list in the system config, then delete it through a second + // commit and verify it is gone from bgpd's running config. + discardSession(); + clearBgpSession(); + stageAsPathList({kList, "description", "delete-me"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + ASSERT_NE(findList(readRunningBgpConfigViaRpc(), kList), nullptr) + << "setup commit did not land the as-path-list in bgpd's running config"; + + clearBgpSession(); + auto result = + runCli({"delete", "protocol", "bgp", "policy", "as-path-list", kList}); + EXPECT_THAT(result.stdout, HasSubstr("Successfully deleted")); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after delete commit; state=" + << bgpDaemonActiveState(); + EXPECT_EQ(findList(readRunningBgpConfigViaRpc(), kList), nullptr) + << "deleted as-path-list still present in bgpd's running config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListCommunityTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListCommunityTest.cpp new file mode 100644 index 0000000000000..8b06618521fc9 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListCommunityTest.cpp @@ -0,0 +1,174 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp policy community-list + * community [ ...]`. + * + * Scope: the inline community-member level. Every test stages the change AND + * commits it, then asserts the value landed at the correct thrift field path + * inside the matching .policies.community_lists[].members[] entry of bgpd's + * running config (via getRunningConfig RPC). Stage-only behavior (attribute + * parsing, validation, rejection) is covered by the unit tests; an integration + * test that never commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only community-list / member names, unlikely to collide with a real +// list in the device's running BGP config. +const std::string kList = "FBOSS2-TEST-COMMUNITY-MEMBER"; +const std::string kMember = "FBOSS2-TEST-CM1"; +const std::string kMember2 = "FBOSS2-TEST-CM2"; +} // namespace + +class ConfigBgpPolicyCommunityListCommunityTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp policy community-list community + // ` WITHOUT clearing the staged session, so attributes can + // accumulate across invocations. Returns the staged session JSON. + folly::dynamic stageCommunity(const std::vector& tokens) { + std::vector args = { + "config", + "protocol", + "bgp", + "policy", + "community-list", + kList, + "community"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .policies.community_lists[] entry named `name`, or nullptr. + static const folly::dynamic* findList( + const folly::dynamic& config, + const std::string& name) { + if (config.count("policies") == 0 || + config["policies"].count("community_lists") == 0) { + return nullptr; + } + for (const auto& list : config["policies"]["community_lists"]) { + if (list.count("name") && list["name"].asString() == name) { + return &list; + } + } + return nullptr; + } + + // The inline Community held by a .members[] entry named `name`, or nullptr. + static const folly::dynamic* findMember( + const folly::dynamic& list, + const std::string& name) { + if (list.count("members") == 0) { + return nullptr; + } + for (const auto& member : list["members"]) { + if (member.count("community") && member["community"].count("name") && + member["community"]["name"].asString() == name) { + return &member["community"]; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpPolicyCommunityListCommunityTest, SetAttributesAndCommit) { + discardSession(); + clearBgpSession(); + stageCommunity({kMember, "value", "65000:100"}); + stageCommunity({kMember, "type", "NORMAL"}); + stageCommunity({kMember, "description", "test"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Verify the nested member path .members[].community.{value,type, + // description} through the daemon's own view of its config — which also + // confirms the community subcommand's implicit creation of its parent list + // reaches bgpd. + auto running = readRunningBgpConfigViaRpc(); + const auto* list = findList(running, kList); + ASSERT_NE(list, nullptr) << "bgpd's running config has no community-list " + << kList; + const auto* community = findMember(*list, kMember); + ASSERT_NE(community, nullptr) + << "running config has no member community " << kMember; + EXPECT_EQ((*community)["value"].asString(), "65000:100"); + // bgp_policy.CommunityType.NORMAL = 1 (integer on the SimpleJSON wire). + EXPECT_EQ((*community)["type"].asInt(), 1); + EXPECT_EQ((*community)["description"].asString(), "test"); +} + +TEST_F(ConfigBgpPolicyCommunityListCommunityTest, DeleteCommunityAndCommit) { + // Land a community-list with two inline members, delete one member through + // a second commit, and verify the list and the other member survive in + // bgpd's running config. + discardSession(); + clearBgpSession(); + stageCommunity({kMember, "value", "65000:100"}); + stageCommunity({kMember2, "value", "65000:200"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + { + auto running = readRunningBgpConfigViaRpc(); + const auto* list = findList(running, kList); + ASSERT_NE(list, nullptr) + << "setup commit did not land the community-list in bgpd's running " + "config"; + ASSERT_NE(findMember(*list, kMember), nullptr); + ASSERT_NE(findMember(*list, kMember2), nullptr); + } + + clearBgpSession(); + auto result = runCli( + {"delete", + "protocol", + "bgp", + "policy", + "community-list", + kList, + "community", + kMember}); + EXPECT_THAT( + result.stdout, + HasSubstr( + fmt::format( + "Successfully deleted BGP community-list {} community {}", + kList, + kMember))); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after delete commit; state=" + << bgpDaemonActiveState(); + auto running = readRunningBgpConfigViaRpc(); + const auto* list = findList(running, kList); + ASSERT_NE(list, nullptr) + << "deleting one member must not delete the community-list"; + EXPECT_EQ(findMember(*list, kMember), nullptr) + << "deleted member still present in bgpd's running config"; + EXPECT_NE(findMember(*list, kMember2), nullptr) + << "surviving member missing from bgpd's running config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListTest.cpp new file mode 100644 index 0000000000000..7a30d7425dcc1 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpPolicyCommunityListTest.cpp @@ -0,0 +1,126 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for `fboss2-dev config protocol bgp policy community-list + * [ ...]`. + * + * Scope: the community-list level (its inline community members are covered by + * ConfigBgpPolicyCommunityListCommunityTest). Every test + * stages the change AND commits it, then asserts the value landed at the + * correct thrift field path inside the matching .policies.community_lists[] + * entry of bgpd's running config (via getRunningConfig RPC) — which also + * confirms bgpd accepts and adopts a `.policies` blob at all. Stage-only + * behavior (attribute parsing, validation, rejection) is covered by the unit + * tests; an integration test that never commits exercises no daemon. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd is installed/active (commit restarts it). + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" +#include "folly/json/dynamic.h" +#include "gmock/gmock.h" + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +namespace { +// Test-only community-list name, unlikely to collide with a real list in the +// device's running BGP config. +const std::string kList = "FBOSS2-TEST-COMMUNITY"; +} // namespace + +class ConfigBgpPolicyCommunityListTest : public ConfigBgpTestBase { + protected: + // Stage `config protocol bgp policy community-list ` WITHOUT + // clearing the staged session, so attributes can accumulate across + // invocations. Returns the staged session JSON. + folly::dynamic stageCommunityList(const std::vector& tokens) { + std::vector args = { + "config", "protocol", "bgp", "policy", "community-list"}; + args.insert(args.end(), tokens.begin(), tokens.end()); + auto result = runCli(args); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // The .policies.community_lists[] entry named `name`, or nullptr. + static const folly::dynamic* findList( + const folly::dynamic& config, + const std::string& name) { + if (config.count("policies") == 0 || + config["policies"].count("community_lists") == 0) { + return nullptr; + } + for (const auto& list : config["policies"]["community_lists"]) { + if (list.count("name") && list["name"].asString() == name) { + return &list; + } + } + return nullptr; + } +}; + +TEST_F(ConfigBgpPolicyCommunityListTest, SetListAttributesAndCommit) { + discardSession(); + clearBgpSession(); + stageCommunityList({kList, "description", "test", "spine", "communities"}); + stageCommunityList({kList, "boolean-operator", "AND"}); + stageCommunityList({kList, "exact-match", "true"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + // Two layers: the promoted file proves what the commit wrote; the daemon's + // getRunningConfig RPC proves bgpd parsed and adopted the .policies blob. + auto config = readSystemBgpConfig(); + const auto* list = findList(config, kList); + ASSERT_NE(list, nullptr) << "committed config has no community-list " + << kList; + EXPECT_EQ((*list)["description"].asString(), "test spine communities"); + + auto running = readRunningBgpConfigViaRpc(); + const auto* runningList = findList(running, kList); + ASSERT_NE(runningList, nullptr) + << "bgpd's running config has no community-list " << kList; + EXPECT_EQ((*runningList)["description"].asString(), "test spine communities"); + // Enums ride the SimpleJSON wire format as integers: + // routing_policy.BooleanOperator.AND = 1. + EXPECT_EQ((*runningList)["boolean_operator"].asInt(), 1); + EXPECT_TRUE((*runningList)["exact_match"].asBool()); +} + +TEST_F(ConfigBgpPolicyCommunityListTest, DeleteListAndCommit) { + // Land a community-list in the system config, then delete it through a + // second commit and verify it is gone from bgpd's running config. + discardSession(); + clearBgpSession(); + stageCommunityList({kList, "description", "delete-me"}); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + ASSERT_NE(findList(readRunningBgpConfigViaRpc(), kList), nullptr) + << "setup commit did not land the community-list in bgpd's running " + "config"; + + clearBgpSession(); + auto result = + runCli({"delete", "protocol", "bgp", "policy", "community-list", kList}); + EXPECT_THAT(result.stdout, HasSubstr("Successfully deleted")); + commitAndGetSha(); + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after delete commit; state=" + << bgpDaemonActiveState(); + EXPECT_EQ(findList(readRunningBgpConfigViaRpc(), kList), nullptr) + << "deleted community-list still present in bgpd's running config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpSessionTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigBgpSessionTest.cpp new file mode 100644 index 0000000000000..d4595f1beb188 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpSessionTest.cpp @@ -0,0 +1,218 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +/** + * End-to-end tests for BGP config *session* management, mirroring the agent + * config session tests (e.g. ConfigSessionClearTest) but for the BGP domain. + * + * BGP global edits stage ~/.fboss2/bgp_config.json (no agent.conf), and + * `config session commit` promotes it to /etc/coop/bgpcpp/bgpcpp.conf and + * restarts bgpd. These tests exercise the session lifecycle around that: + * - clear (including a BGP-only session) + * - diff (a staged BGP change must be visible) + * - commit (bgpd is restarted) + * - rollback (the bgpd system config is restored) + * + * Per-attribute global config behavior lives in ConfigBgpGlobalTest. + * + * Requirements: + * - The fboss2-dev binary under test (config subcommand tree). + * - HOME is set (the session file lives under $HOME/.fboss2). + * - bgpd installed; commit/rollback tests skip if bgpd is not active. + */ + +#include +#include +#include + +#include "fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h" + +namespace fs = std::filesystem; + +using namespace facebook::fboss; +using ::testing::HasSubstr; +using ::testing::Not; + +class ConfigBgpSessionTest : public ConfigBgpTestBase {}; + +// Staging a BGP global change creates a session file; `config session clear` +// removes it (a BGP-only session has no agent.conf to key off of). +TEST_F(ConfigBgpSessionTest, CreateAndClearBgpSession) { + runBgpGlobal("graceful-restart-time", "55"); + ASSERT_TRUE(fs::exists(bgpSessionPath())) + << "expected a staged BGP session after a global change"; + + auto result = runCli({"config", "session", "clear"}); + ASSERT_EQ(result.exitCode, 0) << "stderr=" << result.stderr; + + EXPECT_FALSE(fs::exists(bgpSessionPath())) + << "config session clear must remove the staged BGP config"; +} + +TEST_F(ConfigBgpSessionTest, ClearNonExistentBgpSession) { + // Start fully clean: no agent session, no BGP session, no metadata. + discardSession(); + clearBgpSession(); + + auto result = runCli({"config", "session", "clear"}); + ASSERT_EQ(result.exitCode, 0) << "stderr=" << result.stderr; + EXPECT_THAT(result.stdout, HasSubstr("No config session exists")); +} + +// `config session diff` must surface a staged BGP global change. +TEST_F(ConfigBgpSessionTest, DiffShowsStagedBgpChange) { + runBgpGlobal("graceful-restart-time", "77"); + + auto result = runCli({"config", "session", "diff"}); + ASSERT_EQ(result.exitCode, 0) << "stderr=" << result.stderr; + EXPECT_THAT(result.stdout, Not(HasSubstr("No config session exists"))); + EXPECT_THAT(result.stdout, HasSubstr("graceful_restart_convergence_seconds")); +} + +// Committing a staged BGP change restarts the bgpd daemon. +TEST_F(ConfigBgpSessionTest, CommitRestartsBgpDaemon) { + if (bgpDaemonActiveState() != "active") { + GTEST_SKIP() << "bgpd is not active on this DUT; skipping commit/restart " + "verification"; + } + discardSession(); + const std::string pidBefore = bgpDaemonMainPid(); + + runBgpGlobal("graceful-restart-time", "123"); + ASSERT_FALSE(commitAndGetSha().empty()); + + EXPECT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return to active after commit; state=" + << bgpDaemonActiveState(); + + const std::string pidAfter = bgpDaemonMainPid(); + EXPECT_NE(pidAfter, "0") << "bgpd has no MainPID after commit"; + EXPECT_NE(pidAfter, pidBefore) << "bgpd MainPID unchanged (" << pidBefore + << "); expected a restart on commit"; +} + +// Rolling back a committed BGP change restores the bgpd system config and +// restarts bgpd (not just the agent config). +TEST_F(ConfigBgpSessionTest, RollbackRestoresBgpConfig) { + if (bgpDaemonActiveState() != "active") { + GTEST_SKIP() << "bgpd is not active on this DUT; skipping rollback " + "verification"; + } + discardSession(); + + auto convergenceSeconds = [&]() { + return readSystemBgpConfig()["graceful_restart_convergence_seconds"] + .asInt(); + }; + + // Commit A (111), then commit B (222). + runBgpGlobal("graceful-restart-time", "111"); + std::string shaA = commitAndGetSha(); + ASSERT_FALSE(shaA.empty()) << "could not parse commit A sha"; + ASSERT_TRUE(waitForBgpDaemonActive()); + + runBgpGlobal("graceful-restart-time", "222"); + ASSERT_FALSE(commitAndGetSha().empty()) << "could not parse commit B sha"; + ASSERT_TRUE(waitForBgpDaemonActive()); + + EXPECT_EQ(convergenceSeconds(), 222) + << "system bgp config should reflect the latest commit"; + + // Roll back to commit A -> system bgp config restored to 111, bgpd restart. + resetBgpDaemonLimit(); // avoid systemd start-limit on the rollback's restart + auto rb = runCli({"config", "rollback", shaA}); + EXPECT_EQ(rb.exitCode, 0) << "stderr=" << rb.stderr; + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after rollback"; + + EXPECT_EQ(convergenceSeconds(), 111) + << "rollback must restore the bgpd system config"; +} + +// Committing a BGP config identical to what is already running must be a no-op: +// "Nothing to commit" and, crucially, NO bgpd restart (a restart is traffic +// affecting). saveBgpConfig() always records BGP_RESTART, so commit() has to +// compare the staged config against the running one. +TEST_F(ConfigBgpSessionTest, CommitUnchangedBgpConfigDoesNotRestart) { + if (bgpDaemonActiveState() != "active") { + GTEST_SKIP() << "bgpd is not active on this DUT; skipping no-op restart " + "verification"; + } + discardSession(); + + // Establish a known running value. + runBgpGlobal("graceful-restart-time", "88"); + ASSERT_FALSE(commitAndGetSha().empty()); + ASSERT_TRUE(waitForBgpDaemonActive()); + const std::string pidBefore = bgpDaemonMainPid(); + ASSERT_NE(pidBefore, "0"); + + // Stage the SAME value and commit again -> nothing to commit, no restart. + runBgpGlobal("graceful-restart-time", "88"); + auto result = runCli({"config", "session", "commit"}); + EXPECT_EQ(result.exitCode, 0) << "stderr=" << result.stderr; + EXPECT_THAT(result.stdout, HasSubstr("Nothing to commit")) + << "an unchanged BGP commit should report nothing to commit"; + + EXPECT_EQ(bgpDaemonMainPid(), pidBefore) + << "bgpd was restarted for an unchanged BGP config (pidBefore=" + << pidBefore << ")"; +} + +// An agent-only commit (no BGP staged) must still snapshot the running bgpd +// config, so a rollback to it restores BGP instead of wiping it. Pre-fix, +// bgpcpp.conf was untracked at such commits and rollback deleted it. +TEST_F(ConfigBgpSessionTest, AgentCommitSnapshotsBgpAndRollbackPreservesIt) { + if (bgpDaemonActiveState() != "active") { + GTEST_SKIP() << "bgpd is not active on this DUT; skipping cross-domain " + "rollback verification"; + } + discardSession(); + clearBgpSession(); + + // The running (default) BGP config that must survive a rollback unchanged. + ASSERT_TRUE(fs::exists(systemBgpConfigPath())) + << "expected a running bgpd config on an active-BGP DUT"; + const folly::dynamic defaultBgp = readSystemBgpConfig(); + + // Step 1: an agent-only commit (interface description). No BGP is staged. + Interface intf = findFirstEthInterface(); + auto setRes = + runCli({"config", "interface", intf.name, "description", "bgp-rb-test"}); + ASSERT_EQ(setRes.exitCode, 0) << "stderr=" << setRes.stderr; + ASSERT_FALSE(fs::exists(bgpSessionPath())) + << "an interface-description change must not stage a BGP session"; + resetBgpDaemonLimit(); + commitConfig(); + waitForAgentReady(); + const std::string agentSha = gitHead(); + ASSERT_FALSE(agentSha.empty()) + << "could not read git HEAD after agent commit"; + + // The fix: bgpcpp.conf must be tracked at the agent-only commit, so a later + // rollback to it has a faithful BGP snapshot to restore. + EXPECT_TRUE(bgpTrackedAtRevision(agentSha)) + << "agent-only commit " << agentSha + << " did not snapshot bgpcpp.conf; a rollback to it would wipe BGP"; + + // Step 2: stage + commit a BGP change so the running config diverges from the + // snapshot captured at agentSha. + runBgpGlobal("graceful-restart-time", "222"); + ASSERT_FALSE(commitAndGetSha().empty()) << "BGP commit produced no SHA"; + ASSERT_TRUE(waitForBgpDaemonActive()); + EXPECT_EQ( + readSystemBgpConfig()["graceful_restart_convergence_seconds"].asInt(), + 222); + + // Step 3: roll back to the agent-only commit. BGP must be RESTORED to the + // original default snapshot (not deleted), and bgpd must come back. + resetBgpDaemonLimit(); + auto rb = runCli({"config", "rollback", agentSha}); + EXPECT_EQ(rb.exitCode, 0) << "stderr=" << rb.stderr; + ASSERT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after rollback"; + + EXPECT_TRUE(fs::exists(systemBgpConfigPath())) + << "rollback to an agent-era commit wiped the running bgpd config"; + EXPECT_EQ(readSystemBgpConfig(), defaultBgp) + << "rollback did not restore the original (default) bgpd config"; +} diff --git a/fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h b/fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h new file mode 100644 index 0000000000000..0bc0b39513965 --- /dev/null +++ b/fboss/cli/fboss2/test/integration_test/ConfigBgpTestBase.h @@ -0,0 +1,372 @@ +// (c) Meta Platforms, Inc. and affiliates. Confidential and proprietary. + +#pragma once + +/** + * Shared fixture + helpers for BGP config integration tests. + * + * BGP config is not pushed into the agent's running config like the + * SwitchConfig-backed commands. Instead the CLI stages a BGP++ + * thrift-compatible JSON file at ~/.fboss2/bgp_config.json; `config session + * commit` promotes it to /etc/coop/bgpcpp/bgpcpp.conf and restarts the bgpd + * daemon. These helpers let the global-attribute tests and the + * session-lifecycle tests share the staging, commit, daemon-state, and + * system-config plumbing. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "fboss/cli/fboss2/test/integration_test/Fboss2IntegrationTest.h" +#include "fboss/cli/fboss2/utils/CmdClientUtilsCommon.h" +#include "neteng/fboss/bgp/if/gen-cpp2/TBgpService.h" + +namespace facebook::fboss { + +class ConfigBgpTestBase : public Fboss2IntegrationTest { + protected: + void SetUp() override { + Fboss2IntegrationTest::SetUp(); + if (bgpDaemonActiveState() != "active") { + GTEST_SKIP() << "skipping because bgp is not active"; + } + // Snapshot the config bgpd runs with; TearDown restores it, so committed + // test objects never outlive the test regardless of where it failed. + haveBgpSnapshot_ = folly::readFile(kBgpDaemonConfigPath, bgpSnapshot_); + if (haveBgpSnapshot_) { + bgpSnapshotConfig_ = parseBgpConfig(bgpSnapshot_); + } + } + + void TearDown() override { + restoreBgpConfigSnapshot(); + Fboss2IntegrationTest::TearDown(); + } + + // Staged session file written by the CLI (~/.fboss2/bgp_config.json). + std::string bgpSessionPath() const { + // NOLINTNEXTLINE(concurrency-mt-unsafe): HOME is read-only in practice + const char* home = std::getenv("HOME"); + if (home == nullptr) { + throw std::runtime_error("HOME environment variable not set"); + } + return std::string(home) + "/.fboss2/bgp_config.json"; + } + + // System config consumed by the bgpd daemon (written on commit). + std::string systemBgpConfigPath() const { + return "/etc/coop/bgpcpp/bgpcpp.conf"; + } + + // Remove any pre-existing staged BGP session so each test starts clean. + void clearBgpSession() const { + std::remove(bgpSessionPath().c_str()); + } + + folly::dynamic readBgpSessionConfig() const { + std::string content; + if (!folly::readFile(bgpSessionPath().c_str(), content)) { + throw std::runtime_error( + "Failed to read BGP session config at " + bgpSessionPath()); + } + return folly::parseJson(content); + } + + folly::dynamic readSystemBgpConfig() const { + std::string content; + if (!folly::readFile(systemBgpConfigPath().c_str(), content)) { + const int promotedErrno = errno; + // On a box where no BGP commit ever happened, the promoted + // bgpcpp/bgpcpp.conf doesn't exist yet; the effective config is the + // plain file the RPM installed at /etc/coop/bgpcpp.conf (a symlink to + // the promoted file afterwards, so it is always safe to read). + if (promotedErrno != ENOENT) { + throw std::runtime_error( + "Failed to read system BGP config at " + systemBgpConfigPath() + + ": " + folly::errnoStr(promotedErrno)); + } + if (!folly::readFile(kBgpDaemonConfigPath, content)) { + throw std::runtime_error( + "Failed to read system BGP config: " + systemBgpConfigPath() + + " does not exist and reading " + kBgpDaemonConfigPath + + " failed: " + folly::errnoStr(errno)); + } + } + return folly::parseJson(content); + } + + // The running config as reported by the bgpd daemon itself, over its + // TBgpService::getRunningConfig thrift RPC. Unlike readSystemBgpConfig() + // (the promoted file on disk, which only proves what the CLI wrote), this + // proves the daemon parsed and adopted the config after the post-commit + // restart. Mirrors Fboss2IntegrationTest::getRunningConfig() for the agent. + // + // Retries on connection errors: systemd reports bgpd "active" as soon as + // the process starts, but the thrift server only binds its port a few + // seconds later — an RPC issued right after a commit-triggered restart + // would otherwise race that window and get ECONNREFUSED. + folly::dynamic readRunningBgpConfigViaRpc( + std::chrono::seconds timeout = std::chrono::seconds(90)) const { + auto deadline = std::chrono::steady_clock::now() + timeout; + HostInfo hostInfo("localhost"); + std::string configStr; + while (true) { + try { + auto client = utils::createClient>(hostInfo); + client->sync_getRunningConfig(configStr); + break; + } catch (const std::exception& ex) { + // A NOT_OPEN transport exception (connect refused / connection + // closed) is the expected bind-window race; any other RPC error is + // worth surfacing even though we keep retrying until the deadline. + // The refused connect reaches us as a channel-level + // TTransportException wrapping the socket error, so the inner errno + // is gone but the NOT_OPEN type survives. + const auto* tex = + dynamic_cast( + &ex); + if (tex == nullptr || + tex->getType() != + apache::thrift::transport::TTransportException::NOT_OPEN) { + XLOG(WARN) << "BGP getRunningConfig failed with an unexpected " + "error (not a connection refused error): " + << ex.what(); + } + if (std::chrono::steady_clock::now() >= deadline) { + throw; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + } + return folly::parseJson(configStr); + } + + // Root of the git repo that versions both the agent config (cli/agent.conf) + // and the BGP config (bgpcpp/bgpcpp.conf). + std::string coopRepoDir() const { + return "/etc/coop"; + } + + // Current git HEAD sha of the /etc/coop repo (trimmed; "" on failure). + // runCmd uses folly::Subprocess, which does not search PATH, so git is + // invoked by full path. -c safe.directory mirrors the CLI's Git class: + // /etc/coop is typically owned by another user (e.g. coop), which git + // otherwise rejects as dubious ownership. + std::string gitHead() const { + auto r = runCmd( + {"/usr/bin/git", + "-c", + "safe.directory=" + coopRepoDir(), + "-C", + coopRepoDir(), + "rev-parse", + "HEAD"}); + std::string s = r.stdout; + while (!s.empty() && + (s.back() == '\n' || s.back() == '\r' || s.back() == ' ')) { + s.pop_back(); + } + return s; + } + + // True if bgpcpp/bgpcpp.conf is tracked (present in the tree) at the given + // revision. `git cat-file -e :` exits 0 iff the blob exists. + bool bgpTrackedAtRevision(const std::string& sha) const { + auto r = runCmd( + {"/usr/bin/git", + "-c", + "safe.directory=" + coopRepoDir(), + "-C", + coopRepoDir(), + "cat-file", + "-e", + sha + ":bgpcpp/bgpcpp.conf"}); + return r.exitCode == 0; + } + + // Stage a `config protocol bgp global ` change (no commit). + // Returns the staged session JSON. + folly::dynamic runBgpGlobal(const std::string& attr, const std::string& value) + const { + clearBgpSession(); + XLOG(INFO) << "Running: config protocol bgp global " << attr << " " + << value; + auto result = runCli({"config", "protocol", "bgp", "global", attr, value}); + EXPECT_EQ(result.exitCode, 0) + << "stdout=" << result.stdout << " stderr=" << result.stderr; + // Handler error strings are printed to stdout with exit code 0, so guard + // against silent failures by rejecting an "Error" prefix. + EXPECT_THAT(result.stdout, ::testing::Not(::testing::HasSubstr("Error:"))); + return readBgpSessionConfig(); + } + + // Reset bgpd's systemd start-limit burst counter. Tests commit several + // times in quick succession, and each commit restarts bgpd; without this, + // systemd's default StartLimitBurst (5 starts / 10s) refuses a rapid restart + // with "start limit hit" — a test artifact, not a product issue. + void resetBgpDaemonLimit() const { + runCmd({"/usr/bin/systemctl", "reset-failed", "bgpd"}); + } + + // Run `config session commit` and return the short SHA parsed from + // "Config session committed successfully as ". Empty string on failure. + std::string commitAndGetSha() const { + resetBgpDaemonLimit(); + auto r = runCli({"config", "session", "commit"}); + EXPECT_EQ(r.exitCode, 0) << "stderr=" << r.stderr; + const std::string marker = "as "; + auto pos = r.stdout.find(marker); + if (pos == std::string::npos) { + return ""; + } + pos += marker.size(); + auto end = r.stdout.find_first_of(" .\n", pos); + return r.stdout.substr(pos, end - pos); + } + + // Stage a global change, commit it, wait for bgpd to come back, and return + // bgpd's own running config as reported over its getRunningConfig RPC. + // + // The returned config is the daemon's adopted view, which is strictly + // stronger than the promoted file on disk (readSystemBgpConfig): a value + // present here proves the commit promoted /etc/coop/bgpcpp/bgpcpp.conf AND + // that bgpd parsed and adopted it after the commit-triggered restart, not + // merely that the CLI wrote the file. The running config shares the same + // BgpConfig JSON schema as the promoted file, so callers assert the same + // field paths against it. + // + // A no-op commit (staged value already current) yields no SHA and is fine: + // the caller's assertions on the returned config still verify the value; + // commit/restart mechanics are covered by ConfigBgpSessionTest. + folly::dynamic setAndCommit(const std::string& attr, const std::string& value) + const { + discardSession(); + runBgpGlobal(attr, value); + commitAndGetSha(); + EXPECT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after commit; state=" + << bgpDaemonActiveState(); + return readRunningBgpConfigViaRpc(); + } + + // Trailing-whitespace-trimmed stdout of a `systemctl` query for bgpd. + std::string systemctlValue(const std::string& property) const { + // Full path: folly::Subprocess (used by runCmd) does not search PATH. + auto r = runCmd( + {"/usr/bin/systemctl", "show", "bgpd", "-p", property, "--value"}); + std::string s = r.stdout; + while (!s.empty() && + (s.back() == '\n' || s.back() == '\r' || s.back() == ' ')) { + s.pop_back(); + } + return s; + } + + // "active" / "inactive" / "failed" / ... (trimmed). + std::string bgpDaemonActiveState() const { + auto r = runCmd({"/usr/bin/systemctl", "is-active", "bgpd"}); + std::string s = r.stdout; + while (!s.empty() && + (s.back() == '\n' || s.back() == '\r' || s.back() == ' ')) { + s.pop_back(); + } + return s; + } + + // bgpd main PID per systemd ("0" if not running). + std::string bgpDaemonMainPid() const { + return systemctlValue("MainPID"); + } + + // Poll until bgpd reports active or the timeout elapses. + bool waitForBgpDaemonActive( + std::chrono::seconds timeout = std::chrono::seconds(60)) const { + auto deadline = std::chrono::steady_clock::now() + timeout; + while (std::chrono::steady_clock::now() < deadline) { + if (bgpDaemonActiveState() == "active") { + return true; + } + std::this_thread::sleep_for(std::chrono::seconds(1)); + } + return bgpDaemonActiveState() == "active"; + } + + private: + // The stable path bgpd reads (--config): a plain file on a device the CLI + // never committed on, a symlink into bgpcpp/ afterwards. Reading follows + // the symlink, so the snapshot is always bgpd's effective config. + static constexpr auto kBgpDaemonConfigPath = "/etc/coop/bgpcpp.conf"; + + // Deserialized view of a serialized BgpConfig; nullopt if unparseable. + static std::optional parseBgpConfig( + const std::string& content) { + try { + return apache::thrift::SimpleJSONSerializer::deserialize< + bgp::thrift::BgpConfig>(content); + } catch (const std::exception&) { + return std::nullopt; + } + } + + // True when `content` matches the snapshot: by thrift struct equality when + // both sides parse (formatting-only differences from a commit round-trip + // don't count), else by bytes. + bool matchesBgpSnapshot(const std::string& content) const { + auto current = parseBgpConfig(content); + if (bgpSnapshotConfig_ && current) { + return *current == *bgpSnapshotConfig_; + } + return content == bgpSnapshot_; + } + + void restoreBgpConfigSnapshot() { + if (!haveBgpSnapshot_) { + return; // SetUp skipped or there was no config to protect + } + discardSession(); + clearBgpSession(); + std::string current; + if (folly::readFile(kBgpDaemonConfigPath, current) && + matchesBgpSnapshot(current)) { + return; // semantically unchanged; skip the restart + } + // Write the real file, never through the bgpd.conf symlink. + std::string target = std::filesystem::exists(systemBgpConfigPath()) + ? systemBgpConfigPath() + : std::string(kBgpDaemonConfigPath); + EXPECT_TRUE(folly::writeFile(bgpSnapshot_, target.c_str())) + << "failed to restore BGP config snapshot to " << target; + resetBgpDaemonLimit(); + runCmd({"/usr/bin/systemctl", "restart", "bgpd"}); + EXPECT_TRUE(waitForBgpDaemonActive()) + << "bgpd did not return active after snapshot restore; state=" + << bgpDaemonActiveState(); + } + + bool haveBgpSnapshot_{false}; + // Raw bytes, written back verbatim on restore; the typed view drives the + // changed/unchanged decision. + std::string bgpSnapshot_; + std::optional bgpSnapshotConfig_; +}; + +} // namespace facebook::fboss diff --git a/fboss/cli/fboss2/test/integration_test/ConfigInterfaceDescriptionTest.cpp b/fboss/cli/fboss2/test/integration_test/ConfigInterfaceDescriptionTest.cpp index c0cb7b2a1543d..952c566675b38 100644 --- a/fboss/cli/fboss2/test/integration_test/ConfigInterfaceDescriptionTest.cpp +++ b/fboss/cli/fboss2/test/integration_test/ConfigInterfaceDescriptionTest.cpp @@ -89,3 +89,52 @@ TEST_F(ConfigInterfaceDescriptionTest, SetAndVerifyDescription) { XLOG(INFO) << "TEST PASSED"; } + +// Setting an interface description to the value it already has must produce a +// no-op commit: the staged agent.conf is byte-identical to what is running, so +// `config session commit` reports "Nothing to commit" and does NOT reload the +// agent (skip-when-unchanged). Regression test for the agent-side unification. +TEST_F(ConfigInterfaceDescriptionTest, SetSameDescriptionIsNoOpCommit) { + XLOG(INFO) << "[Step 1] Finding an interface to test..."; + Interface interface = getInterfaceInfo(getRandomInterfacePortName()); + const std::string originalDescription = interface.description; + XLOG(INFO) << " Using interface: " << interface.name << " (description: '" + << originalDescription << "')"; + + // Set a deterministic description and commit so cli/agent.conf is in the + // canonical serialized form. + std::string testDescription = "CLI_E2E_NOOP_DESCRIPTION"; + XLOG(INFO) << "[Step 2] Setting description to '" << testDescription + << "' and committing..."; + setInterfaceDescription(interface.name, testDescription); + waitForInterfaceInfo(interface.name, [&](const auto& info) { + return info.description == testDescription; + }); + + // Stage the SAME description again, then commit directly so we can inspect + // the output. The staged config equals what is running -> the commit is a + // no-op. + XLOG(INFO) << "[Step 3] Re-setting the SAME description and committing..."; + auto setResult = runCli( + {"config", "interface", interface.name, "description", testDescription}); + ASSERT_EQ(setResult.exitCode, 0) << setResult.stderr; + auto commitResult = runCli({"config", "session", "commit"}); + ASSERT_EQ(commitResult.exitCode, 0) << commitResult.stderr; + XLOG(INFO) << " Commit output: " << commitResult.stdout; + EXPECT_NE(commitResult.stdout.find("Nothing to commit"), std::string::npos) + << "Re-committing an unchanged description must be a no-op, got: " + << commitResult.stdout; + EXPECT_EQ(commitResult.stdout.find("reloaded"), std::string::npos) + << "A no-op commit must not reload the agent, got: " + << commitResult.stdout; + + // Restore the original description. + XLOG(INFO) << "[Step 4] Restoring original description ('" + << originalDescription << "')..."; + setInterfaceDescription(interface.name, originalDescription); + waitForInterfaceInfo(interface.name, [&](const auto& info) { + return info.description == originalDescription; + }); + + XLOG(INFO) << "TEST PASSED"; +} diff --git a/fboss/cli/fboss2/tools/bgp_json_to_cli.py b/fboss/cli/fboss2/tools/bgp_json_to_cli.py index ddf328c4fd3ca..7d43bb0b2b0bb 100644 --- a/fboss/cli/fboss2/tools/bgp_json_to_cli.py +++ b/fboss/cli/fboss2/tools/bgp_json_to_cli.py @@ -10,95 +10,98 @@ This enables round-trip conversion: JSON -> CLI -> JSON (via fboss2). Usage: - python3 bgp_json_to_cli.py [--output output.sh] [--stub] + python3 bgp_json_to_cli.py [--output output.sh] Example: - python3 bgp_json_to_cli.py rsw_bgp_config.json --stub > configure_bgp.sh + python3 bgp_json_to_cli.py rsw_bgp_config.json > configure_bgp.sh """ import argparse import json -import shlex import sys -from typing import Any, Dict, List +from typing import Any def escape_shell_arg(arg: str) -> str: - """Escape argument for shell usage.""" - return shlex.quote(str(arg)) + """Escape argument for shell usage. + + Backslash-escapes the characters that stay special inside double quotes + (backslash, double quote, dollar, backtick) so free-form fields like + descriptions cannot terminate the quoted string or trigger expansion in + the generated script. + """ + if " " in arg or '"' in arg or "'" in arg or any(c in arg for c in "!$`\\"): + escaped = ( + arg.replace("\\", "\\\\") + .replace('"', '\\"') + .replace("$", "\\$") + .replace("`", "\\`") + ) + return f'"{escaped}"' + return arg -def _generate_global_basic_commands(config: Dict[str, Any]) -> List[str]: +def _generate_global_basic_commands(config: dict[str, Any]) -> list[str]: """Generate basic global BGP commands.""" commands = [] if "router_id" in config: commands.append( - f"config protocol bgp global router-id {escape_shell_arg(config['router_id'])}" + f"config protocol bgp global router-id {escape_shell_arg(str(config['router_id']))}" ) if "local_as_4_byte" in config: commands.append( - f"config protocol bgp global local-asn {escape_shell_arg(str(config['local_as_4_byte']))}" + f"config protocol bgp global local-asn {config['local_as_4_byte']}" ) if "hold_time" in config: - commands.append( - f"config protocol bgp global hold-time {escape_shell_arg(str(config['hold_time']))}" - ) + commands.append(f"config protocol bgp global hold-time {config['hold_time']}") if "local_confed_as_4_byte" in config: commands.append( - f"config protocol bgp global confed-asn {escape_shell_arg(str(config['local_confed_as_4_byte']))}" - ) - if "cluster_id" in config: - commands.append( - f"config protocol bgp global cluster-id {escape_shell_arg(config['cluster_id'])}" + f"config protocol bgp global confed-asn {config['local_confed_as_4_byte']}" ) return commands -def _generate_network6_commands(networks: List[Dict[str, Any]]) -> List[str]: +def _generate_network6_commands(networks: list[dict[str, Any]]) -> list[str]: """Generate network6 commands for global BGP config.""" commands = [] for network in networks: prefix = network.get("prefix", "") if not prefix: continue - cmd_parts = [ - f"config protocol bgp global network6 add {escape_shell_arg(prefix)}" - ] + cmd_parts = [f"config protocol bgp global network6 add {prefix}"] if "policy_name" in network: cmd_parts.append(f"policy {escape_shell_arg(network['policy_name'])}") if "install_to_fib" in network: cmd_parts.append(f"install-to-fib {str(network['install_to_fib']).lower()}") if "minimum_supporting_routes" in network: - cmd_parts.append( - f"min-routes {escape_shell_arg(str(network['minimum_supporting_routes']))}" - ) + cmd_parts.append(f"min-routes {network['minimum_supporting_routes']}") commands.append(" ".join(cmd_parts)) return commands -def _generate_switch_limit_commands(switch_limit: Dict[str, Any]) -> List[str]: +def _generate_switch_limit_commands(switch_limit: dict[str, Any]) -> list[str]: """Generate switch_limit_config commands.""" commands = [] if "prefix_limit" in switch_limit: commands.append( - f"config protocol bgp global switch-limit {escape_shell_arg(str(switch_limit['prefix_limit']))}" + f"config protocol bgp global switch-limit {switch_limit['prefix_limit']}" ) if "total_path_limit" in switch_limit: commands.append( - f"config protocol bgp global switch-limit-total-path {escape_shell_arg(str(switch_limit['total_path_limit']))}" + f"config protocol bgp global switch-limit-total-path {switch_limit['total_path_limit']}" ) if "max_golden_vips" in switch_limit: commands.append( - f"config protocol bgp global switch-limit-max-golden-vips {escape_shell_arg(str(switch_limit['max_golden_vips']))}" + f"config protocol bgp global switch-limit-max-golden-vips {switch_limit['max_golden_vips']}" ) if "overload_protection_mode" in switch_limit: commands.append( - f"config protocol bgp global switch-limit-overload-protection-mode {escape_shell_arg(str(switch_limit['overload_protection_mode']))}" + f"config protocol bgp global switch-limit-overload-protection-mode {switch_limit['overload_protection_mode']}" ) return commands -def generate_global_commands(config: Dict[str, Any]) -> List[str]: +def generate_global_commands(config: dict[str, Any]) -> list[str]: """Generate CLI commands for global BGP settings.""" commands = [] commands.extend(_generate_global_basic_commands(config)) @@ -110,13 +113,13 @@ def generate_global_commands(config: Dict[str, Any]) -> List[str]: def _generate_peer_group_basic_commands( - peer_group: Dict[str, Any], escaped_name: str -) -> List[str]: + peer_group: dict[str, Any], escaped_name: str +) -> list[str]: """Generate basic peer-group commands (remote-asn, description, policies).""" commands = [] if "remote_as_4_byte" in peer_group: commands.append( - f"config protocol bgp peer-group {escaped_name} remote-asn {escape_shell_arg(str(peer_group['remote_as_4_byte']))}" + f"config protocol bgp peer-group {escaped_name} remote-asn {peer_group['remote_as_4_byte']}" ) if "description" in peer_group: commands.append( @@ -138,8 +141,8 @@ def _generate_peer_group_basic_commands( def _generate_peer_group_bool_commands( - peer_group: Dict[str, Any], escaped_name: str -) -> List[str]: + peer_group: dict[str, Any], escaped_name: str +) -> list[str]: """Generate boolean flag commands for peer-group.""" commands = [] bool_fields = [ @@ -158,41 +161,41 @@ def _generate_peer_group_bool_commands( def _generate_peer_group_timer_commands( - timers: Dict[str, Any], escaped_name: str -) -> List[str]: + timers: dict[str, Any], escaped_name: str +) -> list[str]: """Generate timer commands for peer-group.""" commands = [] if timers.get("hold_time_seconds"): commands.append( - f"config protocol bgp peer-group {escaped_name} timers hold-time {escape_shell_arg(str(timers['hold_time_seconds']))}" + f"config protocol bgp peer-group {escaped_name} timers hold-time {timers['hold_time_seconds']}" ) if timers.get("keep_alive_seconds"): commands.append( - f"config protocol bgp peer-group {escaped_name} timers keepalive {escape_shell_arg(str(timers['keep_alive_seconds']))}" + f"config protocol bgp peer-group {escaped_name} timers keepalive {timers['keep_alive_seconds']}" ) if "out_delay_seconds" in timers: commands.append( - f"config protocol bgp peer-group {escaped_name} timers out-delay {escape_shell_arg(str(timers['out_delay_seconds']))}" + f"config protocol bgp peer-group {escaped_name} timers out-delay {timers['out_delay_seconds']}" ) if "withdraw_unprog_delay_seconds" in timers: commands.append( - f"config protocol bgp peer-group {escaped_name} timers withdraw-unprog-delay {escape_shell_arg(str(timers['withdraw_unprog_delay_seconds']))}" + f"config protocol bgp peer-group {escaped_name} timers withdraw-unprog-delay {timers['withdraw_unprog_delay_seconds']}" ) return commands def _generate_peer_group_prefilter_commands( - pre_filter: Dict[str, Any], escaped_name: str -) -> List[str]: + pre_filter: dict[str, Any], escaped_name: str +) -> list[str]: """Generate pre_filter commands for peer-group.""" commands = [] if pre_filter.get("max_routes"): commands.append( - f"config protocol bgp peer-group {escaped_name} max-routes {escape_shell_arg(str(pre_filter['max_routes']))}" + f"config protocol bgp peer-group {escaped_name} max-routes {pre_filter['max_routes']}" ) if "warning_limit" in pre_filter: commands.append( - f"config protocol bgp peer-group {escaped_name} warning-limit {escape_shell_arg(str(pre_filter['warning_limit']))}" + f"config protocol bgp peer-group {escaped_name} warning-limit {pre_filter['warning_limit']}" ) if "warning_only" in pre_filter: commands.append( @@ -201,7 +204,7 @@ def _generate_peer_group_prefilter_commands( return commands -def generate_peer_group_commands(peer_group: Dict[str, Any]) -> List[str]: +def generate_peer_group_commands(peer_group: dict[str, Any]) -> list[str]: """Generate CLI commands for a peer group.""" name = peer_group.get("name", "") if not name: @@ -228,179 +231,164 @@ def format_bandwidth(bps: int) -> str: """Format bandwidth in bps to human-readable format (e.g., 10G).""" if bps >= 1_000_000_000_000 and bps % 1_000_000_000_000 == 0: return f"{bps // 1_000_000_000_000}T" - elif bps >= 1_000_000_000 and bps % 1_000_000_000 == 0: + if bps >= 1_000_000_000 and bps % 1_000_000_000 == 0: return f"{bps // 1_000_000_000}G" - elif bps >= 1_000_000 and bps % 1_000_000 == 0: + if bps >= 1_000_000 and bps % 1_000_000 == 0: return f"{bps // 1_000_000}M" - elif bps >= 1_000 and bps % 1_000 == 0: + if bps >= 1_000 and bps % 1_000 == 0: return f"{bps // 1_000}K" return str(bps) -def _generate_peer_basic_commands(peer: Dict[str, Any], peer_addr: str) -> List[str]: - """Generate basic peer commands (remote-asn, peer-group, description, etc.).""" +# (json field, CLI attribute, escape as free-form shell arg) — fields whose +# value maps 1:1 onto a neighbor attribute token. +_NEIGHBOR_SCALAR_FIELDS = [ + ("remote_as_4_byte", "remote-asn", False), + ("local_as_4_byte", "local-asn", False), + ("peer_group_name", "peer-group", True), + ("description", "description", True), + ("peer_tag", "peer-tag", True), + ("local_addr", "bind-addr address", True), + ("ingress_policy_name", "ingress-policy", True), + ("egress_policy_name", "egress-policy", True), + ("next_hop4", "next-hop4", True), + ("next_hop6", "next-hop6", True), + ("peer_id", "peer-id", True), + ("type", "type", True), +] + + +def _generate_neighbor_basic_commands(peer: dict[str, Any], prefix: str) -> list[str]: + """Generate scalar neighbor commands (ASNs, names, policies, addresses).""" commands = [] - if "remote_as_4_byte" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} remote-asn {escape_shell_arg(str(peer['remote_as_4_byte']))}" - ) - if "peer_group_name" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} peer-group {escape_shell_arg(peer['peer_group_name'])}" - ) - if "description" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} description {escape_shell_arg(peer['description'])}" - ) - if "local_addr" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} local-addr {escape_shell_arg(peer['local_addr'])}" - ) - if "ingress_policy_name" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} ingress-policy {escape_shell_arg(peer['ingress_policy_name'])}" - ) - if "egress_policy_name" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} egress-policy {escape_shell_arg(peer['egress_policy_name'])}" - ) + for field, cli_name, escape in _NEIGHBOR_SCALAR_FIELDS: + if field in peer: + value = escape_shell_arg(str(peer[field])) if escape else peer[field] + commands.append(f"{prefix} {cli_name} {value}") + if "is_passive" in peer: + mode = "PASSIVE" if peer["is_passive"] else "ACTIVE" + commands.append(f"{prefix} connect-mode {mode}") + if "link_bandwidth_bps" in peer: + bw = peer["link_bandwidth_bps"] + bw_str = format_bandwidth(bw) if isinstance(bw, int) else str(bw) + commands.append(f"{prefix} link-bandwidth {bw_str}") + if "advertise_link_bandwidth" in peer: + commands.append(f"{prefix} advertise-lbw {peer['advertise_link_bandwidth']}") + if "receive_link_bandwidth" in peer: + commands.append(f"{prefix} receive-lbw {peer['receive_link_bandwidth']}") return commands -def _generate_peer_bool_commands(peer: Dict[str, Any], peer_addr: str) -> List[str]: - """Generate boolean flag commands for peer.""" +def _generate_neighbor_bool_commands(peer: dict[str, Any], prefix: str) -> list[str]: + """Generate boolean flag commands for a neighbor.""" commands = [] bool_fields = [ - ("is_passive", "passive"), ("is_rr_client", "rr-client"), + ("is_confed_peer", "confed-peer"), + ("is_redistribute_peer", "redistribute-peer"), + ("enhanced_route_refresh", "enhanced-route-refresh"), + ("disable_ipv4_afi", "afi disable-ipv4-afi"), + ("disable_ipv6_afi", "afi disable-ipv6-afi"), + ("v4_over_v6_nexthop", "afi ipv4-over-ipv6-nh"), + ("enable_stateful_ha", "graceful-restart stateful-ha"), ("next_hop_self", "next-hop-self"), - ("v4_over_v6_nexthop", "v4-over-v6-nh"), - ("disable_ipv4_afi", "disable-ipv4-afi"), - ("advertise_link_bandwidth", "advertise-lbw"), ] for field, cli_name in bool_fields: if field in peer: - commands.append( - f"config protocol bgp peer {peer_addr} {cli_name} {str(peer[field]).lower()}" - ) + commands.append(f"{prefix} {cli_name} {str(peer[field]).lower()}") return commands -def _generate_peer_nexthop_commands(peer: Dict[str, Any], peer_addr: str) -> List[str]: - """Generate next-hop and link-bandwidth commands for peer.""" +def _generate_neighbor_add_path_commands( + peer: dict[str, Any], prefix: str +) -> list[str]: + """Generate add-path commands from the AddPath enum (RECEIVE=1, SEND=2, BOTH=3).""" + if "add_path" not in peer: + return [] + raw = peer["add_path"] + value = ( + {"RECEIVE": 1, "SEND": 2, "BOTH": 3}.get(raw, raw) + if isinstance(raw, str) + else raw + ) + value = int(value) commands = [] - if "next_hop4" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} next-hop4 {escape_shell_arg(peer['next_hop4'])}" - ) - if "next_hop6" in peer: - commands.append( - f"config protocol bgp peer {peer_addr} next-hop6 {escape_shell_arg(peer['next_hop6'])}" - ) - if "link_bandwidth_bps" in peer: - bw = peer["link_bandwidth_bps"] - bw_str = format_bandwidth(bw) if isinstance(bw, int) else str(bw) - commands.append( - f"config protocol bgp peer {peer_addr} link-bandwidth {escape_shell_arg(bw_str)}" - ) + if value & 1: + commands.append(f"{prefix} add-path receive true") + if value & 2: + commands.append(f"{prefix} add-path send true") return commands -def _generate_peer_timer_commands(timers: Dict[str, Any], peer_addr: str) -> List[str]: - """Generate timer commands for peer.""" +def _generate_neighbor_timer_commands(timers: dict[str, Any], prefix: str) -> list[str]: + """Generate timer and graceful-restart commands for a neighbor.""" commands = [] - if timers.get("hold_time_seconds"): - commands.append( - f"config protocol bgp peer {peer_addr} hold-time {escape_shell_arg(str(timers['hold_time_seconds']))}" - ) - if timers.get("keep_alive_seconds"): - commands.append( - f"config protocol bgp peer {peer_addr} timers keepalive {escape_shell_arg(str(timers['keep_alive_seconds']))}" - ) + if "hold_time_seconds" in timers: + commands.append(f"{prefix} timers hold-time {timers['hold_time_seconds']}") + if "keep_alive_seconds" in timers: + commands.append(f"{prefix} timers keepalive {timers['keep_alive_seconds']}") if "out_delay_seconds" in timers: + commands.append(f"{prefix} timers out-delay {timers['out_delay_seconds']}") + if "withdraw_unprog_delay_seconds" in timers: commands.append( - f"config protocol bgp peer {peer_addr} timers out-delay {escape_shell_arg(str(timers['out_delay_seconds']))}" + f"{prefix} timers withdraw-unprog-delay {timers['withdraw_unprog_delay_seconds']}" ) - if "withdraw_unprog_delay_seconds" in timers: + if "graceful_restart_seconds" in timers: commands.append( - f"config protocol bgp peer {peer_addr} timers withdraw-unprog-delay {escape_shell_arg(str(timers['withdraw_unprog_delay_seconds']))}" + f"{prefix} graceful-restart restart-time {timers['graceful_restart_seconds']}" ) return commands -def _generate_peer_prefilter_commands( - pre_filter: Dict[str, Any], peer_addr: str -) -> List[str]: - """Generate pre_filter commands for peer.""" +def _generate_neighbor_route_limit_commands( + peer: dict[str, Any], prefix: str +) -> list[str]: + """Generate max-route commands from pre_filter/post_filter.""" commands = [] - if pre_filter.get("max_routes"): - commands.append( - f"config protocol bgp peer {peer_addr} max-routes {escape_shell_arg(str(pre_filter['max_routes']))}" - ) + pre_filter = peer.get("pre_filter", {}) + if "max_routes" in pre_filter: + commands.append(f"{prefix} max-route pre-filter {pre_filter['max_routes']}") if "warning_limit" in pre_filter: commands.append( - f"config protocol bgp peer {peer_addr} warning-limit {escape_shell_arg(str(pre_filter['warning_limit']))}" + f"{prefix} max-route pre-warning-threshold {pre_filter['warning_limit']}" ) if "warning_only" in pre_filter: commands.append( - f"config protocol bgp peer {peer_addr} warning-only {str(pre_filter['warning_only']).lower()}" + f"{prefix} max-route pre-warning-only {str(pre_filter['warning_only']).lower()}" ) - return commands - - -def _generate_peer_id_commands(peer: Dict[str, Any], peer_addr: str) -> List[str]: - """Generate peer identification commands.""" - commands = [] - if "peer_id" in peer: + post_filter = peer.get("post_filter", {}) + if "max_routes" in post_filter: + commands.append(f"{prefix} max-route post-filter {post_filter['max_routes']}") + if "warning_limit" in post_filter: commands.append( - f"config protocol bgp peer {peer_addr} peer-id {escape_shell_arg(peer['peer_id'])}" + f"{prefix} max-route post-warning-threshold {post_filter['warning_limit']}" ) - if "type" in peer: + if "warning_only" in post_filter: commands.append( - f"config protocol bgp peer {peer_addr} type {escape_shell_arg(peer['type'])}" + f"{prefix} max-route post-warning-only {str(post_filter['warning_only']).lower()}" ) return commands -def generate_peer_commands(peer: Dict[str, Any]) -> List[str]: - """Generate CLI commands for a peer.""" +def generate_peer_commands(peer: dict[str, Any]) -> list[str]: + """Generate `config protocol bgp neighbor` CLI commands for a peer.""" peer_addr = peer.get("peer_addr", "") if not peer_addr: return [] - escaped_peer_addr = escape_shell_arg(peer_addr) + prefix = f"config protocol bgp neighbor {escape_shell_arg(peer_addr)}" commands = [] - commands.extend(_generate_peer_basic_commands(peer, escaped_peer_addr)) - commands.extend(_generate_peer_bool_commands(peer, escaped_peer_addr)) - commands.extend(_generate_peer_nexthop_commands(peer, escaped_peer_addr)) - commands.extend( - _generate_peer_timer_commands( - peer.get("bgp_peer_timers", {}), escaped_peer_addr - ) - ) + commands.extend(_generate_neighbor_basic_commands(peer, prefix)) + commands.extend(_generate_neighbor_bool_commands(peer, prefix)) + commands.extend(_generate_neighbor_add_path_commands(peer, prefix)) commands.extend( - _generate_peer_prefilter_commands(peer.get("pre_filter", {}), escaped_peer_addr) + _generate_neighbor_timer_commands(peer.get("bgp_peer_timers", {}), prefix) ) - commands.extend(_generate_peer_id_commands(peer, escaped_peer_addr)) + commands.extend(_generate_neighbor_route_limit_commands(peer, prefix)) return commands -def generate_stub_commands(commands: List[str], binary: str = "fboss2") -> List[str]: - """Wrap commands for stub mode execution.""" - stub_commands = [ - "#!/bin/bash", - "# BGP configuration script generated by j2c", - "# Run with FBOSS_BGP_STUB_MODE=1 for testing", - "", - "export FBOSS_BGP_STUB_MODE=1", - "", - ] - for cmd in commands: - stub_commands.append(f"{binary} {cmd}") - return stub_commands - - -def generate_exec_commands(commands: List[str], binary: str = "fboss2") -> List[str]: +def generate_exec_commands(commands: list[str], binary: str = "fboss2") -> list[str]: """Generate executable commands with custom binary.""" exec_commands = [ "#!/bin/bash", @@ -424,9 +412,7 @@ def generate_exec_commands(commands: List[str], binary: str = "fboss2") -> List[ return exec_commands -def json_to_cli( - config: Dict[str, Any], stub: bool = False, binary: str = "fboss2" -) -> List[str]: +def json_to_cli(config: dict[str, Any], binary: str = "fboss2") -> list[str]: """Convert BGP++ JSON config to CLI commands.""" commands = [] @@ -441,9 +427,6 @@ def json_to_cli( for peer in config.get("peers", []): commands.extend(generate_peer_commands(peer)) - if stub: - return generate_stub_commands(commands, binary) - return generate_exec_commands(commands, binary) @@ -455,11 +438,6 @@ def main() -> int: parser.add_argument( "--output", "-o", help="Output file (default: stdout)", default=None ) - parser.add_argument( - "--stub", - action="store_true", - help="Generate stub mode script with FBOSS_BGP_STUB_MODE=1", - ) parser.add_argument( "--binary", "-b", @@ -474,7 +452,7 @@ def main() -> int: args = parser.parse_args() try: - with open(args.input, "r") as f: + with open(args.input) as f: config = json.load(f) except FileNotFoundError: print(f"Error: Input file '{args.input}' not found", file=sys.stderr) @@ -493,7 +471,7 @@ def main() -> int: commands.extend(generate_peer_commands(peer)) output = "\n".join(commands) else: - commands = json_to_cli(config, stub=args.stub, binary=args.binary) + commands = json_to_cli(config, binary=args.binary) output = "\n".join(commands) if args.output: diff --git a/fboss/cli/fboss2/tools/tests/test_bgp_json_to_cli.py b/fboss/cli/fboss2/tools/tests/test_bgp_json_to_cli.py index 0c5f7a604aad2..9e9aab462f4a1 100644 --- a/fboss/cli/fboss2/tools/tests/test_bgp_json_to_cli.py +++ b/fboss/cli/fboss2/tools/tests/test_bgp_json_to_cli.py @@ -24,7 +24,6 @@ generate_global_commands, generate_peer_commands, generate_peer_group_commands, - generate_stub_commands, json_to_cli, ) @@ -38,40 +37,38 @@ def test_simple_string_not_escaped(self) -> None: self.assertEqual(result, "simple") def test_string_with_space_is_quoted(self) -> None: - """Strings with spaces should be wrapped in single quotes.""" + """Strings with spaces should be wrapped in double quotes.""" result = escape_shell_arg("hello world") - self.assertEqual(result, "'hello world'") + self.assertEqual(result, '"hello world"') def test_string_with_special_chars_is_quoted(self) -> None: - """Strings with shell special characters should be quoted.""" + """Shell specials should be quoted AND escaped so they stay literal.""" result = escape_shell_arg("value$var") - self.assertEqual(result, "'value$var'") + self.assertEqual(result, '"value\\$var"') def test_string_with_backslash_is_quoted(self) -> None: - """Strings with backslash should be quoted.""" + """Backslashes should be quoted and doubled to stay literal.""" result = escape_shell_arg("path\\to\\file") - self.assertEqual(result, "'path\\to\\file'") + self.assertEqual(result, '"path\\\\to\\\\file"') def test_empty_string(self) -> None: - """Empty string is quoted as empty single quotes.""" + """Empty string should not be quoted.""" result = escape_shell_arg("") - self.assertEqual(result, "''") + self.assertEqual(result, "") + + def test_embedded_quotes_and_dollars_escaped(self) -> None: + """Specials that stay live inside double quotes must be backslashed.""" + self.assertEqual( + escape_shell_arg('rack "A1" $spine'), '"rack \\"A1\\" \\$spine"' + ) + self.assertEqual(escape_shell_arg("tick `id`"), '"tick \\`id\\`"') + self.assertEqual(escape_shell_arg("back\\slash"), '"back\\\\slash"') def test_ipv6_address_not_escaped(self) -> None: """IPv6 addresses should not be quoted.""" result = escape_shell_arg("2401:db00:501c::/64") self.assertEqual(result, "2401:db00:501c::/64") - def test_command_injection_payload_neutralized(self) -> None: - """Command injection payloads should be rendered literal.""" - result = escape_shell_arg("$(reboot)") - self.assertEqual(result, "'$(reboot)'") - - def test_backtick_injection_neutralized(self) -> None: - """Backtick command substitution should be rendered literal.""" - result = escape_shell_arg("`reboot`") - self.assertEqual(result, "'`reboot`'") - class FormatBandwidthTest(unittest.TestCase): """Tests for format_bandwidth function.""" @@ -134,14 +131,6 @@ def test_confed_asn(self) -> None: commands = generate_global_commands(config) self.assertEqual(commands, ["config protocol bgp global confed-asn 65001"]) - def test_cluster_id(self) -> None: - """Cluster ID should generate correct command.""" - config = {"cluster_id": "192.168.1.1"} - commands = generate_global_commands(config) - self.assertEqual( - commands, ["config protocol bgp global cluster-id 192.168.1.1"] - ) - def test_networks6_with_all_fields(self) -> None: """networks6 should generate command with all fields.""" config = { @@ -162,14 +151,7 @@ def test_networks6_with_all_fields(self) -> None: def test_networks6_with_install_to_fib_true(self) -> None: """networks6 with install_to_fib=true should preserve value.""" - config = { - "networks6": [ - { - "prefix": "2001:db8::/32", - "install_to_fib": True, - } - ] - } + config = {"networks6": [{"prefix": "2001:db8::/32", "install_to_fib": True}]} commands = generate_global_commands(config) self.assertIn("install-to-fib true", commands[0]) @@ -263,7 +245,7 @@ def test_description_with_spaces(self) -> None: peer_group = {"name": "TEST", "description": "Test peer group"} commands = generate_peer_group_commands(peer_group) self.assertIn( - "config protocol bgp peer-group TEST description 'Test peer group'", + 'config protocol bgp peer-group TEST description "Test peer group"', commands, ) @@ -368,7 +350,7 @@ def test_peer_tag(self) -> None: class GeneratePeerCommandsTest(unittest.TestCase): - """Tests for generate_peer_commands function.""" + """Tests for generate_peer_commands (neighbor grammar).""" def test_empty_peer_addr_returns_empty(self) -> None: """Peer without peer_addr should return empty list.""" @@ -380,36 +362,55 @@ def test_remote_asn(self) -> None: """remote_as_4_byte should generate correct command.""" peer = {"peer_addr": "2001:db8::1", "remote_as_4_byte": 65000} commands = generate_peer_commands(peer) - self.assertIn("config protocol bgp peer 2001:db8::1 remote-asn 65000", commands) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 remote-asn 65000", commands + ) + + def test_local_asn(self) -> None: + """local_as_4_byte should generate local-asn command.""" + peer = {"peer_addr": "2001:db8::1", "local_as_4_byte": 64512} + commands = generate_peer_commands(peer) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 local-asn 64512", commands + ) def test_peer_group_name(self) -> None: """peer_group_name should generate peer-group command.""" peer = {"peer_addr": "2001:db8::1", "peer_group_name": "MY-GROUP"} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 peer-group MY-GROUP", commands + "config protocol bgp neighbor 2001:db8::1 peer-group MY-GROUP", commands ) def test_local_addr(self) -> None: - """local_addr should generate local-addr command.""" + """local_addr should generate bind-addr address command.""" peer = {"peer_addr": "2001:db8::1", "local_addr": "2001:db8::a"} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 local-addr 2001:db8::a", commands + "config protocol bgp neighbor 2001:db8::1 bind-addr address 2001:db8::a", + commands, ) def test_is_passive(self) -> None: - """is_passive should generate passive command.""" + """is_passive should generate connect-mode command.""" peer = {"peer_addr": "2001:db8::1", "is_passive": True} commands = generate_peer_commands(peer) - self.assertIn("config protocol bgp peer 2001:db8::1 passive true", commands) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 connect-mode PASSIVE", commands + ) + peer["is_passive"] = False + commands = generate_peer_commands(peer) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 connect-mode ACTIVE", commands + ) def test_disable_ipv4_afi_false_preserved(self) -> None: """disable_ipv4_afi: false should NOT be omitted.""" peer = {"peer_addr": "2001:db8::1", "disable_ipv4_afi": False} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 disable-ipv4-afi false", commands + "config protocol bgp neighbor 2001:db8::1 afi disable-ipv4-afi false", + commands, ) def test_disable_ipv4_afi_true(self) -> None: @@ -417,58 +418,40 @@ def test_disable_ipv4_afi_true(self) -> None: peer = {"peer_addr": "2001:db8::1", "disable_ipv4_afi": True} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 disable-ipv4-afi true", commands + "config protocol bgp neighbor 2001:db8::1 afi disable-ipv4-afi true", + commands, ) - def test_next_hop4_and_next_hop6(self) -> None: - """next_hop4 and next_hop6 should generate correct commands.""" - peer = { - "peer_addr": "2001:db8::1", - "next_hop4": "0.0.0.0", - "next_hop6": "2001:db8::a", - } + def test_stateful_ha(self) -> None: + """enable_stateful_ha should generate graceful-restart stateful-ha.""" + peer = {"peer_addr": "2001:db8::1", "enable_stateful_ha": True} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 next-hop4 0.0.0.0", commands - ) - self.assertIn( - "config protocol bgp peer 2001:db8::1 next-hop6 2001:db8::a", commands + "config protocol bgp neighbor 2001:db8::1 graceful-restart stateful-ha true", + commands, ) - def test_link_bandwidth_string(self) -> None: - """link_bandwidth_bps as string should be used directly.""" - peer = {"peer_addr": "2001:db8::1", "link_bandwidth_bps": "10G"} + def test_add_path_both(self) -> None: + """add_path BOTH (3) should generate both directions.""" + peer = {"peer_addr": "2001:db8::1", "add_path": 3} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 link-bandwidth 10G", commands + "config protocol bgp neighbor 2001:db8::1 add-path receive true", commands ) - - def test_link_bandwidth_int(self) -> None: - """link_bandwidth_bps as int should be formatted.""" - peer = {"peer_addr": "2001:db8::1", "link_bandwidth_bps": 10_000_000_000} - commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 link-bandwidth 10G", commands + "config protocol bgp neighbor 2001:db8::1 add-path send true", commands ) - def test_advertise_link_bandwidth(self) -> None: - """advertise_link_bandwidth should generate advertise-lbw command.""" - peer = {"peer_addr": "2001:db8::1", "advertise_link_bandwidth": 1} - commands = generate_peer_commands(peer) - self.assertIn("config protocol bgp peer 2001:db8::1 advertise-lbw 1", commands) - - def test_peer_id_and_type(self) -> None: - """peer_id and type should generate correct commands.""" - peer = { - "peer_addr": "2001:db8::1", - "peer_id": "test-peer:v6:1", - "type": "BGP_MONITOR", - } + def test_add_path_receive_only(self) -> None: + """add_path RECEIVE (1) should generate only the receive direction.""" + peer = {"peer_addr": "2001:db8::1", "add_path": 1} commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 peer-id test-peer:v6:1", commands + "config protocol bgp neighbor 2001:db8::1 add-path receive true", commands + ) + self.assertNotIn( + "config protocol bgp neighbor 2001:db8::1 add-path send true", commands ) - self.assertIn("config protocol bgp peer 2001:db8::1 type BGP_MONITOR", commands) def test_timers(self) -> None: """Timer fields should generate correct commands.""" @@ -478,35 +461,101 @@ def test_timers(self) -> None: "hold_time_seconds": 120, "keep_alive_seconds": 40, "out_delay_seconds": 0, - "withdraw_unprog_delay_seconds": 0, + "graceful_restart_seconds": 60, }, } commands = generate_peer_commands(peer) - self.assertIn("config protocol bgp peer 2001:db8::1 hold-time 120", commands) self.assertIn( - "config protocol bgp peer 2001:db8::1 timers keepalive 40", commands + "config protocol bgp neighbor 2001:db8::1 timers hold-time 120", commands + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 timers keepalive 40", commands + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 timers out-delay 0", commands + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 graceful-restart restart-time 60", + commands, ) - def test_pre_filter(self) -> None: - """pre_filter fields should generate correct commands.""" + def test_route_limits(self) -> None: + """pre_filter/post_filter should generate max-route commands.""" peer = { "peer_addr": "2001:db8::1", - "pre_filter": { - "max_routes": 45000, - "warning_limit": 0, - "warning_only": False, - }, + "pre_filter": {"max_routes": 45000}, + "post_filter": {"max_routes": 50000, "warning_limit": 48000}, + } + commands = generate_peer_commands(peer) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 max-route pre-filter 45000", + commands, + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 max-route post-filter 50000", + commands, + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 max-route post-warning-threshold 48000", + commands, + ) + + def test_parity_fields(self) -> None: + """Fields carried over from the old peer commands map to the new grammar.""" + peer = { + "peer_addr": "2001:db8::1", + "next_hop4": "0.0.0.0", + "next_hop6": "2001:db8::a", + "next_hop_self": True, + "link_bandwidth_bps": "10G", + "advertise_link_bandwidth": 1, + "receive_link_bandwidth": 1, + "peer_id": "test-peer:v6:1", + "type": "BGP_MONITOR", + "bgp_peer_timers": {"withdraw_unprog_delay_seconds": 5}, + "pre_filter": {"warning_limit": 100, "warning_only": True}, + } + commands = generate_peer_commands(peer) + prefix = "config protocol bgp neighbor 2001:db8::1" + self.assertIn(f"{prefix} next-hop4 0.0.0.0", commands) + self.assertIn(f"{prefix} next-hop6 2001:db8::a", commands) + self.assertIn(f"{prefix} next-hop-self true", commands) + self.assertIn(f"{prefix} link-bandwidth 10G", commands) + self.assertIn(f"{prefix} advertise-lbw 1", commands) + self.assertIn(f"{prefix} receive-lbw 1", commands) + self.assertIn(f"{prefix} peer-id test-peer:v6:1", commands) + self.assertIn(f"{prefix} type BGP_MONITOR", commands) + self.assertIn(f"{prefix} timers withdraw-unprog-delay 5", commands) + self.assertIn(f"{prefix} max-route pre-warning-threshold 100", commands) + self.assertIn(f"{prefix} max-route pre-warning-only true", commands) + + def test_zero_values_preserved(self) -> None: + """Explicit zero timers/limits must not be dropped.""" + peer = { + "peer_addr": "2001:db8::1", + "bgp_peer_timers": {"hold_time_seconds": 0, "keep_alive_seconds": 0}, + "pre_filter": {"max_routes": 0}, } commands = generate_peer_commands(peer) - self.assertIn("config protocol bgp peer 2001:db8::1 max-routes 45000", commands) - self.assertIn("config protocol bgp peer 2001:db8::1 warning-limit 0", commands) + prefix = "config protocol bgp neighbor 2001:db8::1" + self.assertIn(f"{prefix} timers hold-time 0", commands) + self.assertIn(f"{prefix} timers keepalive 0", commands) + self.assertIn(f"{prefix} max-route pre-filter 0", commands) + + def test_add_path_symbolic(self) -> None: + """add_path serialized as an enum name must not crash the tool.""" + peer = {"peer_addr": "2001:db8::1", "add_path": "BOTH"} + commands = generate_peer_commands(peer) self.assertIn( - "config protocol bgp peer 2001:db8::1 warning-only false", commands + "config protocol bgp neighbor 2001:db8::1 add-path receive true", commands + ) + self.assertIn( + "config protocol bgp neighbor 2001:db8::1 add-path send true", commands ) class GenerateScriptCommandsTest(unittest.TestCase): - """Tests for generate_exec_commands and generate_stub_commands.""" + """Tests for generate_exec_commands.""" def test_exec_commands_contains_header(self) -> None: """Exec commands should contain shebang and header.""" @@ -524,12 +573,6 @@ def test_exec_commands_prepends_binary(self) -> None: "/path/to/fboss2 config protocol bgp global router-id 10.0.0.1", result ) - def test_stub_commands_contains_stub_env(self) -> None: - """Stub commands should set FBOSS_BGP_STUB_MODE.""" - commands = ["test command"] - result = generate_stub_commands(commands, "fboss2") - self.assertIn("export FBOSS_BGP_STUB_MODE=1", result) - class JsonToCliIntegrationTest(unittest.TestCase): """Integration tests for json_to_cli function.""" @@ -537,7 +580,7 @@ class JsonToCliIntegrationTest(unittest.TestCase): def test_minimal_config(self) -> None: """Minimal config with just router_id should work.""" config = {"router_id": "10.0.0.1"} - commands = json_to_cli(config, stub=False, binary="fboss2") + commands = json_to_cli(config, binary="fboss2") self.assertTrue(any("router-id 10.0.0.1" in cmd for cmd in commands)) def test_full_rsw_config(self) -> None: @@ -569,10 +612,7 @@ def test_full_rsw_config(self) -> None: "keep_alive_seconds": 10, }, }, - { - "name": "RSW-RTSW-V6", - "disable_ipv4_afi": True, - }, + {"name": "RSW-RTSW-V6", "disable_ipv4_afi": True}, ], "peers": [ { @@ -589,7 +629,7 @@ def test_full_rsw_config(self) -> None: ], } - commands = json_to_cli(config, stub=False, binary="fboss2") + commands = json_to_cli(config, binary="fboss2") joined = "\n".join(commands) # Verify global commands @@ -605,51 +645,38 @@ def test_full_rsw_config(self) -> None: self.assertIn("peer-group RSW-RTSW-V6 disable-ipv4-afi true", joined) # Verify peer commands - self.assertIn("peer 2401:db00:501c::/64 remote-asn 65000", joined) - self.assertIn("peer 2401:db00:501c::/64 disable-ipv4-afi false", joined) - self.assertIn("peer 2401:db00:e50e:1000:: peer-group RSW-FSW-V6", joined) - - def test_stub_mode(self) -> None: - """Stub mode should set FBOSS_BGP_STUB_MODE environment variable.""" - config = {"router_id": "10.0.0.1"} - commands = json_to_cli(config, stub=True, binary="fboss2") - self.assertIn("export FBOSS_BGP_STUB_MODE=1", commands) + self.assertIn("neighbor 2401:db00:501c::/64 remote-asn 65000", joined) + self.assertIn("neighbor 2401:db00:501c::/64 afi disable-ipv4-afi false", joined) + self.assertIn("neighbor 2401:db00:e50e:1000:: peer-group RSW-FSW-V6", joined) def test_empty_config(self) -> None: """Empty config should produce script with no commands.""" config = {} - commands = json_to_cli(config, stub=False, binary="fboss2") + commands = json_to_cli(config, binary="fboss2") # Should only have header and footer, no actual BGP commands self.assertTrue(any("#!/bin/bash" in cmd for cmd in commands)) def test_custom_binary(self) -> None: """Custom binary path should be used in commands.""" config = {"router_id": "10.0.0.1"} - commands = json_to_cli(config, stub=False, binary="/custom/path/fboss2") + commands = json_to_cli(config, binary="/custom/path/fboss2") self.assertTrue(any("/custom/path/fboss2" in cmd for cmd in commands)) def test_injection_in_router_id_neutralized(self) -> None: - """Command injection in router_id should be single-quoted.""" + """Command injection in router_id should be escaped.""" config = {"router_id": "$(reboot)"} - commands = json_to_cli(config, stub=False, binary="fboss2") + commands = json_to_cli(config, binary="fboss2") joined = "\n".join(commands) - self.assertIn("router-id '$(reboot)'", joined) + self.assertIn('router-id "\\$(reboot)"', joined) self.assertNotIn("router-id $(reboot)", joined) def test_injection_in_peer_addr_neutralized(self) -> None: - """Command injection in peer_addr should be single-quoted.""" - config = { - "peers": [ - { - "peer_addr": "$(malicious)", - "remote_as_4_byte": 65000, - } - ] - } - commands = json_to_cli(config, stub=False, binary="fboss2") + """Command injection in peer_addr should be escaped.""" + config = {"peers": [{"peer_addr": "$(malicious)", "remote_as_4_byte": 65000}]} + commands = json_to_cli(config, binary="fboss2") joined = "\n".join(commands) - self.assertIn("peer '$(malicious)'", joined) - self.assertNotIn("peer $(malicious)", joined) + self.assertIn('neighbor "\\$(malicious)"', joined) + self.assertNotIn("neighbor $(malicious)", joined) if __name__ == "__main__":