Coverage for src/birdplan/plugins/cmdline/ospf/summary.py: 48%
58 statements
« prev ^ index » next coverage.py v7.15.2, created at 2026-07-25 07:38 +0000
« 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/>.
19"""BirdPlan commandline options for OSPF summary."""
21import argparse
22import io
23from typing import Any
25from ....cmdline import BirdPlanCommandLine, BirdPlanCommandlineResult
26from ....console.colors import colored
27from ..cmdline_plugin import BirdPlanCmdlinePluginBase
29__all__ = ["BirdPlanCmdlineOSPFShow"]
32class BirdPlanCmdlineOSPFShowResult(BirdPlanCommandlineResult):
33 """BirdPlan OSPF summary result class."""
35 def as_text(self) -> str:
36 """
37 Return data as text.
39 Returns
40 -------
41 str
42 Data as text.
44 """
46 ob = io.StringIO()
48 # Write out header
49 ob.write(f"+{'=' * 130}+\n")
50 ob.write(f"| {'OSPF Summary'.center(128)} |\n")
51 ob.write(f"+{'-' * 34}+{'-' * 10}+{'-' * 10}+{'-' * 21}+{'-' * 51}+\n")
52 ob.write(
53 f"| {'Name'.center(32)} | {'Proto'.center(8)} | {'Status'.center(8)} | {'Since'.center(19)} | {'Info'.center(49)} |\n"
54 )
55 ob.write(f"+{'-' * 34}+{'-' * 10}+{'-' * 10}+{'-' * 21}+{'-' * 51}+\n")
57 # Loop with each protocol
58 for name, protocol_status in self.data.items():
59 ipv = "-"
60 if name.endswith("4"):
61 ipv = "ipv4"
62 elif name.endswith("6"):
63 ipv = "ipv6"
64 # Start with plain strings with no color
65 state: str = protocol_status["state"]
66 info: str = protocol_status["info"]
67 since: str = protocol_status["since"]
69 # NK - Update in peer_arg show too
70 # Check how we're going to color entries based on their state and info
71 state_out = f"{state[:8]}".center(8)
72 info_out = f"{info[:49]}".center(49)
73 if protocol_status["state"] == "down":
74 state_out = colored(f"{state[:8]}".center(8), "red")
75 if "info_extra" in protocol_status:
76 info += " - " + protocol_status["info_extra"]
77 info_out = colored(f"{info[:49]}".center(49), "red")
78 elif protocol_status["state"] == "up":
79 if protocol_status["info"] == "running":
80 state_out = colored(f"{state[:8]}".center(8), "green")
81 info_out = colored(f"{info[:49]}".center(49), "green")
83 # Center some columns
84 ipv_out = f"{ipv[:8]}".center(8)
86 # Write out info line
87 ob.write(f"| {name[:32]:<32} | {ipv_out} | {state_out} | {since[:19]:<19} | {info_out} |\n")
89 # Write out footer
90 ob.write(f"+{'=' * 130}+\n")
92 return ob.getvalue()
95class BirdPlanCmdlineOSPFShow(BirdPlanCmdlinePluginBase):
96 """BirdPlan "ospf summary" command."""
98 def __init__(self) -> None:
99 """Initialize object."""
101 super().__init__()
103 # Plugin setup
104 self.plugin_description = "birdplan ospf summary"
105 self.plugin_order = 20
107 def register_parsers(self, args: dict[str, Any]) -> None:
108 """
109 Register commandline parsers.
111 Parameters
112 ----------
113 args : Dict[str, Any]
114 Method argument(s).
116 """
118 plugins = args["plugins"]
120 parent_subparsers = plugins.call_plugin("birdplan.plugins.cmdline.ospf", "get_subparsers", {})
122 # CMD: ospf summary
123 subparser = parent_subparsers.add_parser("summary", help="OSPF summary commands")
124 subparser.add_argument(
125 "--action",
126 action="store_const",
127 const="ospf_summary",
128 default="ospf_summary",
129 help=argparse.SUPPRESS,
130 )
132 # Set our internal subparser property
133 self._subparser = subparser
134 self._subparsers = None
136 def cmd_ospf_summary(self, args: dict[str, Any]) -> BirdPlanCmdlineOSPFShowResult: # pylint: disable=unused-argument
137 """
138 Commandline handler for "ospf summary" action.
140 Parameters
141 ----------
142 args : Dict[str, Any]
143 Method argument(s).
145 """
147 if not self._subparser: # pragma: no cover
148 raise RuntimeError
150 cmdline: BirdPlanCommandLine = args["cmdline"]
152 # Grab Bird control socket
153 bird_socket = cmdline.args.bird_socket[0]
155 # Suppress info output
156 cmdline.birdplan.birdconf.birdconfig_globals.suppress_info = True
158 # Load BirdPlan configuration using the cache
159 cmdline.birdplan_load_config(ignore_irr_changes=True, ignore_peeringdb_changes=True, use_cached=True)
161 res = cmdline.birdplan.state_ospf_summary(bird_socket=bird_socket)
163 return BirdPlanCmdlineOSPFShowResult(res)