Coverage for ipam/forms/filtersets.py: 100%

170 statements  

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

1from django import forms 

2from django.utils.translation import gettext_lazy as _ 

3 

4from dcim.models import Device, Location, Rack, RackGroup, Region, Site, SiteGroup 

5from ipam.choices import * 

6from ipam.constants import * 

7from ipam.models import * 

8from netbox.forms import NetBoxModelFilterSetForm, OrganizationalModelFilterSetForm, PrimaryModelFilterSetForm 

9from tenancy.forms import ContactModelFilterForm, TenancyFilterForm 

10from utilities.forms import BOOLEAN_WITH_BLANK_CHOICES, add_blank_choice 

11from utilities.forms.fields import DynamicModelChoiceField, DynamicModelMultipleChoiceField, TagFilterField 

12from utilities.forms.rendering import FieldSet 

13from virtualization.models import Cluster, ClusterGroup, VirtualMachine 

14from vpn.models import L2VPN 

15 

16__all__ = ( 

17 'ASNFilterForm', 

18 'ASNRangeFilterForm', 

19 'AggregateFilterForm', 

20 'FHRPGroupFilterForm', 

21 'IPAddressFilterForm', 

22 'IPRangeFilterForm', 

23 'PrefixFilterForm', 

24 'RIRFilterForm', 

25 'RoleFilterForm', 

26 'RouteTargetFilterForm', 

27 'ServiceFilterForm', 

28 'ServiceTemplateFilterForm', 

29 'VLANFilterForm', 

30 'VLANGroupFilterForm', 

31 'VLANTranslationPolicyFilterForm', 

32 'VLANTranslationRuleFilterForm', 

33 'VRFFilterForm', 

34) 

35 

36PREFIX_MASK_LENGTH_CHOICES = add_blank_choice([ 

37 (i, i) for i in range(PREFIX_LENGTH_MIN, PREFIX_LENGTH_MAX + 1) 

38]) 

39 

40IPADDRESS_MASK_LENGTH_CHOICES = add_blank_choice([ 

41 (i, i) for i in range(IPADDRESS_MASK_LENGTH_MIN, IPADDRESS_MASK_LENGTH_MAX + 1) 

42]) 

43 

44 

45class VRFFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm): 

46 model = VRF 

47 fieldsets = ( 

48 FieldSet('q', 'filter_id', 'tag'), 

49 FieldSet('import_target_id', 'export_target_id', name=_('Route Targets')), 

50 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

51 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

52 ) 

53 import_target_id = DynamicModelMultipleChoiceField( 

54 queryset=RouteTarget.objects.all(), 

55 required=False, 

56 label=_('Import targets') 

57 ) 

58 export_target_id = DynamicModelMultipleChoiceField( 

59 queryset=RouteTarget.objects.all(), 

60 required=False, 

61 label=_('Export targets') 

62 ) 

63 tag = TagFilterField(model) 

64 

65 

66class RouteTargetFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm): 

67 model = RouteTarget 

68 fieldsets = ( 

69 FieldSet('q', 'filter_id', 'tag'), 

70 FieldSet('importing_vrf_id', 'exporting_vrf_id', name=_('VRF')), 

71 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

72 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

73 ) 

74 importing_vrf_id = DynamicModelMultipleChoiceField( 

75 queryset=VRF.objects.all(), 

76 required=False, 

77 label=_('Imported by VRF') 

78 ) 

79 exporting_vrf_id = DynamicModelMultipleChoiceField( 

80 queryset=VRF.objects.all(), 

81 required=False, 

82 label=_('Exported by VRF') 

83 ) 

84 tag = TagFilterField(model) 

85 

86 

87class RIRFilterForm(OrganizationalModelFilterSetForm): 

88 model = RIR 

89 fieldsets = ( 

90 FieldSet('q', 'filter_id', 'tag'), 

91 FieldSet('is_private', name=_('RIR')), 

92 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

93 ) 

94 is_private = forms.NullBooleanField( 

95 required=False, 

96 label=_('Private'), 

97 widget=forms.Select( 

98 choices=BOOLEAN_WITH_BLANK_CHOICES 

99 ) 

100 ) 

101 tag = TagFilterField(model) 

102 

103 

104class AggregateFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm): 

105 model = Aggregate 

