Coverage for ipam/tables/vlans.py: 100%

82 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1import django_tables2 as tables 

2from django.utils.safestring import mark_safe 

3from django.utils.translation import gettext_lazy as _ 

4 

5from dcim.models import Interface 

6from dcim.tables.template_code import INTERFACE_LINKTERMINATION, LINKTERMINATION 

7from ipam.models import * 

8from netbox.tables import NetBoxTable, OrganizationalModelTable, PrimaryModelTable, columns 

9from tenancy.tables import TenancyColumnsMixin 

10from virtualization.models import VMInterface 

11 

12from .template_code import * 

13 

14__all__ = ( 

15 'VLANDevicesTable', 

16 'VLANGroupTable', 

17 'VLANMembersTable', 

18 'VLANTable', 

19 'VLANTranslationPolicyTable', 

20 'VLANTranslationRuleTable', 

21 'VLANVirtualMachinesTable', 

22) 

23 

24AVAILABLE_LABEL = mark_safe('<span class="badge text-bg-success">Available</span>') 

25 

26 

27# 

28# VLAN groups 

29# 

30 

31class VLANGroupTable(TenancyColumnsMixin, OrganizationalModelTable): 

32 name = tables.Column( 

33 verbose_name=_('Name'), 

34 linkify=True 

35 ) 

36 scope_type = columns.ContentTypeColumn( 

37 verbose_name=_('Scope Type'), 

38 ) 

39 scope = tables.Column( 

40 verbose_name=_('Scope'), 

41 linkify=True, 

42 orderable=False 

43 ) 

44 vid_ranges_list = columns.ArrayColumn( 

45 accessor='vid_ranges_items', 

46 verbose_name=_('VID Ranges'), 

47 orderable=False 

48 ) 

49 vlan_count = columns.LinkedCountColumn( 

50 viewname='ipam:vlan_list', 

51 url_params={'group_id': 'pk'}, 

52 verbose_name=_('VLANs') 

53 ) 

54 total_vlan_ids = tables.Column( 

55 verbose_name=_('Total VLAN IDs'), 

56 ) 

57 utilization = columns.UtilizationColumn( 

58 orderable=False, 

59 verbose_name=_('Utilization') 

60 ) 

61 tags = columns.TagColumn( 

62 url_name='ipam:vlangroup_list' 

63 ) 

64 actions = columns.ActionsColumn( 

65 extra_buttons=VLANGROUP_BUTTONS 

66 ) 

67 

68 class Meta(OrganizationalModelTable.Meta): 

69 model = VLANGroup 

70 fields = ( 

71 'pk', 'id', 'name', 'slug', 'description', 'scope_type', 'scope', 'vid_ranges_list', 'vlan_count', 

72 'total_vlan_ids', 'tenant', 'tenant_group', 'comments', 'tags', 'created', 'last_updated', 'actions', 

73 'utilization', 

74 ) 

75 default_columns = ( 

76 'pk', 'name', 'scope_type', 'scope', 'vlan_count', 'utilization', 'tenant', 'description' 

77 ) 

78 

79 

80# 

81# VLANs 

82# 

83 

84class VLANTable(TenancyColumnsMixin, PrimaryModelTable): 

85 vid = tables.TemplateColumn( 

86 template_code=VLAN_LINK, 

87 verbose_name=_('VID') 

88 ) 

89 name = tables.Column( 

90 verbose_name=_('Name'), 

91 linkify=True 

92 ) 

93 site = tables.Column( 

94 verbose_name=_('Site'), 

95 linkify=True 

96 ) 

97 group = tables.Column( 

98 verbose_name=_('Group'), 

99 linkify=True 

100 ) 

101 status = columns.ChoiceFieldColumn( 

102 verbose_name=_('Status'), 

103 default=AVAILABLE_LABEL 

104 ) 

105 role = tables.Column( 

106 verbose_name=_('Role'), 

107 linkify=True 

108 ) 

109 qinq_role = columns.ChoiceFieldColumn( 

110 verbose_name=_('Q-in-Q role') 

111 ) 

112 qinq_svlan = tables.Column( 

113 verbose_name=_('Q-in-Q SVLAN'), 

114 linkify=True 

115 ) 

116 l2vpn = tables.Column( 

117 accessor=tables.A('l2vpn_termination__l2vpn'), 

118 linkify=True, 

119 orderable=False, 

120 verbose_name=_('L2VPN') 

121 ) 

122 prefixes = columns.TemplateColumn( 

123 template_code=VLAN_PREFIXES, 

124 orderable=False, 

125 verbose_name=_('Prefixes') 

126 ) 

127 tags = columns.TagColumn( 

128 url_name='ipam:vlan_list' 

129 ) 

