forward-netbox 3.0.0__tar.gz → 3.0.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (610) hide show
  1. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/PKG-INFO +11 -8
  2. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/README.md +5 -3
  3. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/__init__.py +1 -1
  4. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/api/serializers.py +7 -0
  5. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/api/views.py +298 -9
  6. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/criteria.py +3 -1
  7. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/choices.py +11 -0
  8. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/filtersets.py +34 -0
  9. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/forms.py +125 -7
  10. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/jobs.py +558 -6
  11. forward_netbox-3.0.2/forward_netbox/management/commands/forward_apic_cimc_readiness_audit.py +53 -0
  12. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_device_scope_reconciliation_audit.py +67 -1
  13. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_module_readiness.py +5 -2
  14. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_profile_merge.py +57 -1
  15. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_pushdown_profile.py +5 -2
  16. forward_netbox-3.0.2/forward_netbox/management/commands/forward_routing_dangling_audit.py +31 -0
  17. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_smoke_sync.py +13 -1
  18. forward_netbox-3.0.2/forward_netbox/migrations/0053_routing_policy_nqe_map_choices.py +18 -0
  19. forward_netbox-3.0.2/forward_netbox/migrations/0054_aci_tenant_policy_nqe_map_choices.py +18 -0
  20. forward_netbox-3.0.2/forward_netbox/migrations/0055_operator_delete_releases_ownership.py +18 -0
  21. forward_netbox-3.0.2/forward_netbox/migrations/0056_aci_attachment_nqe_map_choices.py +18 -0
  22. forward_netbox-3.0.2/forward_netbox/migrations/0056_routing_policy_nqe_map_choices.py +91 -0
  23. forward_netbox-3.0.2/forward_netbox/migrations/0057_aci_tenant_policy_nqe_map_choices.py +106 -0
  24. forward_netbox-3.0.2/forward_netbox/migrations/0057_nqe_map_last_live_drift.py +28 -0
  25. forward_netbox-3.0.2/forward_netbox/migrations/0058_operator_delete_releases_ownership.py +34 -0
  26. forward_netbox-3.0.2/forward_netbox/migrations/0059_aci_attachment_nqe_map_choices.py +113 -0
  27. forward_netbox-3.0.2/forward_netbox/migrations/0060_merge_maint_2_9_x_history.py +19 -0
  28. forward_netbox-3.0.2/forward_netbox/migrations/0061_static_route_nqe_map_choice.py +115 -0
  29. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/models.py +120 -10
  30. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/navigation.py +10 -1
  31. forward_netbox-3.0.0/forward_netbox/queries/forward_aci_filters.nqe → forward_netbox-3.0.2/forward_netbox/queries/forward_aci_apic_filters.nqe +10 -8
  32. forward_netbox-3.0.0/forward_netbox/queries/forward_aci_pods.nqe → forward_netbox-3.0.2/forward_netbox/queries/forward_aci_apic_pods.nqe +8 -5
  33. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_app_profiles.nqe +34 -0
  34. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_bridge_domains.nqe +58 -0
  35. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_contracts.nqe +37 -0
  36. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_endpoint_groups.nqe +50 -0
  37. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_fabrics.nqe +38 -0
  38. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_filter_entries.nqe +45 -0
  39. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_filters.nqe +65 -0
  40. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_l3outs.nqe +9 -7
  41. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_nodes.nqe +30 -1
  42. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_pods.nqe +63 -0
  43. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_source_readiness.nqe +51 -0
  44. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_static_port_bindings.nqe +51 -0
  45. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_subject_filters.nqe +51 -0
  46. forward_netbox-3.0.2/forward_netbox/queries/forward_aci_subjects.nqe +51 -0
  47. forward_netbox-3.0.2/forward_netbox/queries/forward_bgp_peer_address_families.nqe +189 -0
  48. forward_netbox-3.0.2/forward_netbox/queries/forward_config_backup.nqe +97 -0
  49. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_devices.nqe +21 -5
  50. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_devices_with_netbox_aliases.nqe +21 -5
  51. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_hsrp_groups.nqe +7 -0
  52. forward_netbox-3.0.2/forward_netbox/queries/forward_interfaces.nqe +171 -0
  53. forward_netbox-3.0.2/forward_netbox/queries/forward_ip_addresses_ipv4.nqe +311 -0
  54. forward_netbox-3.0.2/forward_netbox/queries/forward_routing_community_lists.nqe +87 -0
  55. forward_netbox-3.0.2/forward_netbox/queries/forward_routing_prefix_lists.nqe +96 -0
  56. forward_netbox-3.0.2/forward_netbox/queries/forward_routing_route_maps.nqe +78 -0
  57. forward_netbox-3.0.2/forward_netbox/queries/forward_static_routes.nqe +48 -0
  58. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/signals.py +37 -13
  59. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tables.py +53 -0
  60. forward_netbox-3.0.2/forward_netbox/template_content.py +309 -0
  61. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardingestionissue.html +26 -3
  62. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync.html +48 -2
  63. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/forwardsync_audit_report.html +107 -0
  64. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/forwardsync_audits.html +62 -0
  65. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/forwardsync_delete.html +18 -0
  66. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_drift_report.html +19 -2
  67. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_health.html +159 -1
  68. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_module_readiness.html +26 -0
  69. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_scope_reconciliation.html +201 -10
  70. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/htmx/forwardsync_delete_form.html +106 -0
  71. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/inc/count_trend.html +15 -0
  72. forward_netbox-3.0.2/forward_netbox/templates/forward_netbox/inc/device_ownership_panel.html +231 -0
  73. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_absence_quarantine.py +156 -1
  74. forward_netbox-3.0.2/forward_netbox/tests/test_absent_configuration_detail.py +361 -0
  75. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_aci_drift_comparison.py +2 -1
  76. forward_netbox-3.0.2/forward_netbox/tests/test_aci_source_readiness.py +179 -0
  77. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_api_views.py +114 -18
  78. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_apic_cimc_readiness_audit_command.py +4 -1
  79. forward_netbox-3.0.2/forward_netbox/tests/test_audit_report_views.py +289 -0
  80. forward_netbox-3.0.2/forward_netbox/tests/test_bgp_peer_af_query.py +95 -0
  81. forward_netbox-3.0.2/forward_netbox/tests/test_bgp_peer_policy_links.py +201 -0
  82. forward_netbox-3.0.2/forward_netbox/tests/test_bgp_peer_round_trip_variants.py +242 -0
  83. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_builtin_query_id_binding.py +9 -0
  84. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_bulk_merge.py +167 -8
  85. forward_netbox-3.0.2/forward_netbox/tests/test_bundle_diagnostics_parity.py +146 -0
  86. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_button_jobs.py +86 -23
  87. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_cable_drift_comparison.py +6 -3
  88. forward_netbox-3.0.2/forward_netbox/tests/test_catalogue_models_compare.py +70 -0
  89. forward_netbox-3.0.2/forward_netbox/tests/test_change_explainability_full_counts.py +85 -0
  90. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup.py +1333 -0
  91. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup_folder.py +320 -0
  92. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup_job_and_health.py +417 -0
  93. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup_path.py +117 -0
  94. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup_query.py +83 -0
  95. forward_netbox-3.0.2/forward_netbox/tests/test_config_backup_result_evidence.py +288 -0
  96. forward_netbox-3.0.2/forward_netbox/tests/test_constraint_diagnosis.py +216 -0
  97. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_cross_site_vlan_revalidation.py +6 -1
  98. forward_netbox-3.0.2/forward_netbox/tests/test_dependency_preview_summary.py +153 -0
  99. forward_netbox-3.0.2/forward_netbox/tests/test_device_name_case_identity.py +136 -0
  100. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_device_scope_reconciliation_audit_command.py +86 -3
  101. forward_netbox-3.0.2/forward_netbox/tests/test_device_site_relabel_identity.py +255 -0
  102. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_diagnostics_readback.py +52 -1
  103. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_diff_removal_allowlist.py +35 -0
  104. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_dlm_catalogue_conflicts.py +3 -4
  105. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_dlm_drift_comparison.py +2 -1
  106. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_dlm_inventoryitem_drift_comparison.py +2 -1
  107. forward_netbox-3.0.2/forward_netbox/tests/test_durable_workload_state_attribution.py +109 -0
  108. forward_netbox-3.0.2/forward_netbox/tests/test_endpoint_absence_detail.py +192 -0
  109. forward_netbox-3.0.2/forward_netbox/tests/test_endpoint_ipv4_netmask.py +75 -0
  110. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_endpoints_import.py +64 -0
  111. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_execute_by_query_id_without_commit.py +31 -10
  112. forward_netbox-3.0.2/forward_netbox/tests/test_export_redaction.py +260 -0
  113. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_failed_run_model_evidence.py +9 -1
  114. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_fast_baseline.py +179 -3
  115. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_fast_paths_report_when_disabled.py +14 -4
  116. forward_netbox-3.0.2/forward_netbox/tests/test_fast_paths_subset_runtime.py +173 -0
  117. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_fhrpgroup_drift_comparison.py +4 -2
  118. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_forms.py +125 -1
  119. forward_netbox-3.0.2/forward_netbox/tests/test_forward_api.py +2237 -0
  120. forward_netbox-3.0.2/forward_netbox/tests/test_forward_client_errors.py +212 -0
  121. forward_netbox-3.0.2/forward_netbox/tests/test_forward_client_factory.py +124 -0
  122. forward_netbox-3.0.2/forward_netbox/tests/test_forward_usage_hooks.py +85 -0
  123. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_head_commit_from_listing.py +34 -27
  124. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_health.py +82 -20
  125. forward_netbox-3.0.2/forward_netbox/tests/test_health_evidence.py +380 -0
  126. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ingestion_merge.py +3 -1
  127. forward_netbox-3.0.2/forward_netbox/tests/test_interface_lookup_query_shape.py +114 -0
  128. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_inventoryitem_drift_comparison.py +30 -17
  129. forward_netbox-3.0.2/forward_netbox/tests/test_issue_diagnosis.py +597 -0
  130. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_jobs.py +11 -3
  131. forward_netbox-3.0.2/forward_netbox/tests/test_license_tier.py +62 -0
  132. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_log_export.py +497 -0
  133. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_merge_rule_rejection.py +33 -0
  134. forward_netbox-3.0.2/forward_netbox/tests/test_migration_lineage.py +55 -0
  135. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_models.py +46 -27
  136. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_module_drift_comparison.py +6 -3
  137. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_module_readiness.py +12 -4
  138. forward_netbox-3.0.2/forward_netbox/tests/test_nqe_lint_blind_spots.py +110 -0
  139. forward_netbox-3.0.2/forward_netbox/tests/test_operator_delete_releases_ownership.py +267 -0
  140. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_optional_plugin_versions.py +80 -33
  141. forward_netbox-3.0.2/forward_netbox/tests/test_ospf_neighbour_rows_converge.py +161 -0
  142. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ownership.py +101 -0
  143. forward_netbox-3.0.2/forward_netbox/tests/test_ownership_lock_wait.py +88 -0
  144. forward_netbox-3.0.2/forward_netbox/tests/test_parameter_signature_drift.py +85 -0
  145. forward_netbox-3.0.2/forward_netbox/tests/test_plan_statistics_monotonic.py +92 -0
  146. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_plugin_integrations.py +11 -11
  147. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_preview_primes_its_lookup_caches.py +98 -0
  148. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_primary_ip.py +84 -0
  149. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_primary_ip_audit.py +10 -1
  150. forward_netbox-3.0.2/forward_netbox/tests/test_primary_ip_duplicate_names.py +100 -0
  151. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_primary_ip_integration.py +90 -5
  152. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_provision_preflight.py +13 -2
  153. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_binding.py +37 -1
  154. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_execution_contract.py +52 -8
  155. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_registry.py +110 -16
  156. forward_netbox-3.0.2/forward_netbox/tests/test_query_signature_drift_check.py +88 -0
  157. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_variants.py +49 -1
  158. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_refused_deletes_are_not_staged.py +3 -4
  159. forward_netbox-3.0.2/forward_netbox/tests/test_release_foreign_delete_blockers.py +298 -0
  160. forward_netbox-3.0.2/forward_netbox/tests/test_routing_apply_compare_round_trip.py +172 -0
  161. forward_netbox-3.0.2/forward_netbox/tests/test_routing_catalogue_cleanup.py +283 -0
  162. forward_netbox-3.0.2/forward_netbox/tests/test_routing_catalogue_drift.py +103 -0
  163. forward_netbox-3.0.2/forward_netbox/tests/test_routing_catalogue_scope.py +107 -0
  164. forward_netbox-3.0.2/forward_netbox/tests/test_row_collapsing.py +136 -0
  165. forward_netbox-3.0.2/forward_netbox/tests/test_run_size_anomaly.py +122 -0
  166. forward_netbox-3.0.2/forward_netbox/tests/test_run_size_guard.py +192 -0
  167. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_runtime_dependency_check.py +1 -1
  168. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scheduled_jobs.py +71 -8
  169. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_matched_tags.py +14 -9
  170. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_module_ui.py +294 -21
  171. forward_netbox-3.0.2/forward_netbox/tests/test_scope_reconciliation_site_aware.py +317 -0
  172. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_shrink_guard.py +2 -0
  173. forward_netbox-3.0.2/forward_netbox/tests/test_sdk_result_contract.py +44 -0
  174. forward_netbox-3.0.2/forward_netbox/tests/test_site_relabel_pairs_merge.py +706 -0
  175. forward_netbox-3.0.2/forward_netbox/tests/test_site_relabel_prompts.py +271 -0
  176. forward_netbox-3.0.2/forward_netbox/tests/test_static_routes_query.py +64 -0
  177. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_stuck_recovery.py +205 -1
  178. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync.py +102 -1
  179. forward_netbox-3.0.2/forward_netbox/tests/test_sync_aci.py +1850 -0
  180. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync_facade.py +30 -10
  181. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync_orchestration.py +55 -43
  182. forward_netbox-3.0.2/forward_netbox/tests/test_sync_routing_policy.py +818 -0
  183. forward_netbox-3.0.2/forward_netbox/tests/test_sync_routing_static.py +339 -0
  184. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_taggeditem_drift_comparison.py +8 -4
  185. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_uncovered_absence_and_trend.py +148 -4
  186. forward_netbox-3.0.2/forward_netbox/tests/test_uncovered_device_cleanup.py +472 -0
  187. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_uncovered_device_tag.py +8 -2
  188. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_validated_runtime_is_declared_once.py +10 -4
  189. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_validation_org_query_audit_command.py +76 -12
  190. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_vsys_parent.py +10 -4
  191. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_workload_state.py +89 -5
  192. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/__init__.py +1 -5
  193. forward_netbox-3.0.2/forward_netbox/utilities/apic_cimc_readiness.py +77 -0
  194. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/apply_engine_bulk.py +321 -44
  195. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/apply_engine_decision.py +71 -32
  196. forward_netbox-3.0.2/forward_netbox/utilities/audit_reports.py +684 -0
  197. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/branch_budget.py +58 -0
  198. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/branch_lifecycle.py +64 -2
  199. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/bulk_merge.py +12 -2
  200. forward_netbox-3.0.2/forward_netbox/utilities/bundle_diagnostics.py +520 -0
  201. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/change_explainability.py +44 -4
  202. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/config_backup.py +424 -59
  203. forward_netbox-3.0.2/forward_netbox/utilities/config_backup_path.py +98 -0
  204. forward_netbox-3.0.2/forward_netbox/utilities/constraint_diagnosis.py +322 -0
  205. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/device_analysis.py +3 -1
  206. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/diagnostics.py +104 -4
  207. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/dlm_notice_audit.py +3 -1
  208. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/drift_comparison.py +110 -17
  209. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/drift_report.py +56 -0
  210. forward_netbox-3.0.2/forward_netbox/utilities/export_redaction.py +95 -0
  211. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/fast_baseline.py +71 -10
  212. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/fast_baseline_models.py +19 -0
  213. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/forward_api.py +22 -1
  214. forward_netbox-3.0.2/forward_netbox/utilities/forward_api_impl.py +1830 -0
  215. forward_netbox-3.0.2/forward_netbox/utilities/forward_client_config.py +151 -0
  216. forward_netbox-3.0.2/forward_netbox/utilities/forward_client_errors.py +105 -0
  217. forward_netbox-3.0.2/forward_netbox/utilities/forward_client_factory.py +103 -0
  218. forward_netbox-3.0.2/forward_netbox/utilities/forward_read_cache.py +100 -0
  219. forward_netbox-3.0.2/forward_netbox/utilities/forward_throttle.py +98 -0
  220. forward_netbox-3.0.2/forward_netbox/utilities/forward_usage.py +144 -0
  221. forward_netbox-3.0.2/forward_netbox/utilities/forward_usage_hooks.py +70 -0
  222. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/full_removal_reconciliation.py +15 -0
  223. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/health.py +859 -121
  224. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/health_checks.py +82 -34
  225. forward_netbox-3.0.2/forward_netbox/utilities/health_evidence.py +307 -0
  226. forward_netbox-3.0.2/forward_netbox/utilities/ingestion_issues.py +91 -0
  227. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/interface_vlan_audit.py +76 -2
  228. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/merge.py +30 -5
  229. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/merge_set_based.py +6 -30
  230. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/model_validation.py +14 -0
  231. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/module_readiness.py +4 -1
  232. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/ownership.py +156 -15
  233. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/plugin_integrations/registry.py +52 -5
  234. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/primary_ip.py +131 -17
  235. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/primary_ip_audit.py +3 -1
  236. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_binding_resolution.py +124 -21
  237. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_diagnostics.py +182 -2
  238. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_fetch_execution.py +137 -44
  239. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_registry.py +158 -9
  240. forward_netbox-3.0.2/forward_netbox/utilities/routing_catalogue_cleanup.py +313 -0
  241. forward_netbox-3.0.2/forward_netbox/utilities/routing_dangling_audit.py +57 -0
  242. forward_netbox-3.0.2/forward_netbox/utilities/row_collapsing.py +140 -0
  243. forward_netbox-3.0.2/forward_netbox/utilities/run_size_anomaly.py +138 -0
  244. forward_netbox-3.0.2/forward_netbox/utilities/run_size_guard.py +76 -0
  245. forward_netbox-3.0.2/forward_netbox/utilities/scope_reconciliation.py +2845 -0
  246. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/single_branch_executor.py +53 -6
  247. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/snapshot_freshness.py +5 -2
  248. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/stuck_recovery.py +94 -7
  249. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/support_bundle_archive.py +5 -1
  250. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync.py +35 -1
  251. forward_netbox-3.0.2/forward_netbox/utilities/sync_aci.py +1420 -0
  252. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_contracts.py +125 -0
  253. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_core_models.py +30 -3
  254. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_device.py +109 -4
  255. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_execution.py +12 -5
  256. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_facade.py +95 -3
  257. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_ipam.py +162 -23
  258. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_orchestration.py +7 -0
  259. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_primitives.py +239 -3
  260. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_reporting.py +179 -1
  261. forward_netbox-3.0.2/forward_netbox/utilities/sync_routing.py +3 -0
  262. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_routing_impl.py +58 -0
  263. forward_netbox-3.0.2/forward_netbox/utilities/sync_routing_policy.py +963 -0
  264. forward_netbox-3.0.2/forward_netbox/utilities/sync_routing_static.py +304 -0
  265. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_runner_adapters.py +129 -9
  266. forward_netbox-3.0.2/forward_netbox/utilities/validated_runtime.py +168 -0
  267. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/vsys_parent.py +3 -1
  268. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/workload_state.py +221 -13
  269. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/views.py +1539 -78
  270. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/pyproject.toml +11 -6
  271. forward_netbox-3.0.0/forward_netbox/management/commands/forward_apic_cimc_readiness_audit.py +0 -118
  272. forward_netbox-3.0.0/forward_netbox/management/commands/forward_routing_dangling_audit.py +0 -82
  273. forward_netbox-3.0.0/forward_netbox/queries/forward_aci_bridge_domains.nqe +0 -45
  274. forward_netbox-3.0.0/forward_netbox/queries/forward_aci_fabrics.nqe +0 -25
  275. forward_netbox-3.0.0/forward_netbox/queries/forward_bgp_peer_address_families.nqe +0 -65
  276. forward_netbox-3.0.0/forward_netbox/queries/forward_config_backup.nqe +0 -38
  277. forward_netbox-3.0.0/forward_netbox/queries/forward_interfaces.nqe +0 -66
  278. forward_netbox-3.0.0/forward_netbox/queries/forward_ip_addresses_ipv4.nqe +0 -154
  279. forward_netbox-3.0.0/forward_netbox/template_content.py +0 -31
  280. forward_netbox-3.0.0/forward_netbox/tests/test_config_backup.py +0 -608
  281. forward_netbox-3.0.0/forward_netbox/tests/test_dependency_preview_summary.py +0 -64
  282. forward_netbox-3.0.0/forward_netbox/tests/test_forward_api.py +0 -2831
  283. forward_netbox-3.0.0/forward_netbox/tests/test_issue_diagnosis.py +0 -260
  284. forward_netbox-3.0.0/forward_netbox/tests/test_license_tier.py +0 -131
  285. forward_netbox-3.0.0/forward_netbox/tests/test_sync_aci.py +0 -951
  286. forward_netbox-3.0.0/forward_netbox/utilities/forward_api_impl.py +0 -2308
  287. forward_netbox-3.0.0/forward_netbox/utilities/ingestion_issues.py +0 -22
  288. forward_netbox-3.0.0/forward_netbox/utilities/scope_reconciliation.py +0 -1385
  289. forward_netbox-3.0.0/forward_netbox/utilities/sync_aci.py +0 -614
  290. forward_netbox-3.0.0/forward_netbox/utilities/sync_routing.py +0 -1
  291. forward_netbox-3.0.0/forward_netbox/utilities/validated_runtime.py +0 -84
  292. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/LICENSE +0 -0
  293. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/api/__init__.py +0 -0
  294. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/api/urls.py +0 -0
  295. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/__init__.py +0 -0
  296. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/choices.py +0 -0
  297. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/evidence.py +0 -0
  298. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/gates.py +0 -0
  299. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/policy.py +0 -0
  300. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/predict.py +0 -0
  301. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/change_control/state_machine.py +0 -0
  302. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/exceptions.py +0 -0
  303. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/__init__.py +0 -0
  304. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/__init__.py +0 -0
  305. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_accept_merge_failures.py +0 -0
  306. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_apply_identity_audit.py +0 -0
  307. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_blocker_audit.py +0 -0
  308. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_changediff_audit.py +0 -0
  309. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_collection_gap_alert.py +0 -0
  310. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_device_name_ambiguity_audit.py +0 -0
  311. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_dlm_hardware_notice_audit.py +0 -0
  312. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_fast_baseline_preflight.py +0 -0
  313. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_interface_vlan_audit.py +0 -0
  314. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_link_vsys_parents.py +0 -0
  315. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_metrics.py +0 -0
  316. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_ownership_audit.py +0 -0
  317. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_primary_ip_audit.py +0 -0
  318. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_query_diff_coverage_audit.py +0 -0
  319. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_resolve_query_ids.py +0 -0
  320. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_scope_ipam_audit.py +0 -0
  321. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_seed_ui_harness.py +0 -0
  322. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_stuck_job_alert.py +0 -0
  323. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_stuck_job_recover.py +0 -0
  324. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_tag_delete_eligible.py +0 -0
  325. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_validation_org_query_audit.py +0 -0
  326. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_warning_audit.py +0 -0
  327. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/management/commands/forward_watch_sync.py +0 -0
  328. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0001_initial.py +0 -0
  329. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0002_add_coalesce_fields.py +0 -0
  330. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0003_forwardingestionissue_context_fields.py +0 -0
  331. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0004_forwardingestion_baseline_fields.py +0 -0
  332. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0005_validation_and_reporting.py +0 -0
  333. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0006_alter_forwardnqemap_netbox_model.py +0 -0
  334. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0007_forwardingestion_persisted_change_counters.py +0 -0
  335. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0008_alter_forwardnqemap_netbox_model.py +0 -0
  336. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0009_alter_forwardnqemap_netbox_model.py +0 -0
  337. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0010_forwardvalidationrun_override_applied_and_more.py +0 -0
  338. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0011_forwardingestion_change_request_id.py +0 -0
  339. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0012_forwardnqemap_query_reference.py +0 -0
  340. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0013_execution_run_step.py +0 -0
  341. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0014_execution_step_fetch_scope.py +0 -0
  342. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0015_execution_step_apply_engine.py +0 -0
  343. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0016_execution_step_query_metrics.py +0 -0
  344. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0017_execution_step_row_counters.py +0 -0
  345. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0018_execution_run_reconciliation_events.py +0 -0
  346. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0019_forwardexecutionstep_query_parameters.py +0 -0
  347. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0020_execution_step_operation.py +0 -0
  348. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0021_add_fhrpgroup_nqe_map_choice.py +0 -0
  349. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0022_alter_forwardnqemap_netbox_model.py +0 -0
  350. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0023_split_ip_address_maps.py +0 -0
  351. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0024_forwarddeviceanalysis.py +0 -0
  352. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0025_device_analysis_netboxmodel.py +0 -0
  353. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0026_forwarddeviceanalysis_collection_result.py +0 -0
  354. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0027_alter_forwardexecutionrun_backend.py +0 -0
  355. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0028_remove_forwardexecutionstep_run_and_more.py +0 -0
  356. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0029_forward_parent_device_cf.py +0 -0
  357. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0030_forwarddeviceanalysis_cve_ids.py +0 -0
  358. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0031_encrypt_source_password.py +0 -0
  359. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0032_alter_forwardnqemap_netbox_model.py +0 -0
  360. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0033_alter_forwardnqemap_netbox_model.py +0 -0
  361. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0034_source_ownership_provenance.py +0 -0
  362. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0035_initialize_ownership_control_plane.py +0 -0
  363. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0036_protect_ownership_provenance.py +0 -0
  364. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0037_merge_identity_and_assignment_provenance.py +0 -0
  365. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0038_managed_tag_domain_guard.py +0 -0
  366. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0039_forwardingestion_catchup_state.py +0 -0
  367. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0040_remove_redundant_nqe_settings.py +0 -0
  368. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0041_forwardworkloadstate.py +0 -0
  369. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0042_device_generic_relation_guards.py +0 -0
  370. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0043_forwardnqemap_diff_contract.py +0 -0
  371. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0044_contributor_baseline_cache.py +0 -0
  372. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0045_forwardmergeattempt.py +0 -0
  373. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0046_alter_forwardnqemap_netbox_model.py +0 -0
  374. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0047_ownership_reconciliation_cascade.py +0 -0
  375. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0048_forwardingestion_skipped_change_count.py +0 -0
  376. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0049_drift_policy_row_shrink_floor.py +0 -0
  377. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0050_contributor_baseline_cascade.py +0 -0
  378. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0051_ownership_provenance_stamp_nullable.py +0 -0
  379. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0052_device_absence_quarantine.py +0 -0
  380. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0053_alter_forwardsource_owner.py +0 -0
  381. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0054_forwardchange_forwardchangecriterion_and_more.py +0 -0
  382. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/0055_change_control_approvals.py +0 -0
  383. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/migrations/__init__.py +0 -0
  384. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/__init__.py +0 -0
  385. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_apic_cimc_inventory.nqe +0 -0
  386. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_apic_nodes.nqe +0 -0
  387. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_command_inventory.nqe +0 -0
  388. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_tenants.nqe +0 -0
  389. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_aci_vrfs.nqe +0 -0
  390. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_bgp_address_families.nqe +0 -0
  391. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_bgp_peers.nqe +0 -0
  392. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_cimc_endpoint_inventory.nqe +0 -0
  393. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_analysis.nqe +0 -0
  394. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_feature_tags.nqe +0 -0
  395. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_feature_tags_with_rules.nqe +0 -0
  396. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_models.nqe +0 -0
  397. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_models_with_netbox_aliases.nqe +0 -0
  398. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_types.nqe +0 -0
  399. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_device_vendors.nqe +0 -0
  400. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_apic_cimc_inventory_item_software.nqe +0 -0
  401. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_cves.nqe +0 -0
  402. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_device_software.nqe +0 -0
  403. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_hardware_notices.nqe +0 -0
  404. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_hardware_notices_with_netbox_aliases.nqe +0 -0
  405. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_inventory_item_software.nqe +0 -0
  406. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_software_versions.nqe +0 -0
  407. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_dlm_vulnerabilities.nqe +0 -0
  408. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_inferred_interface_cables.nqe +0 -0
  409. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_inventory_items.nqe +0 -0
  410. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_ip_addresses_ipv6.nqe +0 -0
  411. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_ip_addresses_unassignable_diagnostics.nqe +0 -0
  412. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_locations.nqe +0 -0
  413. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_mac_addresses.nqe +0 -0
  414. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_modules.nqe +0 -0
  415. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_ospf_areas.nqe +0 -0
  416. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_ospf_instances.nqe +0 -0
  417. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_ospf_interfaces.nqe +0 -0
  418. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_peering_sessions.nqe +0 -0
  419. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_platforms.nqe +0 -0
  420. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_prefixes_ipv4.nqe +0 -0
  421. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_prefixes_ipv6.nqe +0 -0
  422. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_routing_import_diagnostics.nqe +0 -0
  423. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_virtual_chassis.nqe +0 -0
  424. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_vlans.nqe +0 -0
  425. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/forward_vrfs.nqe +0 -0
  426. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/queries/netbox_utilities.nqe +0 -0
  427. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/static/forward_netbox/img/fn-logo.svg +0 -0
  428. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/device_cves.html +0 -0
  429. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardchange.html +0 -0
  430. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardchangepolicy.html +0 -0
  431. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwarddeviceanalysis.html +0 -0
  432. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwarddriftpolicy.html +0 -0
  433. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardingestion.html +0 -0
  434. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardnqemap.html +0 -0
  435. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsource.html +0 -0
  436. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_dependency_preview.html +0 -0
  437. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardsync_uncovered_devices.html +0 -0
  438. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/forwardvalidationrun.html +0 -0
  439. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/brand_bar.html +0 -0
  440. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/device_analysis_panel.html +0 -0
  441. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/diff.html +0 -0
  442. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/execution_insights.html +0 -0
  443. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/logs_pending.html +0 -0
  444. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/merge_form.html +0 -0
  445. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/inc/validation_force_allow_form.html +0 -0
  446. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/change_explainability.html +0 -0
  447. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/ingestion_all.html +0 -0
  448. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/ingestion_merge_button.html +0 -0
  449. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/ingestion_progress.html +0 -0
  450. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/ingestion_statistics.html +0 -0
  451. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/ingestion_status.html +0 -0
  452. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/job_logs.html +0 -0
  453. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/object_tabs.html +0 -0
  454. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/stage_switcher_buttons.html +0 -0
  455. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templates/forward_netbox/partials/validation_force_allow_button.html +0 -0
  456. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templatetags/__init__.py +0 -0
  457. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/templatetags/forward_netbox_helpers.py +0 -0
  458. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/__init__.py +0 -0
  459. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/fixtures/aci_command_inventory_expected.json +0 -0
  460. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/fixtures/aci_discovery_expected.json +0 -0
  461. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_a_warning_is_not_a_failure.py +0 -0
  462. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_absent_device_does_not_block_tag_domain.py +0 -0
  463. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_accepted_merge_failures.py +0 -0
  464. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_adapter_drift_scale.py +0 -0
  465. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_api_serializer_base.py +0 -0
  466. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_api_usage.py +0 -0
  467. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_apply_engine.py +0 -0
  468. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_apply_identity_audit.py +0 -0
  469. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_bgp_peer_comment_churn.py +0 -0
  470. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_branch_budget_split.py +0 -0
  471. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_branching.py +0 -0
  472. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_brand_bar.py +0 -0
  473. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_bulk_adapter_parity.py +0 -0
  474. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_bulk_merge_scale.py +0 -0
  475. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_change_control_evidence.py +0 -0
  476. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_change_control_gates.py +0 -0
  477. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_change_control_policy.py +0 -0
  478. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_change_control_predict.py +0 -0
  479. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_change_control_state_machine.py +0 -0
  480. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_changediff_audit.py +0 -0
  481. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_collection_collapse_guard.py +0 -0
  482. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_contract_preflight_message.py +0 -0
  483. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_contributor_baseline.py +0 -0
  484. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_converged_models_are_measured.py +0 -0
  485. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_copy_sql_apply_engine.py +0 -0
  486. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_crypto.py +0 -0
  487. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_density_observation.py +0 -0
  488. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_device_analysis_query.py +0 -0
  489. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_device_scope_tagging.py +0 -0
  490. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_dlm_hardware_notice_audit.py +0 -0
  491. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_dlm_integration.py +0 -0
  492. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_drift_comparison.py +0 -0
  493. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_drift_coverage_is_explained.py +0 -0
  494. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_drift_rows_are_distinguishable.py +0 -0
  495. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_empty_comparison_is_not_a_measurement.py +0 -0
  496. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_empty_workload_failure.py +0 -0
  497. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_execution_insights_delete_label.py +0 -0
  498. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_field_reported_integrity_failures.py +0 -0
  499. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_force_allow_override.py +0 -0
  500. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_full_removal_reconciliation.py +0 -0
  501. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ingestion_delete.py +0 -0
  502. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ingestion_is_deletable.py +0 -0
  503. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_interface_naming.py +0 -0
  504. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_interface_vlan_audit.py +0 -0
  505. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ip_address_dedup_query.py +0 -0
  506. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ipaddress_dup_global.py +0 -0
  507. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_issue_rendering.py +0 -0
  508. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_job_liveness.py +0 -0
  509. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_job_queue.py +0 -0
  510. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_keyerror_names_its_key.py +0 -0
  511. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_logging.py +0 -0
  512. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_merge_observability.py +0 -0
  513. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_merge_profiling.py +0 -0
  514. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_migration_dependencies.py +0 -0
  515. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_migrations.py +0 -0
  516. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_mixed_model_change_diffs.py +0 -0
  517. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_model_view_routes.py +0 -0
  518. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_module_readiness_rollup.py +0 -0
  519. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_operator_commands.py +0 -0
  520. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ospf_drift_comparison.py +0 -0
  521. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ownership_command.py +0 -0
  522. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ownership_completes_with_preexisting_status_tag.py +0 -0
  523. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ownership_conflict_reason.py +0 -0
  524. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_ownership_migration.py +0 -0
  525. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_peering_drift_comparison.py +0 -0
  526. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_post_sync.py +0 -0
  527. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_preview_isolation.py +0 -0
  528. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_preview_reports_its_cost.py +0 -0
  529. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_preview_runner_satisfies_the_priming_contract.py +0 -0
  530. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_protected_delete_is_a_skip.py +0 -0
  531. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_protecting_reference_deletes.py +0 -0
  532. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_protecting_relations.py +0 -0
  533. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_quarantine_cadence.py +0 -0
  534. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_diff_coverage_audit_command.py +0 -0
  535. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_query_id_binding_end_to_end.py +0 -0
  536. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_raise_site_is_recorded.py +0 -0
  537. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_refused_deletes_are_retried.py +0 -0
  538. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_release_readiness_audit.py +0 -0
  539. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_reserved_status_tag_adoption.py +0 -0
  540. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_row_count_floor.py +0 -0
  541. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_audit_full.py +0 -0
  542. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_ipam_audit.py +0 -0
  543. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_reconciliation_view.py +0 -0
  544. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_scope_tag_slug_collision.py +0 -0
  545. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_set_based_merge.py +0 -0
  546. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_skip_dependency_direction.py +0 -0
  547. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_skip_names_netbox_row.py +0 -0
  548. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_skip_raisers_name_dependency.py +0 -0
  549. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_skip_rollup_direction.py +0 -0
  550. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_smoke_sync_command.py +0 -0
  551. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_source_parameter_keys_agree.py +0 -0
  552. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_stability_hardening.py +0 -0
  553. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_support_bundle_archive.py +0 -0
  554. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync_recurrence_pinning.py +0 -0
  555. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync_runner_contracts.py +0 -0
  556. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_sync_state.py +0 -0
  557. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_tier3_reducers.py +0 -0
  558. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_tree_model_detection.py +0 -0
  559. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_upgrade_reconciliation.py +0 -0
  560. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_virtualchassis_drift_comparison.py +0 -0
  561. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/tests/test_workload_normalization.py +0 -0
  562. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/urls.py +0 -0
  563. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/api_usage.py +0 -0
  564. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/apply_engine.py +0 -0
  565. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/apply_engine_copy_sql.py +0 -0
  566. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/apply_identity_audit.py +0 -0
  567. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/branching.py +0 -0
  568. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/bulk_delete.py +0 -0
  569. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/changediff_audit.py +0 -0
  570. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/contributor_baseline.py +0 -0
  571. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/crypto.py +0 -0
  572. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/delete_policy.py +0 -0
  573. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/density_learning.py +0 -0
  574. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/direct_changes.py +0 -0
  575. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/execution_telemetry.py +0 -0
  576. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/executor_base.py +0 -0
  577. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/health_apply_fetch.py +0 -0
  578. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/health_summary_blocks.py +0 -0
  579. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/ingestion_merge.py +0 -0
  580. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/ingestion_presentation.py +0 -0
  581. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/interface_naming.py +0 -0
  582. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/job_liveness.py +0 -0
  583. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/job_queue.py +0 -0
  584. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/json_safe.py +0 -0
  585. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/license_tier.py +0 -0
  586. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/logging.py +0 -0
  587. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/merge_observability.py +0 -0
  588. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/merge_profiling.py +0 -0
  589. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/model_contracts.py +0 -0
  590. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/plugin_integrations/__init__.py +0 -0
  591. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/post_sync.py +0 -0
  592. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_binding.py +0 -0
  593. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_execution_contract.py +0 -0
  594. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/query_fetch.py +0 -0
  595. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/runtime_guidance.py +0 -0
  596. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/scope_ipam_audit.py +0 -0
  597. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_cable.py +0 -0
  598. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_dlm.py +0 -0
  599. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_events.py +0 -0
  600. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_interface.py +0 -0
  601. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_inventory_module.py +0 -0
  602. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_runner_contracts.py +0 -0
  603. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/sync_state.py +0 -0
  604. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/tag_contracts.py +0 -0
  605. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/tier3_reducers.py +0 -0
  606. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/upgrade_reconciliation.py +0 -0
  607. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/validation.py +0 -0
  608. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/validation_org_query.py +0 -0
  609. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/version_series.py +0 -0
  610. {forward_netbox-3.0.0 → forward_netbox-3.0.2}/forward_netbox/utilities/workload_normalization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: forward-netbox