106 fieldsets = ( 

107 FieldSet('q', 'filter_id', 'tag'), 

108 FieldSet('family', 'rir_id', name=_('Attributes')), 

109 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

110 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

111 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), 

112 ) 

113 family = forms.ChoiceField( 

114 required=False, 

115 choices=add_blank_choice(IPAddressFamilyChoices), 

116 label=_('Address family') 

117 ) 

118 rir_id = DynamicModelMultipleChoiceField( 

119 queryset=RIR.objects.all(), 

120 required=False, 

121 label=_('RIR') 

122 ) 

123 tag = TagFilterField(model) 

124 

125 

126class ASNRangeFilterForm(TenancyFilterForm, OrganizationalModelFilterSetForm): 

127 model = ASNRange 

128 fieldsets = ( 

129 FieldSet('q', 'filter_id', 'tag'), 

130 FieldSet('rir_id', 'start', 'end', name=_('Range')), 

131 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

132 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

133 ) 

134 rir_id = DynamicModelMultipleChoiceField( 

135 queryset=RIR.objects.all(), 

136 required=False, 

137 label=_('RIR') 

138 ) 

139 start = forms.IntegerField( 

140 label=_('Start'), 

141 required=False 

142 ) 

143 end = forms.IntegerField( 

144 label=_('End'), 

145 required=False 

146 ) 

147 tag = TagFilterField(model) 

148 

149 

150class ASNFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm): 

151 model = ASN 

152 fieldsets = ( 

153 FieldSet('q', 'filter_id', 'tag'), 

154 FieldSet('rir_id', 'role_id', 'site_group_id', 'site_id', name=_('Assignment')), 

155 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

156 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

157 ) 

158 rir_id = DynamicModelMultipleChoiceField( 

159 queryset=RIR.objects.all(), 

160 required=False, 

161 label=_('RIR') 

162 ) 

163 role_id = DynamicModelMultipleChoiceField( 

164 queryset=Role.objects.all(), 

165 required=False, 

166 label=_('Role') 

167 ) 

168 site_group_id = DynamicModelMultipleChoiceField( 

169 queryset=SiteGroup.objects.all(), 

170 required=False, 

171 label=_('Site group') 

172 ) 

173 site_id = DynamicModelMultipleChoiceField( 

174 queryset=Site.objects.all(), 

175 required=False, 

176 label=_('Site') 

177 ) 

178 tag = TagFilterField(model) 

179 

180 

181class RoleFilterForm(OrganizationalModelFilterSetForm): 

182 model = Role 

183 fieldsets = ( 

184 FieldSet('q', 'filter_id', 'tag'), 

185 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

186 ) 

187 tag = TagFilterField(model) 

188 

189 

190class PrefixFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm): 

191 model = Prefix 

192 fieldsets = ( 

193 FieldSet('q', 'filter_id', 'tag'), 

194 FieldSet( 

195 'within_include', 'family', 'status', 'role_id', 'mask_length', 'is_pool', 'mark_utilized', 

196 name=_('Addressing') 

197 ), 

198 FieldSet('vlan_group_id', 'vlan_id', name=_('VLAN Assignment')), 

199 FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')), 

200 FieldSet('region_id', 'site_group_id', 'site_id', 'location_id', name=_('Scope')), 

201 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

202 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

203 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), 

204 ) 

205 mask_length__lte = forms.IntegerField( 

206 widget=forms.HiddenInput() 

207 ) 

208 within_include = forms.CharField( 

209 required=False, 

210 widget=forms.TextInput( 

211 attrs={ 

212 'placeholder': 'Prefix', 

213 } 

214 ), 

215 label=_('Search within') 

216 ) 

217 family = forms.ChoiceField( 

218 required=False, 

219 choices=add_blank_choice(IPAddressFamilyChoices), 

220 label=_('Address family') 

221 ) 

222 mask_length = forms.MultipleChoiceField( 

223 required=False, 

224 choices=PREFIX_MASK_LENGTH_CHOICES, 

225 label=_('Mask length') 

226 ) 

227 vrf_id = DynamicModelMultipleChoiceField( 

228 queryset=VRF.objects.all(), 

229 required=False, 

230 label=_('Assigned VRF'), 

231 null_option='Global' 

232 ) 

