Coverage for birdplan/plugins/cmdline/ospf/summary.py: 50%

60 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-04-23 03:27 +0000

1# 

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

3# 

4# Copyright (c) 2019-2024, 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 OSPF summary.""" 

20 

21import argparse 

22import io 

23from typing import Any, Dict 

24 

25from .... import BirdPlanOSPFSummary 

26from ....cmdline import BirdPlanCommandLine, BirdPlanCommandlineResult 

27from ....console.colors import colored 

28from ..cmdline_plugin import BirdPlanCmdlinePluginBase 

29 

30__all__ = ["BirdPlanCmdlineOSPFShow"] 

31 

32 

33class BirdPlanCmdlineOSPFShowResult(BirdPlanCommandlineResult): 

34 """BirdPlan OSPF summary result class.""" 

35 

36 def as_text(self) -> str: 

37 """ 

38 Return data as text. 

39 

40 Returns 

41 ------- 

42 str 

43 Data as text. 

44 

45 """ 

46 

47 ob = io.StringIO() 

48 

49 # Write out header 

50 ob.write(f"+{'='*130}+\n") 

51 ob.write(f"| {'OSPF Summary'.center(128)} |\n") 

52 ob.write(f"+{'-'*34}+{'-'*10}+{'-'*10}+{'-'*21}+{'-'*51}+\n") 

53 ob.write( 

54 f"| {'Name'.center(32)} " 

55 f"| {'Proto'.center(8)} " 

56 f"| {'Status'.center(8)} " 

57 f"| {'Since'.center(19)} " 

58 f"| {'Info'.center(49)} |\n" 

59 ) 

60 ob.write(f"+{'-'*34}+{'-'*10}+{'-'*10}+{'-'*21}+{'-'*51}+\n") 

61 

62 # Loop with each protocol 

63 for name, protocol_status in self.data.items(): 

64 ipv = "-" 

65 if name.endswith("4"): 

66 ipv = "ipv4" 

67 elif name.endswith("6"): 

68 ipv = "ipv6" 

69 # Start with plain strings with no color 

70 state: str = protocol_status["state"] 

71 info: str = protocol_status["info"] 

72 since: str = protocol_status["since"] 

73 

74 # NK - Update in peer_arg show too 

75 # Check how we're going to color entries based on their state and info 

76 state_out = f"{state[:8]}".center(8) 

77 info_out = f"{info[:49]}".center(49) 

78 if protocol_status["state"] == "down": 

79 state_out = colored(f"{state[:8]}".center(8), "red") 

80 if "info_extra" in protocol_status: 

81 info += " - " + protocol_status["info_extra"] 

82 info_out = colored(f"{info[:49]}".center(49), "red") 

83 elif protocol_status["state"] == "up": # noqa: SIM102 

84 if protocol_status["info"] == "running": 

85 state_out = colored(f"{state[:8]}".center(8), "green") 

86 info_out = colored(f"{info[:49]}".center(49), "green") 

87 

88 # Center some columns 

89 ipv_out = f"{ipv[:8]}".center(8) 

90 

91 # Write out info line 

92 ob.write(f"| {name[:32]:<32} | {ipv_out} | {state_out} | {since[:19]:<19} | {info_out} |\n") 

93 

94 # Write out footer 

95 ob.write(f"+{'='*130}+\n") 

96 

97 return ob.getvalue() 

98 

99 

100class BirdPlanCmdlineOSPFShow(BirdPlanCmdlinePluginBase): 

101 """BirdPlan "ospf summary" command.""" 

102 

103 def __init__(self) -> None: 

104 """Initialize object.""" 

105 

106 super().__init__() 

107 

108 # Plugin setup 

109 self.plugin_description = "birdplan ospf summary" 

110 self.plugin_order = 20 

111 

112 def register_parsers(self, args: Dict[str, Any]) -> None: 

113 """ 

114 Register commandline parsers. 

115 

116 Parameters 

117 ---------- 

118 args : Dict[str, Any] 

119 Method argument(s). 

120 

121 """ 

122 

123 plugins = args["plugins"] 

124 

125 parent_subparsers = plugins.call_plugin("birdplan.plugins.cmdline.ospf", "get_subparsers", {}) 

126 

127 # CMD: ospf summary 

128 subparser = parent_subparsers.add_parser("summary", help="OSPF summary commands") 

129 subparser.add_argument( 

130 "--action", 

131 action="store_const", 

132 const="ospf_summary", 

133 default="ospf_summary", 

134 help=argparse.SUPPRESS, 

135 ) 

136 

137 # Set our internal subparser property 

138 self._subparser = subparser 

139 self._subparsers = None 

140 

141 def cmd_ospf_summary(self, args: Any) -> Any: # pylint: disable=unused-argument 

142 """ 

143 Commandline handler for "ospf summary" action. 

144 

145 Parameters 

146 ---------- 

147 args : Dict[str, Any] 

148 Method argument(s). 

149 

150 """ 

151 

152 if not self._subparser: # pragma: no cover 

153 raise RuntimeError() 

154 

155 cmdline: BirdPlanCommandLine = args["cmdline"] 

156 

157 # Grab Bird control socket 

158 bird_socket = cmdline.args.bird_socket[0] 

159 

160 # Suppress info output 

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

162 

163 # Load BirdPlan configuration using the cache 

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

165 

166 res: BirdPlanOSPFSummary = cmdline.birdplan.state_ospf_summary(bird_socket=bird_socket) 

167 

168 return BirdPlanCmdlineOSPFShowResult(res)