3
- Version: 3.0.0
3
+ Version: 3.0.2
4
4
  Summary: NetBox plugin to sync Forward data into NetBox via built-in NQE queries
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -27,12 +27,13 @@ Provides-Extra: integrations
27
27
  Provides-Extra: peering
28
28
  Provides-Extra: routing
29
29
  Provides-Extra: validity
30
+ Requires-Dist: forward-sdk (==0.1.20)
30
31
  Requires-Dist: httpx (>0.26,<0.29)
31
32
  Requires-Dist: netbox-cisco-aci (==0.4.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "aci" or extra == "integrations")
32
- Requires-Dist: netbox-dlm (>=0.4.1,<0.10.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "dlm" or extra == "integrations")
33
- Requires-Dist: netbox-peering-manager (==0.3.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "peering" or extra == "integrations")
34
- Requires-Dist: netbox-routing (==0.4.3) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "routing" or extra == "integrations")
35
- Requires-Dist: netbox-validity (==3.5.2) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "validity" or extra == "integrations")
33
+ Requires-Dist: netbox-dlm (>=0.4.1,<0.11.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "dlm" or extra == "integrations")
34
+ Requires-Dist: netbox-peering-manager (==0.3.1) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "peering" or extra == "integrations")
35
+ Requires-Dist: netbox-routing (>=0.5.0,<0.6.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "routing" or extra == "integrations")
36
+ Requires-Dist: netbox-validity (==3.6.0) ; (python_version >= "3.12" and python_version < "3.15") and (extra == "validity" or extra == "integrations")
36
37
  Requires-Dist: netboxlabs-netbox-branching (>=1.2.0,<1.3.0) ; python_version >= "3.12" and python_version < "3.15"