233 present_in_vrf_id = DynamicModelChoiceField( 

234 queryset=VRF.objects.all(), 

235 required=False, 

236 label=_('Present in VRF') 

237 ) 

238 status = forms.MultipleChoiceField( 

239 label=_('Status'), 

240 choices=PrefixStatusChoices, 

241 required=False 

242 ) 

243 region_id = DynamicModelMultipleChoiceField( 

244 queryset=Region.objects.all(), 

245 required=False, 

246 label=_('Region') 

247 ) 

248 site_group_id = DynamicModelMultipleChoiceField( 

249 queryset=SiteGroup.objects.all(), 

250 required=False, 

251 label=_('Site group') 

252 ) 

253 site_id = DynamicModelMultipleChoiceField( 

254 queryset=Site.objects.all(), 

255 required=False, 

256 label=_('Site') 

257 ) 

258 location_id = DynamicModelMultipleChoiceField( 

259 queryset=Location.objects.all(), 

260 required=False, 

261 label=_('Location') 

262 ) 

263 role_id = DynamicModelMultipleChoiceField( 

264 queryset=Role.objects.all(), 

265 required=False, 

266 null_option='None', 

267 label=_('Role') 

268 ) 

269 is_pool = forms.NullBooleanField( 

270 required=False, 

271 label=_('Is a pool'), 

272 widget=forms.Select( 

273 choices=BOOLEAN_WITH_BLANK_CHOICES 

274 ) 

275 ) 

276 mark_utilized = forms.NullBooleanField( 

277 required=False, 

278 label=_('Treat as fully utilized'), 

279 widget=forms.Select( 

280 choices=BOOLEAN_WITH_BLANK_CHOICES 

281 ) 

282 ) 

283 vlan_group_id = DynamicModelMultipleChoiceField( 

284 queryset=VLANGroup.objects.all(), 

285 required=False, 

286 label=_('VLAN Group'), 

287 ) 

288 vlan_id = DynamicModelMultipleChoiceField( 

289 queryset=VLAN.objects.all(), 

290 required=False, 

291 label=_('VLAN'), 

292 ) 

293 

294 tag = TagFilterField(model) 

295 

296 

297class IPRangeFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm): 

298 model = IPRange 

299 fieldsets = ( 

300 FieldSet('q', 'filter_id', 'tag'), 

301 FieldSet('family', 'vrf_id', 'status', 'role_id', 'mark_populated', 'mark_utilized', name=_('Attributes')), 

302 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

303 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

304 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), 

305 ) 

306 family = forms.ChoiceField( 

307 required=False, 

308 choices=add_blank_choice(IPAddressFamilyChoices), 

309 label=_('Address family') 

310 ) 

311 vrf_id = DynamicModelMultipleChoiceField( 

312 queryset=VRF.objects.all(), 

313 required=False, 

314 label=_('Assigned VRF'), 

315 null_option='Global' 

316 ) 

317 status = forms.MultipleChoiceField( 

318 label=_('Status'), 

319 choices=IPRangeStatusChoices, 

320 required=False 

321 ) 

322 role_id = DynamicModelMultipleChoiceField( 

323 queryset=Role.objects.all(), 

324 required=False, 

325 null_option='None', 

326 label=_('Role') 

327 ) 

328 mark_populated = forms.NullBooleanField( 

329 required=False, 

330 label=_('Treat as populated'), 

331 widget=forms.Select( 

332 choices=BOOLEAN_WITH_BLANK_CHOICES 

333 ) 

334 ) 

335 mark_utilized = forms.NullBooleanField( 

336 required=False, 

337 label=_('Treat as fully utilized'), 

338 widget=forms.Select( 

339 choices=BOOLEAN_WITH_BLANK_CHOICES 

340 ) 

341 ) 

342 tag = TagFilterField(model) 

343 

344 

345class IPAddressFilterForm(ContactModelFilterForm, TenancyFilterForm, PrimaryModelFilterSetForm): 

346 model = IPAddress 

347 fieldsets = ( 

348 FieldSet('q', 'filter_id', 'tag'), 

349 FieldSet( 

350 'parent', 'family', 'status', 'role', 'mask_length', 'assigned_to_interface', 'dns_name', 

351 name=_('Attributes') 

352 ), 

353 FieldSet('vrf_id', 'present_in_vrf_id', name=_('VRF')), 

354 FieldSet('device_id', 'virtual_machine_id', name=_('Device/VM')), 

355 FieldSet('nat_inside_id', name=_('NAT')), 

356 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

357 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

358 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), 