130 

131 class Meta(PrimaryModelTable.Meta): 

132 model = VLAN 

133 fields = ( 

134 'pk', 'id', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'tenant_group', 'status', 'role', 

135 'qinq_role', 'qinq_svlan', 'description', 'comments', 'tags', 'l2vpn', 'created', 'last_updated', 

136 ) 

137 default_columns = ('pk', 'vid', 'name', 'site', 'group', 'prefixes', 'tenant', 'status', 'role', 'description') 

138 row_attrs = { 

139 'class': lambda record: 'success' if not isinstance(record, VLAN) else '', 

140 } 

141 

142 

143class VLANMembersTable(NetBoxTable): 

144 """ 

145 Base table for Interface and VMInterface assignments 

146 """ 

147 name = tables.Column( 

148 linkify=True, 

149 verbose_name=_('Interface') 

150 ) 

151 tagged = tables.TemplateColumn( 

152 verbose_name=_('Tagged'), 

153 template_code=VLAN_MEMBER_TAGGED, 

154 orderable=False 

155 ) 

156 

157 

158class VLANDevicesTable(VLANMembersTable): 

159 device = tables.Column( 

160 verbose_name=_('Device'), 

161 linkify=True 

162 ) 

163 actions = columns.ActionsColumn( 

164 actions=('edit',) 

165 ) 

166 link_peer = columns.TemplateColumn( 

167 accessor='link_peers', 

168 template_code=LINKTERMINATION, 

169 orderable=False, 

170 verbose_name=_('Link Peers'), 

171 ) 

172 

173 # Override PathEndpointTable.connection to accommodate virtual circuits 

174 connection = columns.TemplateColumn( 

175 accessor='_path__destinations', 

176 template_code=INTERFACE_LINKTERMINATION, 

177 orderable=False, 

178 verbose_name=_('Connection'), 

179 ) 

180 

181 class Meta(NetBoxTable.Meta): 

182 model = Interface 

183 fields = ('device', 'name', 'link_peer', 'connection', 'tagged', 'actions') 

184 default_columns = ('device', 'name', 'connection', 'tagged', 'actions') 

185 exclude = ('id',) 

186 

187 

188class VLANVirtualMachinesTable(VLANMembersTable): 

189 virtual_machine = tables.Column( 

190 verbose_name=_('Virtual Machine'), 

191 linkify=True 

192 ) 

193 actions = columns.ActionsColumn( 

194 actions=('edit',) 

195 ) 

196 

197 class Meta(NetBoxTable.Meta): 

198 model = VMInterface 

199 fields = ('virtual_machine', 'name', 'tagged', 'actions') 

200 exclude = ('id', ) 

201 

202 

203# 

204# VLAN Translation 

205# 

206 

207class VLANTranslationPolicyTable(PrimaryModelTable): 

208 name = tables.Column( 

209 verbose_name=_('Name'), 

210 linkify=True 

211 ) 

212 rule_count = columns.LinkedCountColumn( 

213 viewname='ipam:vlantranslationrule_list', 

214 url_params={'policy_id': 'pk'}, 

215 verbose_name=_('Rules') 

216 ) 

217 description = tables.Column( 

218 verbose_name=_('Description'), 

219 ) 

220 tags = columns.TagColumn( 

221 url_name='ipam:vlantranslationpolicy_list' 

222 ) 

223 

224 class Meta(PrimaryModelTable.Meta): 

225 model = VLANTranslationPolicy 

226 fields = ( 

227 'pk', 'id', 'name', 'rule_count', 'description', 'tags', 'created', 'last_updated', 

228 ) 

229 default_columns = ('pk', 'name', 'rule_count', 'description') 

230 

231 

232class VLANTranslationRuleTable(NetBoxTable): 

233 policy = tables.Column( 

234 verbose_name=_('Policy'), 

235 linkify=True 

236 ) 

237 local_vid = tables.Column( 

238 verbose_name=_('Local VID'), 

239 linkify=True 

240 ) 

241 remote_vid = tables.Column( 

242 verbose_name=_('Remote VID'), 

243 ) 

244 description = tables.Column( 

245 verbose_name=_('Description'), 

246 ) 

247 tags = columns.TagColumn( 

248 url_name='ipam:vlantranslationrule_list' 

249 ) 

250 

251 class Meta(NetBoxTable.Meta): 

252 model = VLANTranslationRule 

253 fields = ( 

254 'pk', 'id', 'policy', 'local_vid', 'remote_vid', 'description', 'tags', 'created', 'last_updated', 

255 ) 

256 default_columns = ('pk', 'policy', 'local_vid', 'remote_vid', 'description')