Coverage for src/birdplan/plugins/cmdline/bgp/peer/graceful_shutdown/show.py: 43%

65 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-07-25 07:38 +0000

1# 

2# SPDX-License-Identifier: GPL-3.0-or-later 

3# 

4# Copyright (c) 2019-2025, AllWorldIT 

5# 

6# This program is free software: you can redistribute it and/or modify 

7# it under the terms of the GNU General Public License as published by 

8# the Free Software Foundation, either version 3 of the License, or 

9# (at your option) any later version. 

10# 

11# This program is distributed in the hope that it will be useful, 

12# but WITHOUT ANY WARRANTY; without even the implied warranty of 

13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 

14# GNU General Public License for more details. 

15# 

16# You should have received a copy of the GNU General Public License 

17# along with this program. If not, see <http://www.gnu.org/licenses/>. 

18 

19"""BirdPlan commandline options for BGP peer graceful shutdown show.""" 

20 

21import argparse 

22import io 

23from typing import TYPE_CHECKING, Any 

24 

25from ......cmdline import BirdPlanCommandLine, BirdPlanCommandlineResult 

26from ......console.colors import colored 

27from ....cmdline_plugin import BirdPlanCmdlinePluginBase 

28 

29if TYPE_CHECKING: 

30 from birdplan import BirdPlanBGPPeerGracefulShutdownStatus 

31 

32__all__ = ["BirdPlanCmdlineBGPPeerGracefulShutdownShow"] 

33 

34 

35class BirdPlanCmdlineBGPPeerGracefulShutdownShowResult(BirdPlanCommandlineResult): 

36 """BirdPlan BGP peer graceful shutdown show result.""" 

37 

38 def as_text(self) -> str: # noqa: C901 

39 """ 

40 Return data in text format. 

41 

42 Returns 

43 ------- 

44 str 

45 Return data in text format. 

46 

47 """ 

48 

49 ob = io.StringIO() 

50 

51 ob.write("BGP peer graceful shutdown overrides:\n") 

52 ob.write("-------------------------------------\n") 

53 

54 # Loop with sorted override list 

55 for peer in sorted(self.data["overrides"]): 

56 # Print out override 

57 status = colored("Enabled", "red") if self.data["overrides"][peer] else colored("Disabled", "green") 

58 ob.write(f" {peer}: {status}\n") 

59 # If we have no overrides, just print out --none-- 

60 if not self.data["overrides"]: 

61 ob.write("--none--\n") 

62 

63 ob.write("\n") 

64 

65 # Get a list of all peers we know about 

66 peers_all = list(self.data["current"].keys()) + list(self.data["pending"].keys()) 

67 peers_all = sorted(set(peers_all)) 

68 

69 ob.write("BGP peer graceful shutdown status:\n") 

70 ob.write("----------------------------------\n") 

71 

72 # Loop with sorted peer list 

73 for peer in peers_all: 

74 # Grab pending status 

75 pending_status = None 

76 if peer in self.data["pending"]: 

77 pending_status = self.data["pending"][peer] 

78 

79 # Grab current status 

80 current_status = None 

81 if peer in self.data["current"]: 

82 current_status = self.data["current"][peer] 

83 

84 # Work out our status string 

85 status_str = "" 

86 if pending_status is None: 

87 status_str = colored("REMOVED", "magenta") 

88 elif current_status and not pending_status: 

89 status_str = colored("PENDING-GRACEFUL-SHUTDOWN-ENTER", "blue") 

90 elif not current_status and pending_status: 

91 status_str = colored("PENDING-GRACEFUL-SHUTDOWN-EXIT", "yellow") 

92 elif current_status is None: 

93 status_str = colored("NEW", "green") 

94 elif pending_status: 

95 status_str = colored("GRACEFUL-SHUTDOWN", "red") 

96 else: 

97 status_str = "OK" 

98 

99 ob.write(" Peer: " + colored(peer, "cyan") + "\n") 

100 ob.write(f" State: {status_str}\n") 

101 ob.write("\n") 

102 

103 return ob.getvalue() 

104 

105 

106class BirdPlanCmdlineBGPPeerGracefulShutdownShow(BirdPlanCmdlinePluginBase): 

107 """BirdPlan "bgp peer graceful-shutdown show" command.""" 

108 

109 def __init__(self) -> None: 

110 """Initialize object.""" 

111 

112 super().__init__() 

113 

114 # Plugin setup 

115 self.plugin_description = "birdplan bgp peer graceful-shutdown show" 

116 self.plugin_order = 30 

117 

118 def register_parsers(self, args: dict[str, Any]) -> None: 

119 """ 

120 Register commandline parsers. 

121 

122 Parameters 

123 ---------- 

124 args : Dict[str, Any] 

125 Method argument(s). 

126 

127 """ 

128 

129 plugins = args["plugins"] 

130 

131 parent_subparsers = plugins.call_plugin("birdplan.plugins.cmdline.bgp.peer.graceful_shutdown", "get_subparsers", {}) 

132 

133 # CMD: bgp peer graceful-shutdown show 

134 subparser = parent_subparsers.add_parser("show", help="Show BGP peer graceful shutdown status") 

135 subparser.add_argument( 

136 "--action", 

137 action="store_const", 

138 const="bgp_peer_graceful_shutdown_show", 

139 default="bgp_peer_graceful_shutdown_show", 

140 help=argparse.SUPPRESS, 

141 ) 

142 

143 # Set our internal subparser property 

144 self._subparser = subparser 

145 self._subparsers = None 

146 

147 def cmd_bgp_peer_graceful_shutdown_show(self, args: dict[str, Any]) -> BirdPlanCmdlineBGPPeerGracefulShutdownShowResult: 

148 """ 

149 Commandline handler for "bgp peer graceful-shutdown show" action. 

150 

151 Parameters 

152 ---------- 

153 args : Dict[str, Any] 

154 Method argument(s). 

155 

156 """ 

157 

158 if not self._subparser: 

159 raise RuntimeError 

160 

161 cmdline: BirdPlanCommandLine = args["cmdline"] 

162 

163 # Suppress info output 

164 cmdline.birdplan.birdconf.birdconfig_globals.suppress_info = True 

165 

166 # Load BirdPlan configuration using the cache 

167 cmdline.birdplan_load_config(ignore_irr_changes=True, ignore_peeringdb_changes=True, use_cached=True) 

168 

169 # Grab peer list 

170 res: BirdPlanBGPPeerGracefulShutdownStatus = cmdline.birdplan.state_bgp_peer_graceful_shutdown_status() 

171 

172 return BirdPlanCmdlineBGPPeerGracefulShutdownShowResult(res)