359 ) 

360 selector_fields = ('filter_id', 'q', 'region_id', 'group_id', 'parent', 'status', 'role') 

361 parent = forms.CharField( 

362 required=False, 

363 widget=forms.TextInput( 

364 attrs={ 

365 'placeholder': 'Prefix', 

366 } 

367 ), 

368 label=_('Parent Prefix') 

369 ) 

370 family = forms.ChoiceField( 

371 required=False, 

372 choices=add_blank_choice(IPAddressFamilyChoices), 

373 label=_('Address family') 

374 ) 

375 mask_length = forms.ChoiceField( 

376 required=False, 

377 choices=IPADDRESS_MASK_LENGTH_CHOICES, 

378 label=_('Mask length') 

379 ) 

380 vrf_id = DynamicModelMultipleChoiceField( 

381 queryset=VRF.objects.all(), 

382 required=False, 

383 label=_('Assigned VRF'), 

384 null_option='Global' 

385 ) 

386 present_in_vrf_id = DynamicModelChoiceField( 

387 queryset=VRF.objects.all(), 

388 required=False, 

389 label=_('Present in VRF') 

390 ) 

391 device_id = DynamicModelMultipleChoiceField( 

392 queryset=Device.objects.all(), 

393 required=False, 

394 label=_('Assigned Device'), 

395 ) 

396 virtual_machine_id = DynamicModelMultipleChoiceField( 

397 queryset=VirtualMachine.objects.all(), 

398 required=False, 

399 label=_('Assigned VM'), 

400 ) 

401 nat_inside_id = DynamicModelMultipleChoiceField( 

402 queryset=IPAddress.objects.all(), 

403 required=False, 

404 label=_('NAT inside'), 

405 ) 

406 status = forms.MultipleChoiceField( 

407 label=_('Status'), 

408 choices=IPAddressStatusChoices, 

409 required=False 

410 ) 

411 role = forms.MultipleChoiceField( 

412 label=_('Role'), 

413 choices=IPAddressRoleChoices, 

414 required=False 

415 ) 

416 assigned_to_interface = forms.NullBooleanField( 

417 required=False, 

418 label=_('Assigned to an interface'), 

419 widget=forms.Select( 

420 choices=BOOLEAN_WITH_BLANK_CHOICES 

421 ) 

422 ) 

423 dns_name = forms.CharField( 

424 required=False, 

425 label=_('DNS Name') 

426 ) 

427 tag = TagFilterField(model) 

428 

429 

430class FHRPGroupFilterForm(PrimaryModelFilterSetForm): 

431 model = FHRPGroup 

432 fieldsets = ( 

433 FieldSet('q', 'filter_id', 'tag'), 

434 FieldSet('name', 'protocol', 'group_id', name=_('Attributes')), 

435 FieldSet('auth_type', 'auth_key', name=_('Authentication')), 

436 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

437 ) 

438 name = forms.CharField( 

439 label=_('Name'), 

440 required=False 

441 ) 

442 protocol = forms.MultipleChoiceField( 

443 label=_('Protocol'), 

444 choices=FHRPGroupProtocolChoices, 

445 required=False 

446 ) 

447 group_id = forms.IntegerField( 

448 min_value=0, 

449 required=False, 

450 label=_('Group ID') 

451 ) 

452 auth_type = forms.MultipleChoiceField( 

453 choices=FHRPGroupAuthTypeChoices, 

454 required=False, 

455 label=_('Authentication type') 

456 ) 

457 auth_key = forms.CharField( 

458 required=False, 

459 label=_('Authentication key') 

460 ) 

461 tag = TagFilterField(model) 

462 

463 

464class VLANGroupFilterForm(TenancyFilterForm, OrganizationalModelFilterSetForm): 

465 fieldsets = ( 

466 FieldSet('q', 'filter_id', 'tag'), 

467 FieldSet('region', 'site_group', 'site', 'location', 'rack_group', 'rack', name=_('Location')), 

468 FieldSet('cluster_group', 'cluster', name=_('Cluster')), 

469 FieldSet('contains_vid', 'total_vlan_ids', name=_('VLANs')), 

470 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

471 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

472 ) 