37
38
  Requires-Dist: pyzipper (>=0.4.0,<0.5.0)
38
39
  Project-URL: Changelog, https://github.com/forwardnetworks/forward-netbox/blob/main/CHANGELOG.md
@@ -108,15 +109,17 @@ See the
108
109
 
109
110
  ## Release Compatibility
110
111
 
111
- The `3.0.0` release candidate requires NetBox `4.7.x` (tested on `4.7.0`) and `netbox-branching` `1.2.x` (tested on `1.2.0`). Expand for the published release history and candidate notes.
112
+ The `3.0.2` release candidate requires NetBox `4.7.x` (tested on `4.7.1`) and `netbox-branching` `1.2.x` (tested on `1.2.0`). Expand for the published release history and candidate notes.
112
113
 
113
114
  <details>
114
115
  <summary>Release compatibility history</summary>
115
116
 
116
117
  | Plugin Release | NetBox Version | Status |
117
118
  | --- | --- | --- |
118
- | `v3.0.0` | NetBox `4.7.x` supported, tested on `4.7.0`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Release candidate; NetBox 4.7 with netbox-branching 1.2, and change control gated on what Forward saw before and after the change. |
119
- | `v2.9.2` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Current release; Drift is measured exactly for every fetched model, the uncovered-device count says why it grows and warns when it does, and five delete and diagnostic defects are closed. |
119
+ | `v3.0.2` | NetBox `4.7.x` supported, tested on `4.7.1`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Release candidate; Port of 2.9.13's PeeringSession crash + endpoint /32 fixes, plus the 3.0.1 upgrade-runtime override fix |
120
+ | `v3.0.1` | NetBox `4.7.x` supported, tested on `4.7.1`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Current release; Release candidate; Fix: every fix shipped on the 2.9.x line as 2.9.7 through 2.9.11 now ships on NetBox 4.7 - the 3.x line had none of them. Fix: renaming a device's site in Forward moves the existing device instead of creating a duplicate, devices are matched case-insensitively the way NetBox identifies them, and the new Scope Reconciliation action Merge site-relabel duplicates repairs pairs already created (keeps the older device at the site Forward reports; held pairs are listed with a reason and never pruned). Fix: scope membership is by name, so no in-scope device is called out of scope. Feature: duplicates and other silent problems are no longer silent - a Health check, a sync-page banner, a Scope Reconciliation card and a job-log line. Fix: config backup reaches the repository through the proxy NetBox uses, no longer writes credentials to the worker log, fails when the remote refuses the branch, and names the cause of a failure in the job, Health and the support bundle. Fix: the fast baseline, COPY/SQL and set-based merge run on any subset of the validated plugins. Fix: routing-policy scope counts every device that holds a definition, pending removals are what the next sync removes, and Scope Reconciliation offers Remove out-of-scope routing policy (an allowlisted, gated operator action). Fix: the SDK repository lookup read attributes the forward-sdk RepositoryQuery does not have, so committed-query lookups by path failed against a real Forward; forward-sdk is now 0.1.20. Fix: protection against deleting a sync or ingestion while a job runs, and support bundles and log exports no longer carry operator values such as include-tag names. Feature: the support bundle carries a diagnostics section, and a live query-drift check flags a published query whose parameter list no longer matches this release. Feature: Auto merge stops for review when a run is far larger than the sync has been - only with Auto merge on, only after the sync has finished a run before, and only for a model that stages at least 10,000 changes at 3x the table's size (or 10x the typical earlier run); a held run stays staged, with the ingestion's Merge and Delete actions as Merge anyway and Discard. Feature: Health and the support bundle show Forward's row count next to NetBox's per model, the last three ingestions with job and merge status, statistics and merged changes by model and action, and a BGP peer duplicate count, and flag an abnormal run, a baseline that never completed and a NetBox table far smaller than Forward's. Feature: the config backup folder is configurable (nested folders allowed), Health shows the Validity device_config_path for it, and the last backup reports rows, written, unchanged, unmapped, managed devices with no collected configuration and files in the folder. Fix: the Include unmanaged configuration checkbox never persisted from the source form. Migrations 0053 through 0057 and 0060 adopt the 2.9.x schema history. Org-backed deployments: run Publish Bundled Queries after upgrading, because the interface and IPv4 address queries changed their parameter lists (a stale published copy fails every execution against it until republished) and the three routing-policy queries gained an output column. |
121
+ | `v3.0.0` | NetBox `4.7.x` supported, tested on `4.7.0`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Superseded by `v3.0.1`; NetBox 4.7 with netbox-branching 1.2, and change control gated on what Forward saw before and after the change. |
122
+ | `v2.9.2` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v3.0.0`; Drift is measured exactly for every fetched model, the uncovered-device count says why it grows and warns when it does, and five delete and diagnostic defects are closed. |
120
123
  | `v2.9.1` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.2`; Accepts netbox-branching 1.1.3 and records the validated runtime in the lockfile. |
