Coverage for birdplan/bird_config/sections/protocols/ospf/area/__init__.py: 97%

61 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"""BIRD OSPF area configuration.""" 

20 

21# pylint: disable=too-many-lines 

22 

23from typing import Any, Dict 

24 

25from ......exceptions import BirdPlanError 

26from .....globals import BirdConfigGlobals 

27from ....constants import SectionConstants 

28from ....functions import SectionFunctions 

29from ....tables import SectionTables 

30from ...base import SectionProtocolBase 

31from ..ospf_attributes import OSPFAttributes 

32from .area_attributes import OSPFAreaAttributes 

33from .interface import ProtocolOSPFAreaInterface 

34from .ospf_area_types import OSPFAreaConfig 

35 

36__all__ = ["ProtocolOSPFArea"] 

37 

38 

39OSPFAreaInterfaceConfig = Dict[str, Any] 

40OSPFAreaInterfaces = Dict[str, ProtocolOSPFAreaInterface] 

41 

42 

43class ProtocolOSPFArea(SectionProtocolBase): # pylint: disable=too-many-public-methods 

44 """BIRD OSPF area configuration.""" 

45 

46 # OSPF attributes 

47 _ospf_attributes: OSPFAttributes 

48 

49 # OSPF area attributes 

50 _area_attributes: OSPFAreaAttributes 

51 

52 # OSPF interfaces belonging to this area 

53 _interfaces: OSPFAreaInterfaces 

54 

55 def __init__( # noqa: CFQ002 # pylint: disable=too-many-arguments 

56 self, 

57 birdconfig_globals: BirdConfigGlobals, 

58 constants: SectionConstants, 

59 functions: SectionFunctions, 

60 tables: SectionTables, 

61 ospf_attributes: OSPFAttributes, 

62 area_name: str, 

63 area_config: OSPFAreaConfig, 

64 ): 

65 """Initialize the object.""" 

66 super().__init__(birdconfig_globals, constants, functions, tables) 

67 

68 # Setup OSPF attributes 

69 self._ospf_attributes = ospf_attributes 

70 

71 # Setup OSPF area attributes 

72 self._area_attributes = OSPFAreaAttributes() 

73 

74 # Interfaces 

75 self._interfaces = {} 

76 

77 # Set area name 

78 self.name = str(area_name) 

79 

80 if area_config: 

81 raise BirdPlanError("THIS SHOULD NOT HAPPEN UNTIL WE HAVE AREA CONFIG") 

82 

83 def configure(self) -> None: 

84 """Configure the OSPF area.""" 

85 

86 # Don't re-render the configuration, we're called twice for v4 and V6 

87 if self.conf.items: 

88 return 

89 

90 super().configure() 

91 

92 # Blank the OSPF area state 

93 if "ospf" not in self.birdconfig_globals.state: 

94 self.birdconfig_globals.state["ospf"] = {} 

95 if "areas" not in self.birdconfig_globals.state["ospf"]: 

96 self.birdconfig_globals.state["ospf"]["areas"] = {} 

97 if self.name not in self.birdconfig_globals.state["ospf"]["areas"]: 

98 self.birdconfig_globals.state["ospf"]["areas"][self.name] = {} 

99 if "interfaces" not in self.birdconfig_globals.state["ospf"]["areas"][self.name]: 

100 self.birdconfig_globals.state["ospf"]["areas"][self.name]["interfaces"] = {} 

101 

102 # Add area config block 

103 self.conf.add(f" area {self.name} {{") 

104 # Add interfaces 

105 for _, interface in sorted(self.interfaces.items()): 

106 self.conf.add(interface) 

107 # Close area config block 

108 self.conf.add(" };") 

109 

110 def add_interface(self, interface_name: str, interface_config: OSPFAreaConfig) -> ProtocolOSPFAreaInterface: 

111 """Add interface to OSPF.""" 

112 

113 # Make sure area interface doesn't exist 

114 if interface_name in self.interfaces: 

115 raise BirdPlanError(f"OSPF area '{self.name}'' interface '{interface_name}' already exists") 

116 

117 # Create OSPF area interface object 

118 interface = ProtocolOSPFAreaInterface( 

119 self.birdconfig_globals, 

120 self.constants, 

121 self.functions, 

122 self.tables, 

123 self.area_attributes, 

124 interface_name, 

125 interface_config, 

126 ) 

127 

128 # Add interface to the area 

129 self.interfaces[interface_name] = interface 

130 

131 return interface 

132 

133 @property 

134 def area_attributes(self) -> OSPFAreaAttributes: 

135 """OSPF area attributes.""" 

136 return self._area_attributes 

137 

138 @property 

139 def name(self) -> str: 

140 """Area name.""" 

141 return self.area_attributes.name 

142 

143 @name.setter 

144 def name(self, name: str) -> None: 

145 """Area name.""" 

146 self.area_attributes.name = name 

147 

148 @property 

149 def interfaces(self) -> OSPFAreaInterfaces: 

150 """OSPF area interfaces.""" 

151 return self._interfaces