473 model = VLANGroup 

474 region = DynamicModelMultipleChoiceField( 

475 queryset=Region.objects.all(), 

476 required=False, 

477 label=_('Region') 

478 ) 

479 site_group = DynamicModelMultipleChoiceField( 

480 queryset=SiteGroup.objects.all(), 

481 required=False, 

482 label=_('Site group') 

483 ) 

484 site = DynamicModelMultipleChoiceField( 

485 queryset=Site.objects.all(), 

486 required=False, 

487 label=_('Site') 

488 ) 

489 location = DynamicModelMultipleChoiceField( 

490 queryset=Location.objects.all(), 

491 required=False, 

492 label=_('Location') 

493 ) 

494 rack_group = DynamicModelMultipleChoiceField( 

495 queryset=RackGroup.objects.all(), 

496 required=False, 

497 label=_('Rack group') 

498 ) 

499 rack = DynamicModelMultipleChoiceField( 

500 queryset=Rack.objects.all(), 

501 required=False, 

502 label=_('Rack') 

503 ) 

504 cluster = DynamicModelMultipleChoiceField( 

505 queryset=Cluster.objects.all(), 

506 required=False, 

507 label=_('Cluster') 

508 ) 

509 cluster_group = DynamicModelMultipleChoiceField( 

510 queryset=ClusterGroup.objects.all(), 

511 required=False, 

512 label=_('Cluster group') 

513 ) 

514 contains_vid = forms.IntegerField( 

515 min_value=0, 

516 required=False, 

517 label=_('Contains VLAN ID') 

518 ) 

519 total_vlan_ids = forms.IntegerField( 

520 min_value=0, 

521 required=False, 

522 label=_('Total VLAN IDs') 

523 ) 

524 

525 tag = TagFilterField(model) 

526 

527 

528class VLANTranslationPolicyFilterForm(PrimaryModelFilterSetForm): 

529 model = VLANTranslationPolicy 

530 fieldsets = ( 

531 FieldSet('q', 'filter_id', 'tag'), 

532 FieldSet('name', name=_('Attributes')), 

533 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

534 ) 

535 name = forms.CharField( 

536 required=False, 

537 label=_('Name') 

538 ) 

539 tag = TagFilterField(model) 

540 

541 

542class VLANTranslationRuleFilterForm(NetBoxModelFilterSetForm): 

543 model = VLANTranslationRule 

544 fieldsets = ( 

545 FieldSet('q', 'filter_id', 'tag'), 

546 FieldSet('policy_id', 'local_vid', 'remote_vid', name=_('Attributes')), 

547 ) 

548 tag = TagFilterField(model) 

549 policy_id = DynamicModelMultipleChoiceField( 

550 queryset=VLANTranslationPolicy.objects.all(), 

551 required=False, 

552 label=_('VLAN Translation Policy') 

553 ) 

554 local_vid = forms.IntegerField( 

555 min_value=1, 

556 required=False, 

557 label=_('Local VLAN ID') 

558 ) 

559 remote_vid = forms.IntegerField( 

560 min_value=1, 

561 required=False, 

562 label=_('Remote VLAN ID') 

563 ) 

564 

565 

566class VLANFilterForm(TenancyFilterForm, PrimaryModelFilterSetForm): 

567 model = VLAN 

568 fieldsets = ( 

569 FieldSet('q', 'filter_id', 'tag'), 

570 FieldSet('region_id', 'site_group_id', 'site_id', 'related_to_site', name=_('Location')), 

571 FieldSet('group_id', 'status', 'role_id', 'vid', 'l2vpn_id', name=_('Attributes')), 

572 FieldSet('qinq_role', 'qinq_svlan_id', name=_('Q-in-Q/802.1ad')), 

573 FieldSet('tenant_group_id', 'tenant_id', name=_('Tenant')), 

574 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

575 ) 

576 selector_fields = ('filter_id', 'q', 'group_id') 

577 region_id = DynamicModelMultipleChoiceField( 

578 queryset=Region.objects.all(), 

579 required=False, 

580 label=_('Region') 

581 ) 

582 site_group_id = DynamicModelMultipleChoiceField( 

583 queryset=SiteGroup.objects.all(), 

584 required=False, 

585 label=_('Site group') 

586 ) 