121
124
  | `v2.9.0` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.1`; Feature: back up device configurations from Forward into a git data source for Validity golden-config checks, plus the runtime-validation refactor and health check it required. |
122
125
  | `v2.8.9` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.0`; Fix: a sync deletes a device only on the same quarantined evidence the operator prune requires, and never stages a delete the database will refuse. |
@@ -64,15 +64,17 @@ See the
64
64
 
65
65
  ## Release Compatibility
66
66
 
67
- The `3.0.0` release candidate requires NetBox `4.7.x` (tested on `4.7.0`) and `netbox-branching` `1.2.x` (tested on `1.2.0`). Expand for the published release history and candidate notes.
67
+ The `3.0.2` release candidate requires NetBox `4.7.x` (tested on `4.7.1`) and `netbox-branching` `1.2.x` (tested on `1.2.0`). Expand for the published release history and candidate notes.
68
68
 
69
69
  <details>
70
70
  <summary>Release compatibility history</summary>
71
71
 
72
72
  | Plugin Release | NetBox Version | Status |
73
73
  | --- | --- | --- |
74
- | `v3.0.0` | NetBox `4.7.x` supported, tested on `4.7.0`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Release candidate; NetBox 4.7 with netbox-branching 1.2, and change control gated on what Forward saw before and after the change. |
75
- | `v2.9.2` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Current release; Drift is measured exactly for every fetched model, the uncovered-device count says why it grows and warns when it does, and five delete and diagnostic defects are closed. |
74
+ | `v3.0.2` | NetBox `4.7.x` supported, tested on `4.7.1`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Release candidate; Port of 2.9.13's PeeringSession crash + endpoint /32 fixes, plus the 3.0.1 upgrade-runtime override fix |
75
+ | `v3.0.1` | NetBox `4.7.x` supported, tested on `4.7.1`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Current release; Release candidate; Fix: every fix shipped on the 2.9.x line as 2.9.7 through 2.9.11 now ships on NetBox 4.7 - the 3.x line had none of them. Fix: renaming a device's site in Forward moves the existing device instead of creating a duplicate, devices are matched case-insensitively the way NetBox identifies them, and the new Scope Reconciliation action Merge site-relabel duplicates repairs pairs already created (keeps the older device at the site Forward reports; held pairs are listed with a reason and never pruned). Fix: scope membership is by name, so no in-scope device is called out of scope. Feature: duplicates and other silent problems are no longer silent - a Health check, a sync-page banner, a Scope Reconciliation card and a job-log line. Fix: config backup reaches the repository through the proxy NetBox uses, no longer writes credentials to the worker log, fails when the remote refuses the branch, and names the cause of a failure in the job, Health and the support bundle. Fix: the fast baseline, COPY/SQL and set-based merge run on any subset of the validated plugins. Fix: routing-policy scope counts every device that holds a definition, pending removals are what the next sync removes, and Scope Reconciliation offers Remove out-of-scope routing policy (an allowlisted, gated operator action). Fix: the SDK repository lookup read attributes the forward-sdk RepositoryQuery does not have, so committed-query lookups by path failed against a real Forward; forward-sdk is now 0.1.20. Fix: protection against deleting a sync or ingestion while a job runs, and support bundles and log exports no longer carry operator values such as include-tag names. Feature: the support bundle carries a diagnostics section, and a live query-drift check flags a published query whose parameter list no longer matches this release. Feature: Auto merge stops for review when a run is far larger than the sync has been - only with Auto merge on, only after the sync has finished a run before, and only for a model that stages at least 10,000 changes at 3x the table's size (or 10x the typical earlier run); a held run stays staged, with the ingestion's Merge and Delete actions as Merge anyway and Discard. Feature: Health and the support bundle show Forward's row count next to NetBox's per model, the last three ingestions with job and merge status, statistics and merged changes by model and action, and a BGP peer duplicate count, and flag an abnormal run, a baseline that never completed and a NetBox table far smaller than Forward's. Feature: the config backup folder is configurable (nested folders allowed), Health shows the Validity device_config_path for it, and the last backup reports rows, written, unchanged, unmapped, managed devices with no collected configuration and files in the folder. Fix: the Include unmanaged configuration checkbox never persisted from the source form. Migrations 0053 through 0057 and 0060 adopt the 2.9.x schema history. Org-backed deployments: run Publish Bundled Queries after upgrading, because the interface and IPv4 address queries changed their parameter lists (a stale published copy fails every execution against it until republished) and the three routing-policy queries gained an output column. |
76
+ | `v3.0.0` | NetBox `4.7.x` supported, tested on `4.7.0`; needs netbox-branching `1.2.x`, tested on `1.2.0` | Superseded by `v3.0.1`; NetBox 4.7 with netbox-branching 1.2, and change control gated on what Forward saw before and after the change. |
77
+ | `v2.9.2` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v3.0.0`; Drift is measured exactly for every fetched model, the uncovered-device count says why it grows and warns when it does, and five delete and diagnostic defects are closed. |
76
78
  | `v2.9.1` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.2`; Accepts netbox-branching 1.1.3 and records the validated runtime in the lockfile. |
77
79
  | `v2.9.0` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.1`; Feature: back up device configurations from Forward into a git data source for Validity golden-config checks, plus the runtime-validation refactor and health check it required. |
78
80
  | `v2.8.9` | `4.6.x` (>= `4.6.5`) supported, tested on `4.6.8`; needs netbox-branching `1.1.x`, tested on `1.1.2` | Superseded by `v2.9.0`; Fix: a sync deletes a device only on the same quarantined evidence the operator prune requires, and never stages a delete the database will refuse. |
@@ -5,7 +5,7 @@ class NetboxForwardConfig(PluginConfig):
5
5
  name = "forward_netbox"
6
6
  verbose_name = "Forward"
7
7
  description = "Sync Forward data into NetBox using built-in NQE queries."
8
- version = "3.0.0"
8
+ version = "3.0.2"
9
9
  base_url = "forward"
10
10
  min_version = "4.7.0"
11
11
  max_version = "4.7.99"
@@ -378,6 +378,13 @@ class ForwardIngestionIssueSerializer(OrganizationalModelSerializer):
378
378
  ingestion = ForwardIngestionSerializer(nested=True)
379
379
 
380
380
  def to_representation(self, instance):
381
+ # Tier 1, deliberately: this is an authenticated in-deployment read,
382
+ # the same trust level as the GUI, so `raw_data` keeps its
383
+ # `operator_detail` values here. The redaction applies to FILES - a
384
+ # support bundle is exported to be sent to us, and
385
+ # `export_redaction.export_safe_payload` drops that key on every
386
+ # download path. Do not "fix" this by filtering here; the operator
387
+ # troubleshooting their own estate is the reason the values exist.
381
388
  data = super().to_representation(instance)
382
389
  data["coalesce_fields"] = json_safe_value(data.get("coalesce_fields"))
383
390
  data["defaults"] = json_safe_value(data.get("defaults"))
@@ -40,8 +40,15 @@ from forward_netbox.models import ForwardNQEMap
40
40
  from forward_netbox.models import ForwardSource
41
41
  from forward_netbox.models import ForwardSync
42
42
  from forward_netbox.models import ForwardValidationRun
43
+ from forward_netbox.utilities.forward_api import get_committed_nqe_query
44
+ from forward_netbox.utilities.forward_api import get_latest_processed_snapshot
45
+ from forward_netbox.utilities.forward_api import get_networks
46
+ from forward_netbox.utilities.forward_api import get_nqe_query_history
47
+ from forward_netbox.utilities.forward_api import get_nqe_repository_query_index
48
+ from forward_netbox.utilities.forward_api import get_snapshots
43
49
  from forward_netbox.utilities.forward_api import LATEST_COLLECTED_SNAPSHOT
44
50
  from forward_netbox.utilities.forward_api import LATEST_PROCESSED_SNAPSHOT
51
+ from forward_netbox.utilities.forward_api import run_nqe_query
45
52
  from forward_netbox.utilities.query_binding import builtin_filename_to_query_default
46
53
  from forward_netbox.utilities.query_binding import query_filename_from_path
47
54
 
@@ -139,7 +146,7 @@ class ForwardSourceViewSet(NetBoxModelViewSet):
139
146
  results = []
140
147
  if source is not None:
141
148
  try:
142
- for network in source.get_client().get_networks():
149
+ for network in get_networks(source.get_client()):
143
150
  if (
144
151
  q
145
152
  and q not in network["label"].lower()
@@ -245,7 +252,7 @@ class ForwardSourceViewSet(NetBoxModelViewSet):
245
252
  tag_set = set()
246
253
  try:
247
254
  client = source.get_client()
248
- snapshot = client.get_latest_processed_snapshot(network_id)
255
+ snapshot = get_latest_processed_snapshot(client, network_id)
249
256
  snapshot_id = str(snapshot.get("id") or "").strip()
250
257
  if not snapshot_id:
251
258
  return Response(
@@ -259,7 +266,8 @@ class ForwardSourceViewSet(NetBoxModelViewSet):
259
266
  }
260
267
  )
261
268
 
262
- rows = client.run_nqe_query(
269
+ rows = run_nqe_query(
270
+ client,
263
271
  query=(
264
272
  "foreach device in network.devices\n"
265
273
  "where device.snapshotInfo.result == DeviceSnapshotResult.completed\n"
@@ -336,7 +344,8 @@ class ForwardNQEMapViewSet(NetBoxModelViewSet):
336
344
  )
337
345
 
338
346
  try:
339
- query_index = source.get_client().get_nqe_repository_query_index(
347
+ query_index = get_nqe_repository_query_index(
348
+ source.get_client(),
340
349
  repository=repository,
341
350
  directory="/",
342
351
  )
@@ -392,7 +401,8 @@ class ForwardNQEMapViewSet(NetBoxModelViewSet):
392
401
 
393
402
  results = []
394
403
  try:
395
- query_index = source.get_client().get_nqe_repository_query_index(
404
+ query_index = get_nqe_repository_query_index(
405
+ source.get_client(),
396
406
  repository=repository,
397
407
  directory=directory,
398
408
  )
@@ -472,7 +482,8 @@ class ForwardNQEMapViewSet(NetBoxModelViewSet):
472
482
  client = source.get_client()
473
483
  if query_path and not query_id:
474
484
  try:
475
- query_index = client.get_nqe_repository_query_index(
485
+ query_index = get_nqe_repository_query_index(
486
+ client,
476
487
  repository=repository,
477
488
  directory="/",
478
489
  )
@@ -482,14 +493,15 @@ class ForwardNQEMapViewSet(NetBoxModelViewSet):
482
493
  if indexed_query and indexed_query.get("queryId"):
483
494
  query_id = str(indexed_query.get("queryId") or "").strip()
484
495
  else:
485
- committed_query = client.get_committed_nqe_query(
496
+ committed_query = get_committed_nqe_query(
497
+ client,
486
498
  repository=repository,
487
499
  query_path=query_path,
488
500
  commit_id="head",
489
501
  query_index=query_index,
490
502
  )
491
503
  query_id = str(committed_query.get("queryId") or "").strip()
492
- commits = client.get_nqe_query_history(query_id)
504
+ commits = get_nqe_query_history(client, query_id)
493
505
  except Exception:
494
506
  return Response(
495
507
  {
@@ -592,7 +604,7 @@ class ForwardSyncViewSet(NetBoxModelViewSet):
592
604
  return Response({"count": len(results), "results": results})
593
605
 
594
606
  try:
595
- for snapshot in source.get_client().get_snapshots(network_id):
607
+ for snapshot in get_snapshots(source.get_client(), network_id):
596
608
  display = snapshot["label"]
597
609
  if q and q not in display.lower() and q not in snapshot["id"].lower():
598
610
  continue
@@ -928,6 +940,283 @@ class ForwardSyncViewSet(NetBoxModelViewSet):
928
940
  def tag_delete_eligible_ipam(self, request, pk):
929
941
  return self._enqueue_button_job_response(request, "tag_delete_eligible_ipam")
930
942
 
943
+ @extend_schema(
944
+ methods=["post"],
945
+ request=EmptySerializer(),
946
+ responses={
947
+ 201: JobSerializer(),
948
+ 202: OpenApiResponse(
949
+ description='{"status": "already_running", "job_id": N}'
950
+ ),
951
+ },
952
+ )
953
+ @action(detail=True, methods=["post"], url_path="recover-stuck-sync")
954
+ def recover_stuck_sync(self, request, pk):
955
+ return self._enqueue_button_job_response(request, "recover_stuck_sync")
956
+
957
+ @extend_schema(
958
+ methods=["post"],
959
+ request=EmptySerializer(),
960
+ responses={
961
+ 201: JobSerializer(),
962
+ 202: OpenApiResponse(
963
+ description=(
964
+ '{"status": "already_running"|"blocked_by_sync_run", '
965
+ '"job_id": N}'
966
+ )
967
+ ),
968
+ },
969
+ )
970
+ @action(detail=True, methods=["post"], url_path="prune-uncovered")
971
+ def prune_uncovered(self, request, pk):
972
+ return self._enqueue_button_job_response(request, "prune_uncovered")
973
+
974
+ @extend_schema(
975
+ methods=["post"],
976
+ request=EmptySerializer(),
977
+ responses={
978
+ 201: JobSerializer(),
979
+ 202: OpenApiResponse(
980
+ description=(
981
+ '{"status": "already_running"|"blocked_by_sync_run", '
982
+ '"job_id": N}'
983
+ )
984
+ ),
985
+ },
986
+ )
987
+ @action(detail=True, methods=["post"], url_path="prune-out-of-scope-catalogue")
988
+ def prune_out_of_scope_catalogue(self, request, pk):
989
+ return self._enqueue_button_job_response(
990
+ request, "prune_out_of_scope_catalogue"
991
+ )
992
+
993
+ @extend_schema(
994
+ methods=["post"],
995
+ request=EmptySerializer(),
996
+ responses={
997
+ 201: JobSerializer(),
998
+ 202: OpenApiResponse(
999
+ description=(
1000
+ '{"status": "already_running"|"blocked_by_sync_run", '
1001
+ '"job_id": N}'
1002
+ )
1003
+ ),
1004
+ },
1005
+ )
1006
+ @action(detail=True, methods=["post"], url_path="merge-site-relabel-duplicates")
1007
+ def merge_site_relabel_duplicates(self, request, pk):
1008
+ return self._enqueue_button_job_response(
1009
+ request, "merge_site_relabel_duplicates"
1010
+ )
1011
+
1012
+ @extend_schema(
1013
+ methods=["post"],
1014
+ responses={
1015
+ 201: JobSerializer(),
1016
+ 202: OpenApiResponse(
1017
+ description=(
1018
+ '{"status": "already_running"|"blocked_by_sync_run", '
1019
+ '"job_id": N}'
1020
+ )
1021
+ ),
1022
+ 400: OpenApiResponse(
1023
+ description="missing or malformed `device`/`expected_blockers`"
1024
+ ),
1025
+ },
1026
+ )
1027
+ @action(detail=True, methods=["post"], url_path="release-foreign-delete-blockers")
1028
+ def release_foreign_delete_blockers(self, request, pk):
1029
+ """Release exactly the netbox_routing rows named as delete blockers.
1030
+
1031
+ Unlike every other button action here, this one has no whole-set
1032
+ meaning - there is no device to act on without one being named - so
1033
+ it validates its own body rather than going through
1034
+ `_enqueue_button_job_response`, which assumes an empty POST is a
1035
+ complete request.
1036
+ """
1037
+ from ..utilities.sync_facade import button_job_permission
1038
+ from ..utilities.sync_facade import enqueue_button_job
1039
+ from ..utilities.sync_facade import JobAlreadyActive
1040
+ from ..utilities.sync_facade import JobBlockedBySyncRun
1041
+
1042
+ permission = button_job_permission("release_foreign_delete_blockers")
1043
+ if not request.user.has_perm(permission):
1044
+ raise PermissionDenied(
1045
+ f"This user does not have the `{permission}` permission."
1046
+ )
1047
+ data = request.data if isinstance(request.data, dict) else {}
1048
+ try:
1049
+ device_pk = int(data.get("device") or "")
1050
+ except (TypeError, ValueError):
1051
+ return Response(
1052
+ {"detail": "A `device` id is required."},
1053
+ status=status.HTTP_400_BAD_REQUEST,
1054
+ )
1055
+ expected_blockers = data.get("expected_blockers")
1056
+ if (
1057
+ not isinstance(expected_blockers, dict)
1058
+ or not expected_blockers
1059
+ or not all(
1060
+ isinstance(label, str) and isinstance(count, int)
1061
+ for label, count in expected_blockers.items()
1062
+ )
1063
+ ):
1064
+ return Response(
1065
+ {
1066
+ "detail": (
1067
+ "`expected_blockers` must name at least one blocking "
1068
+ "row as {label: count}."
1069
+ )
1070
+ },
1071
+ status=status.HTTP_400_BAD_REQUEST,
1072
+ )
1073
+ sync = self.get_object()
1074
+ try:
1075
+ job = enqueue_button_job(
1076
+ sync,
1077
+ "release_foreign_delete_blockers",
1078
+ request.user,
1079
+ job_kwargs={
1080
+ "device_pk": device_pk,
1081
+ "expected_blockers": expected_blockers,
1082
+ },
1083
+ )
1084
+ except JobBlockedBySyncRun as exc:
1085
+ return Response(
1086
+ {
1087
+ "status": "blocked_by_sync_run",
1088
+ "job_id": exc.job.pk,
1089
+ "detail": (
1090
+ "This operation is blocked while a Forward sync job "
1091
+ "is active."
1092
+ ),
1093
+ },
1094
+ status=status.HTTP_202_ACCEPTED,
1095
+ )
1096
+ except JobAlreadyActive as exc:
1097
+ return Response(
1098
+ {
1099
+ "status": "already_running",
1100
+ "job_id": exc.job.pk,
1101
+ "detail": "An equivalent job is already queued or running.",
1102
+ },
1103
+ status=status.HTTP_202_ACCEPTED,
1104
+ )
1105
+ return Response(
1106
+ JobSerializer(job, context={"request": request}).data, status=201
1107
+ )
1108
+
1109
+ @extend_schema(
1110
+ methods=["post"],
1111
+ request=EmptySerializer(),
1112
+ responses={
1113
+ 201: JobSerializer(),
1114
+ 202: OpenApiResponse(
1115
+ description=(
1116
+ '{"status": "already_running"|"blocked_by_sync_run", '
1117
+ '"job_id": N}'
1118
+ )
1119
+ ),
1120
+ },
1121
+ )
1122
+ @action(detail=True, methods=["post"], url_path="config-backup")
1123
+ def config_backup(self, request, pk):
1124
+ return self._enqueue_button_job_response(request, "config_backup")
1125
+
1126
+ @extend_schema(
1127
+ methods=["post"],
1128
+ request=EmptySerializer(),
1129
+ responses={
1130
+ 201: JobSerializer(),
1131
+ 202: OpenApiResponse(
1132
+ description='{"status": "already_running", "job_id": N}'
1133
+ ),
1134
+ },
1135
+ )
1136
+ @action(detail=True, methods=["post"], url_path="prune-stale-hardware-notices")
1137
+ def prune_stale_hardware_notices(self, request, pk):
1138
+ return self._enqueue_button_job_response(
1139
+ request, "prune_stale_hardware_notices"
1140
+ )
1141
+
1142
+ # Read-only audits that talk to Forward; the report pages render the
1143
+ # latest job. Same overlap guard and permission check as every button.
1144
+ @extend_schema(
1145
+ methods=["post"],
1146
+ request=EmptySerializer(),
1147
+ responses={
1148
+ 201: JobSerializer(),
1149
+ 202: OpenApiResponse(description="already running"),
1150
+ },
1151
+ )
1152
+ @action(detail=True, methods=["post"], url_path="audits/primary-ip")
1153
+ def audit_primary_ip(self, request, pk):
1154
+ return self._enqueue_button_job_response(request, "audit_primary_ip")
1155
+
1156
+ @extend_schema(
1157
+ methods=["post"],
1158
+ request=EmptySerializer(),
1159
+ responses={
1160
+ 201: JobSerializer(),
1161
+ 202: OpenApiResponse(description="already running"),
1162
+ },
1163
+ )
1164
+ @action(detail=True, methods=["post"], url_path="audits/global-ipam")
1165
+ def audit_global_ipam(self, request, pk):
1166
+ return self._enqueue_button_job_response(request, "audit_global_ipam")
1167
+
1168
+ @extend_schema(
1169
+ methods=["post"],
1170
+ request=EmptySerializer(),
1171
+ responses={
1172
+ 201: JobSerializer(),
1173
+ 202: OpenApiResponse(description="already running"),
1174
+ },
1175
+ )
1176
+ @action(detail=True, methods=["post"], url_path="audits/stale-hardware-notices")
1177
+ def audit_stale_hardware_notices(self, request, pk):
1178
+ return self._enqueue_button_job_response(
1179
+ request, "audit_stale_hardware_notices"
1180
+ )
1181
+
1182
+ @extend_schema(
1183
+ methods=["post"],
1184
+ request=EmptySerializer(),
1185
+ responses={
1186
+ 201: JobSerializer(),
1187
+ 202: OpenApiResponse(description="already running"),
1188
+ },
1189
+ )
1190
+ @action(detail=True, methods=["post"], url_path="audits/apply-identity")
1191
+ def audit_apply_identity(self, request, pk):
1192
+ return self._enqueue_button_job_response(request, "audit_apply_identity")
1193
+
1194
+ @extend_schema(
1195
+ methods=["post"],
1196
+ request=EmptySerializer(),
1197
+ responses={
1198
+ 201: JobSerializer(),
1199
+ 202: OpenApiResponse(description="already running"),
1200
+ },
1201
+ )
1202
+ @action(detail=True, methods=["post"], url_path="audits/apic-cimc-readiness")
1203
+ def audit_apic_cimc_readiness(self, request, pk):
1204
+ return self._enqueue_button_job_response(request, "audit_apic_cimc_readiness")
1205
+
1206
+ @extend_schema(
1207
+ methods=["post"],
1208
+ request=EmptySerializer(),
1209
+ responses={
1210
+ 201: JobSerializer(),
1211
+ 202: OpenApiResponse(description="already running"),
1212
+ },
1213
+ )
1214
+ @action(detail=True, methods=["post"], url_path="audits/fast-baseline-preflight")
1215
+ def audit_fast_baseline_preflight(self, request, pk):
1216
+ return self._enqueue_button_job_response(
1217
+ request, "audit_fast_baseline_preflight"
1218
+ )
1219
+
931
1220
 
932
1221
  class ForwardIngestionViewSet(NetBoxReadOnlyModelViewSet):
933
1222
  queryset = ForwardIngestion.objects.all()
@@ -6,6 +6,7 @@
6
6
  # would silently compare two different questions.
7
7
  from dataclasses import dataclass
8
8
 
9
+ from ..utilities.forward_api import resolve_nqe_query_reference
9
10
  from ..utilities.query_execution_contract import query_source_sha256
10
11
  from .choices import ForwardCriterionExpectationChoices as Expectation
11
12
 
@@ -31,7 +32,8 @@ def bind_criterion(criterion, client) -> BindResult:
31
32
  if not criterion.query_path:
32
33
  return BindResult(False, error="The criterion has no query path to bind.")
33
34
  try:
34
- resolved = client.resolve_nqe_query_reference(
35
+ resolved = resolve_nqe_query_reference(
36
+ client,
35
37
  repository="org",
36
38
  query_path=criterion.query_path,
37
39
  commit_id=criterion.commit_id or None,
@@ -10,6 +10,10 @@ FORWARD_BGP_MODELS = (
10
10
  "netbox_routing.ospfinstance",
11
11
  "netbox_routing.ospfarea",
12
12
  "netbox_routing.ospfinterface",
13
+ "netbox_routing.prefixlistentry",
14
+ "netbox_routing.communitylistentry",
15
+ "netbox_routing.routemapentry",
16
+ "netbox_routing.staticroute",
13
17
  "netbox_peering_manager.peeringsession",
14
18
  )
15
19
 
@@ -33,6 +37,13 @@ FORWARD_ACI_MODELS = (
33
37
  "netbox_cisco_aci.acibridgedomain",
34
38
  "netbox_cisco_aci.acifilter",
35
39
  "netbox_cisco_aci.acil3out",
40
+ "netbox_cisco_aci.aciappprofile",
41
+ "netbox_cisco_aci.aciendpointgroup",
42
+ "netbox_cisco_aci.acicontract",
43
+ "netbox_cisco_aci.acisubject",
44
+ "netbox_cisco_aci.acifilterentry",
45
+ "netbox_cisco_aci.acisubjectfilter",
46
+ "netbox_cisco_aci.acistaticportbinding",
36
47
  )
37
48
 
38
49
  FORWARD_SUPPORTED_MODELS = (
@@ -162,11 +162,45 @@ class ForwardIngestionIssueFilterSet(BaseFilterSet):
162
162
  choices=ForwardIngestionPhaseChoices,
163
163
  null_value=None,
164
164
  )
165
+ # "Which of these actually stops the baseline" was answerable only by
166
+ # running a command against the ingestion. Same predicate as readiness.
167
+ blocking = django_filters.BooleanFilter(
168
+ method="filter_blocking",
169
+ label="Blocks baseline readiness",
170
+ )
165
171
 
166
172
  class Meta:
167
173
  model = ForwardIngestionIssue
168
174
  fields = ("phase", "model", "timestamp", "exception", "message")
169
175
 
176
+ def filter_blocking(self, queryset, name, value):
177
+ from django.db.models import Q
178
+
179
+ from .utilities.ingestion_issues import blocking_issue_q
180
+
181
+ if value is None:
182
+ return queryset
183
+ # Matches the column, in both its exclusions. A row whose ingestion
184
+ # promoted blocked nothing; and a row the merge recorded as skipped
185
+ # blocked nothing either, because no retry can satisfy it - that is
186
+ # true whether or not the run went on to promote. Filtering to rows
187
+ # the column calls Blocking and getting back rows it calls Skipped or
188
+ # Promoted over is the same disagreement in the other direction.
189
+ #
190
+ # Rows written before 2.9.5 carry no `disposition` key, and they must
191
+ # keep their old behaviour with no migration. `~Q(disposition=...)`
192
+ # alone does NOT do that: a missing JSONB key reads as NULL, `NOT NULL`
193
+ # is NULL rather than true, and every legacy row would be dropped from
194
+ # the Blocking filter it used to match. The key's absence has to be
195
+ # tested explicitly.
196
+ not_skipped = ~Q(raw_data__has_key="disposition") | ~Q(
197
+ raw_data__disposition="skipped"
198
+ )
199
+ predicate = (
200
+ blocking_issue_q() & Q(ingestion__baseline_ready=False) & not_skipped
201
+ )
202
+ return queryset.filter(predicate if value else ~predicate)
203
+
170
204
  def search(self, queryset, name, value):
171
205
  if not value.strip():
172
206
  return queryset