587 site_id = DynamicModelMultipleChoiceField( 

588 queryset=Site.objects.all(), 

589 required=False, 

590 null_option='None', 

591 query_params={ 

592 'region': '$region' 

593 }, 

594 label=_('Site') 

595 ) 

596 related_to_site = DynamicModelMultipleChoiceField( 

597 queryset=Site.objects.all(), 

598 required=False, 

599 label=_('Related to site') 

600 ) 

601 group_id = DynamicModelMultipleChoiceField( 

602 queryset=VLANGroup.objects.all(), 

603 required=False, 

604 null_option='None', 

605 query_params={ 

606 'region': '$region' 

607 }, 

608 label=_('VLAN group') 

609 ) 

610 status = forms.MultipleChoiceField( 

611 label=_('Status'), 

612 choices=VLANStatusChoices, 

613 required=False 

614 ) 

615 role_id = DynamicModelMultipleChoiceField( 

616 queryset=Role.objects.all(), 

617 required=False, 

618 null_option='None', 

619 label=_('Role') 

620 ) 

621 vid = forms.IntegerField( 

622 required=False, 

623 label=_('VLAN ID') 

624 ) 

625 qinq_role = forms.MultipleChoiceField( 

626 label=_('Q-in-Q role'), 

627 choices=VLANQinQRoleChoices, 

628 required=False 

629 ) 

630 qinq_svlan_id = DynamicModelMultipleChoiceField( 

631 queryset=VLAN.objects.all(), 

632 required=False, 

633 null_option='None', 

634 label=_('Q-in-Q SVLAN') 

635 ) 

636 l2vpn_id = DynamicModelMultipleChoiceField( 

637 queryset=L2VPN.objects.all(), 

638 required=False, 

639 label=_('L2VPN') 

640 ) 

641 tag = TagFilterField(model) 

642 

643 

644class ServiceTemplateFilterForm(PrimaryModelFilterSetForm): 

645 model = ServiceTemplate 

646 fieldsets = ( 

647 FieldSet('q', 'filter_id', 'tag'), 

648 FieldSet('port_mappings', 'protocol', 'port', name=_('Attributes')), 

649 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

650 ) 

651 # A complete protocol/port pair, matched as a whole. Unlike `protocol` and `port` (which are 

652 # correlated but independently specified), this is a single free-text value: an unknown protocol or 

653 # malformed pair simply matches nothing, so no client-side validation is needed here. 

654 port_mappings = forms.CharField( 

655 label=_('Port mapping'), 

656 required=False, 

657 widget=forms.TextInput( 

658 attrs={ 

659 'placeholder': 'e.g. tcp/80', 

660 } 

661 ) 

662 ) 

663 protocol = forms.MultipleChoiceField( 

664 label=_('Protocol'), 

665 choices=ServiceProtocolChoices, 

666 required=False 

667 ) 

668 port = forms.IntegerField( 

669 label=_('Port'), 

670 required=False, 

671 ) 

672 tag = TagFilterField(model) 

673 

674 

675class ServiceFilterForm(ContactModelFilterForm, ServiceTemplateFilterForm): 

676 model = Service 

677 fieldsets = ( 

678 FieldSet('q', 'filter_id', 'tag'), 

679 FieldSet('port_mappings', 'protocol', 'port', name=_('Attributes')), 

680 FieldSet('device_id', 'virtual_machine_id', 'fhrpgroup_id', name=_('Assignment')), 

681 FieldSet('owner_group_id', 'owner_id', name=_('Ownership')), 

682 FieldSet('contact', 'contact_role', 'contact_group', name=_('Contacts')), 

683 ) 

684 device_id = DynamicModelMultipleChoiceField( 

685 queryset=Device.objects.all(), 

686 required=False, 

687 label=_('Device'), 

688 ) 

689 virtual_machine_id = DynamicModelMultipleChoiceField( 

690 queryset=VirtualMachine.objects.all(), 

691 required=False, 

692 label=_('Virtual Machine'), 

693 ) 

694 fhrpgroup_id = DynamicModelMultipleChoiceField( 

695 queryset=FHRPGroup.objects.all(), 

696 required=False, 

697 label=_('FHRP Group'), 

698 ) 

699 tag = TagFilterField(model)