forward-netbox 2.3.0__tar.gz → 2.3.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.
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/PKG-INFO +72 -89
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/README.md +69 -86
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/__init__.py +2 -2
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/forms.py +13 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/navigation.py +1 -1
- forward_netbox-2.3.2/forward_netbox/queries/forward_devices.nqe +82 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync_drift_report.html +10 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/brand_bar.html +3 -3
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_brand_bar.py +2 -2
- forward_netbox-2.3.2/forward_netbox/tests/test_endpoints_import.py +51 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_health.py +62 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync.py +28 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/model_validation.py +3 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_fetch_execution.py +8 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_registry.py +8 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_interface.py +5 -1
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/views.py +17 -1
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/pyproject.toml +5 -5
- forward_netbox-2.3.0/forward_netbox/queries/forward_devices.nqe +0 -41
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/LICENSE +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/api/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/api/serializers.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/api/urls.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/api/views.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/choices.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/exceptions.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/filtersets.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/jobs.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_apic_cimc_readiness_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_apply_identity_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_blocker_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_collection_gap_alert.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_device_scope_reconciliation_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_link_vsys_parents.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_metrics.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_module_readiness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_primary_ip_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_pushdown_profile.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_query_diff_coverage_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_scope_ipam_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_seed_ui_harness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_stuck_job_alert.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_tag_delete_eligible.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/management/commands/forward_validation_org_query_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0001_initial.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0002_add_coalesce_fields.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0003_forwardingestionissue_context_fields.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0004_forwardingestion_baseline_fields.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0005_validation_and_reporting.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0006_alter_forwardnqemap_netbox_model.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0007_forwardingestion_persisted_change_counters.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0008_alter_forwardnqemap_netbox_model.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0009_alter_forwardnqemap_netbox_model.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0010_forwardvalidationrun_override_applied_and_more.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0011_forwardingestion_change_request_id.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0012_forwardnqemap_query_reference.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0013_execution_run_step.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0014_execution_step_fetch_scope.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0015_execution_step_apply_engine.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0016_execution_step_query_metrics.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0017_execution_step_row_counters.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0018_execution_run_reconciliation_events.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0019_forwardexecutionstep_query_parameters.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0020_execution_step_operation.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0021_add_fhrpgroup_nqe_map_choice.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0022_alter_forwardnqemap_netbox_model.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0023_split_ip_address_maps.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0024_forwarddeviceanalysis.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0025_device_analysis_netboxmodel.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0026_forwarddeviceanalysis_collection_result.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0027_alter_forwardexecutionrun_backend.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0028_remove_forwardexecutionstep_run_and_more.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0029_forward_parent_device_cf.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0030_forwarddeviceanalysis_cve_ids.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/0031_encrypt_source_password.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/migrations/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/models.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_apic_cimc_inventory.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_apic_nodes.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_app_profiles.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_bridge_domains.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_command_inventory.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_contracts.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_endpoint_groups.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_fabrics.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_filters.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_l3outs.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_nodes.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_pods.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_static_port_bindings.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_tenants.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_aci_vrfs.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_bgp_address_families.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_bgp_peer_address_families.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_bgp_peers.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_analysis.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_feature_tags.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_feature_tags_with_rules.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_models.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_models_with_netbox_aliases.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_types.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_device_vendors.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_devices_with_netbox_aliases.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_hsrp_groups.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_inferred_interface_cables.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_interfaces.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_inventory_items.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ip_addresses_ipv4.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ip_addresses_ipv6.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ip_addresses_unassignable_diagnostics.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_locations.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_mac_addresses.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_modules.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ospf_areas.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ospf_instances.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_ospf_interfaces.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_peering_sessions.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_platforms.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_prefixes_ipv4.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_prefixes_ipv6.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_routing_import_diagnostics.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_virtual_chassis.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_vlans.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/forward_vrfs.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/queries/netbox_utilities.nqe +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/signals.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/static/forward_netbox/img/fn-logo.svg +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tables.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/template_content.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwarddriftpolicy.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardingestion.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardnqemap.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsource.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync_dependency_preview.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync_health.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync_module_readiness.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardsync_scope_reconciliation.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/forwardvalidationrun.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/device_analysis_panel.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/diff.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/execution_insights.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/logs_pending.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/merge_form.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/inc/validation_force_allow_form.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/change_explainability.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/ingestion_all.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/ingestion_merge_button.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/ingestion_progress.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/ingestion_statistics.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/ingestion_status.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/job_logs.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/object_tabs.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/stage_switcher_buttons.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templates/forward_netbox/partials/validation_force_allow_button.html +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templatetags/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/templatetags/forward_netbox_helpers.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/fixtures/aci_command_inventory_expected.json +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/fixtures/aci_discovery_expected.json +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/scenarios.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_api_usage.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_api_views.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_apic_cimc_readiness_audit_command.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_apply_engine.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_apply_identity_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_branching.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_bulk_adapter_parity.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_bulk_merge.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_bulk_merge_scale.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_crypto.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_dependency_preview_summary.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_device_analysis_query.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_device_scope_reconciliation_audit_command.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_device_scope_tagging.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_execution_insights_delete_label.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_forms.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_forward_api.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_ingestion_merge.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_interface_naming.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_ip_address_dedup_query.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_ipaddress_dup_global.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_issue_rendering.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_job_compat.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_job_liveness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_jobs.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_log_export.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_logging.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_migrations.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_models.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_module_readiness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_module_readiness_rollup.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_plugin_integrations.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_primary_ip.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_primary_ip_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_primary_ip_integration.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_query_binding.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_query_diff_coverage_audit_command.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_query_registry.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_release_readiness_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_runtime_dependency_check.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_scope_ipam_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_scope_matched_tags.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_scope_module_ui.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sensitive_content.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_stability_hardening.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync_aci.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync_facade.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync_orchestration.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync_runner_contracts.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_sync_state.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_synthetic_scenarios.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_validation_org_query_audit_command.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/tests/test_vsys_parent.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/urls.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/api_usage.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/apply_engine.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/apply_engine_bulk.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/apply_engine_decision.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/apply_identity_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/branch_budget.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/branching.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/bulk_merge.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/change_explainability.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/crypto.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/density_learning.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/device_analysis.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/direct_changes.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/drift_report.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/execution_ledger.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/execution_telemetry.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/fast_bootstrap_executor.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/fetch_artifacts.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/forward_api.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/forward_api_impl.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/health.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/health_apply_fetch.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/health_checks.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/health_summary_blocks.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/ingestion_issues.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/ingestion_merge.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/ingestion_presentation.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/interface_naming.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/job_compat.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/job_liveness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/json_safe.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/logging.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/merge.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/model_contracts.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/module_readiness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/multi_branch_lifecycle.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/plugin_integrations/__init__.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/plugin_integrations/registry.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/primary_ip.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/primary_ip_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_binding.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_binding_resolution.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_diagnostics.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/query_fetch.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/runtime_guidance.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/scope_ipam_audit.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/scope_reconciliation.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sensitive_content.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/single_branch_executor.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/snapshot_freshness.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/support_bundle_archive.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_aci.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_cable.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_contracts.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_core_models.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_device.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_events.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_execution.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_facade.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_inventory_module.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_ipam.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_orchestration.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_primitives.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_reporting.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_routing.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_routing_impl.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_runner_adapters.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_runner_contracts.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/sync_state.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/validation.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/validation_org_query.py +0 -0
- {forward_netbox-2.3.0 → forward_netbox-2.3.2}/forward_netbox/utilities/vsys_parent.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: forward-netbox
|
|
3
|
-
Version: 2.3.
|
|
3
|
+
Version: 2.3.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
|
|
@@ -8,7 +8,7 @@ Keywords: netbox,forward,plugin,sync,nqe
|
|
|
8
8
|
Author: Craig Johnson
|
|
9
9
|
Author-email: craigjohnson@forwardnetworks.com
|
|
10
10
|
Requires-Python: >=3.10,<4.0
|
|
11
|
-
Classifier: Development Status ::
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
12
|
Classifier: Framework :: Django
|
|
13
13
|
Classifier: Intended Audience :: Information Technology
|
|
14
14
|
Classifier: Intended Audience :: System Administrators
|
|
@@ -23,7 +23,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
23
23
|
Classifier: Topic :: System :: Networking
|
|
24
24
|
Requires-Dist: httpx (>0.26,<0.29)
|
|
25
25
|
Requires-Dist: netboxlabs-netbox-branching (>=1.1.0)
|
|
26
|
-
Requires-Dist: pyzipper (>=0.3.6,<0.
|
|
26
|
+
Requires-Dist: pyzipper (>=0.3.6,<0.5.0)
|
|
27
27
|
Project-URL: Changelog, https://github.com/forwardnetworks/forward-netbox/blob/main/CHANGELOG.md
|
|
28
28
|
Project-URL: Documentation, https://github.com/forwardnetworks/forward-netbox/tree/main/docs
|
|
29
29
|
Project-URL: Homepage, https://github.com/forwardnetworks/forward-netbox
|
|
@@ -31,17 +31,77 @@ Project-URL: Issue Tracker, https://github.com/forwardnetworks/forward-netbox/is
|
|
|
31
31
|
Project-URL: Repository, https://github.com/forwardnetworks/forward-netbox
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
33
33
|
|
|
34
|
-
# Forward
|
|
34
|
+
# Forward Integration for NetBox
|
|
35
35
|
|
|
36
|
-
**Forward
|
|
36
|
+
**Forward Integration for NetBox** (`forward_netbox`) is a NetBox plugin that syncs Forward Networks inventory into NetBox.
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
[](https://pypi.org/project/forward-netbox/)
|
|
39
|
+
[](https://github.com/forwardnetworks/forward-netbox/actions/workflows/ci.yml)
|
|
40
|
+
|
|
41
|
+
## Status
|
|
42
|
+
|
|
43
|
+
- **Support model:** field integration reference — **not** an officially
|
|
44
|
+
supported Forward Networks product.
|
|
45
|
+
- **Requires:** NetBox `4.6.4`, `netbox-branching` `1.1.0+`; Forward `26.6`
|
|
46
|
+
baseline for async NQE (full matrix in
|
|
47
|
+
[Release Compatibility](#release-compatibility)).
|
|
48
|
+
- **Distribution:** PyPI (`forward-netbox`) + GitHub releases.
|
|
49
|
+
|
|
50
|
+
## What It Does
|
|
51
|
+
|
|
52
|
+
It pulls your Forward-discovered inventory into NetBox — devices, interfaces, IP addresses, prefixes, VLANs, VRFs, cables, LAGs, MAC addresses, and inventory items. It runs Forward NQE against a chosen snapshot, stages every change in a `netbox_branching` branch so you can review the diff, then merges when it looks right.
|
|
53
|
+
|
|
54
|
+
On top of the import it adds scope control (sync only devices carrying chosen Forward tags), orphan pruning, per-device analysis (reachability, connectivity blast-radius, CVE exposure), a drift report, and snapshot selection.
|
|
55
|
+
|
|
56
|
+
## What It Does Not Do
|
|
57
|
+
|
|
58
|
+
- **It does not write back to Forward.** The sync is one-way, Forward → NetBox;
|
|
59
|
+
Forward stays the source of truth and the plugin keeps NetBox populated from
|
|
60
|
+
what Forward collected. (The drift report only *compares* the two.)
|
|
61
|
+
- **It is not a source of truth for Forward configuration or intent** — it
|
|
62
|
+
populates NetBox from Forward's collected snapshot, nothing more.
|
|
63
|
+
- **It does not require** the optional `netbox-routing` / `netbox-peering-manager`
|
|
64
|
+
plugins unless you enable the beta BGP/OSPF maps.
|
|
65
|
+
|
|
66
|
+
## Screenshots
|
|
67
|
+
|
|
68
|
+
**Sync — health, enabled models, and actions**
|
|
69
|
+
|
|
70
|
+

|
|
71
|
+
|
|
72
|
+
**Staged ingestion — progress, snapshot metrics, and issues**
|
|
73
|
+
|
|
74
|
+

|
|
75
|
+
|
|
76
|
+
**Drift report — per-model NetBox-vs-Forward divergence**
|
|
77
|
+
|
|
78
|
+

|
|
79
|
+
|
|
80
|
+
**Forward sources**
|
|
81
|
+
|
|
82
|
+

|
|
83
|
+
|
|
84
|
+
## Architecture
|
|
85
|
+
|
|
86
|
+
Forward NQE runs against a selected snapshot to fetch inventory, each model's
|
|
87
|
+
rows are staged into a `netbox_branching` branch as a reviewable per-model diff,
|
|
88
|
+
and you merge when the changes look correct. Large baselines can use a
|
|
89
|
+
`Fast bootstrap` direct-write backend; steady-state runs use Branching with
|
|
90
|
+
Forward `nqe-diffs` so every change is reviewable. See the
|
|
91
|
+
[Architecture Flow](docs/02_Reference/architecture-flow.md) reference for detail.
|
|
39
92
|
|
|
40
93
|
## Release Compatibility
|
|
41
94
|
|
|
95
|
+
Latest release requires NetBox `4.6.4` and `netbox-branching` `1.1.0+`. Expand for the full per-release history and notes.
|
|
96
|
+
|
|
97
|
+
<details>
|
|
98
|
+
<summary>Release compatibility history</summary>
|
|
99
|
+
|
|
42
100
|
| Plugin Release | NetBox Version | Status |
|
|
43
101
|
| --- | --- | --- |
|
|
44
|
-
| `v2.3.
|
|
102
|
+
| `v2.3.2` | `4.6.4` required; needs netbox-branching `1.1.0+` | Current release; Feature: optional import of Forward SNMP endpoints (e.g. Avocent console servers) as NetBox devices — off by default (`sync_endpoints`), enabled per source and scoped by the same device tags. |
|
|
103
|
+
| `v2.3.1` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.2`; |
|
|
104
|
+
| `v2.3.0` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.1`; GA/enterprise hardening: encrypted Forward credential at rest, PyPI Trusted Publishing + SBOM, Prometheus metrics + stuck-job alert, populated-DB upgrade test, dead-code removal (multi_branch/density-learning), reliability fixes (jittered/Retry-After backoff, SaaS rate clamp, PK-anchored device prune), and supported-product framing. Drop-in from 2.2.5 — stored credentials auto-encrypt on save; rotating SECRET_KEY requires re-entering them. |
|
|
45
105
|
| `v2.2.5` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.0`; Feature: operator-selectable **Sync Device Tags** — pick which Forward device tags (e.g. `Mgmt_*`) become NetBox device tags (replaces the hardcoded feature-tag set); Fix dependency-preview AttributeError + vsys job pile-up guard (hung pending); test/require NetBox 4.6.4 |
|
|
46
106
|
| `v2.2.4` | `4.6.3` required; needs netbox-branching `1.1.0+` | Superseded by `v2.2.5`; Hotfix: device-analysis NQE (bare foreach) errored refresh + CVE list; surface job errors into job.data |
|
|
47
107
|
| `v2.2.3` | `4.6.3` required; needs netbox-branching `1.1.0+` | Superseded by `v2.2.4`; Field-feedback fixes: delete-count labeling, vsys/vdom auto-link, skip empty VRFs, per-device CVE list, churn pinpoint, query-ID status clarify |
|
|
@@ -137,91 +197,14 @@ Forward 26.6 is the baseline for async NQE.
|
|
|
137
197
|
| `v0.3.0.1` | `4.5.8` validated; `4.5.x` only | Superseded by `v0.3.1` |
|
|
138
198
|
| `v0.3.0` | `4.5.8` validated; `4.5.x` only | Superseded by `v0.3.0.1` |
|
|
139
199
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
| Release | Summary |
|
|
143
|
-
| --- | --- |
|
|
144
|
-
| `v1.5.0.1` | Fixes platform NQE query (`normalizePlatformName`), adds `--overwrite` to validation-org repair, hardens org-publish commit to retry on 409 INVALID_CHANGE_PATH. |
|
|
145
|
-
| `v1.5.0` | Hardens ingest throughput: adaptive async-NQE poll backoff, ndjson streaming, webhook/event-rule signal suppression during apply, targeted validation on existing objects (skips DB-hitting uniqueness checks in both bulk engine paths), and async advanced-reachability trigger (FWD-53559). Full suite green on NetBox 4.5.9 and 4.6.2. |
|
|
146
|
-
| `v1.4.3` | Hardens query provenance with source-backed query-id repair during preflight, adds async execution path readiness for 26.6 with resilient NDJSON/JSONL result handling, and proves CIMC/APIC platform/type updates from command-source evidence while preserving prior 1.4 protections. |
|
|
147
|
-
| `v1.4.2` | Adds CIMC platform separation, visible query-drift repair and dependency preview on the sync detail page, and keeps module-bay merge hardening plus parent-interface description preservation. |
|
|
148
|
-
| `v1.4.1.1` | Prevents optional module sync from creating `dcim.modulebay` side-effect changes during merge, skips missing module bays with a readiness/import warning, and keeps LAG member rows from clearing existing parent interface descriptions. |
|
|
149
|
-
| `v1.4.1` | Publishes the 1.4 patch release line with query-ID drift remediation and support-bundle diagnostics on top of the parent-device contract and release surfaces. |
|
|
150
|
-
| `v1.3.6` | Enforces a hard parent-device sync contract so child models cannot run without `dcim.device`, preventing stale sync configs from skipping the device shard and breaking dependent imports. |
|
|
151
|
-
| `v1.3.5.5` | Adds compressed support-bundle ZIP downloads with optional password protection and folds live source/query-drift/data-file diagnostics into the troubleshooting bundle. |
|
|
152
|
-
| `v1.3.5.4` | Republishes the `v1.3.5.3` query-contract hardening as the prior patch release. |
|
|
153
|
-
| `v1.3.5.3` | Preserves the claimed-step and payload-compaction protections from `v1.3.5.2`, adds strict shipped-query parameter-contract validation, strips legacy tag aliases from runtime NQE payloads, and keeps support-bundle previews summary-only. |
|
|
154
|
-
| `v1.3.5.2` | Prevents shard execution drift by tying resume/overlap workers to the claimed execution step and compacts sync execution payloads (`plan_items`, workload previews, and advisory branch summaries) so large runs remain user-visible but lightweight in UI/log exports. |
|
|
155
|
-
| `v1.3.5.1` | Removes the raw `model_results` payload from sync telemetry summaries and stops unparameterized query IDs from inheriting source-level tag parameters, which keeps sync-detail rendering responsive while preserving the saved-query-ID path. |
|
|
156
|
-
| `v1.3.5` | Tightens the saved-query-ID path for 1.3.x, keeps shipped maps parameter-compatible with `forward_netbox_shard_keys`, and uses command-inventory signals to avoid misclassifying ACI platforms during repeat syncs. |
|
|
157
|
-
| `v1.3.4` | Makes non-retryable Branching merge errors operator-visible by persisting the failure reason before the job terminates, marks branches still stuck in `Merging` as `Failed`, preserves timeout/transient retry behavior, and adds disabled-by-default async NQE client support for the future Forward 26.6 execution API. |
|
|
158
|
-
| `v1.3.3` | Refreshes shipped NQE syntax so saved query IDs accept the standard `forward_netbox_shard_keys` parameter payload, republishes the saved validation-folder query set, and validates the affected saved query IDs against a live Forward SaaS dataset. |
|
|
159
|
-
| `v1.3.2` | Adds optional `netbox-cisco-aci` plugin support with disabled-by-default ACI fabric, pod, node, tenant, VRF, and filter maps; keeps deeper ACI policy maps conservative until source identity is proven; and hardens duplicate ACI node observations so repeat syncs remain no-op when source data is unchanged. |
|
|
160
|
-
| `v1.3.1` | Fixes repeat prefix sync accounting by treating unchanged NetBox `ipam.prefix` rows as unchanged, avoids dependency VRF metadata rewrites from prefix/IP/FHRP imports, removes the legacy sync column-filter shard path, and preserves the `v1.3.0` parameterized NQE path. |
|
|
161
|
-
| `v1.3.0` | Eliminates default Forward NQE column-filter shard fetches in favor of query-side `forward_netbox_shard_keys` parameters, keeps local shard safety filtering, and preserves branch boundaries while reducing Forward SaaS API/NQE pressure. |
|
|
162
|
-
| `v1.2.3` | Coalesces compatible sibling shard column-filter fetches into bounded EQUALS_ANY requests, caches prefetched sibling rows locally to avoid repeated Forward calls, and surfaces local Branching change-explainability summaries in support bundles and the ingestion UI. |
|
|
163
|
-
| `v1.2.2` | Adds operator-visible Forward API usage budgets/rate evidence in Sync Health and support bundles, extends repeat-sync no-op hardening across key adapters, and persists successful staged deletes into ingestion statistics so active delete shards are visible before merge accounting catches up. |
|
|
164
|
-
| `v1.2.1` | Fixes repeat prefix sync churn where otherwise unchanged `ipam.prefix` rows could be updated only because the VRF foreign key was re-resolved; built-in prefix maps now use exact `prefix + vrf` identity while prefix shard fetches still use parameterized NQE. |
|
|
165
|
-
| `v1.2.0` | Adds optional NetBox-native HSRP/VRRP FHRP import from Forward native FHRP state, bounded access/native interface VLAN assignment from existing site-scoped VLANs, keeps FHRP upgrade behavior safe for existing 1.1 IPAM data, and hardens current NetBox job-test compatibility. |
|
|
166
|
-
| `v1.1.1` | Adds optional NetBox-native HSRP/FHRP import from Forward native FHRP state, keeps FHRP upgrade behavior safe for existing 1.1 IPAM data, and hardens current NetBox job-test compatibility. |
|
|
167
|
-
| `v1.1.0` | Adds Forward SaaS API request pacing, parameterized prefix shard execution, single-pass interface NQE, configured max-shard persistence in smoke evidence, and release-validation gates for API/NQE scale validation. |
|
|
168
|
-
| `v1.0.0` | Introduced the first `v1.0.0` release line and initial API/NQE release validation flow before the 1.1 runtime and request-pacing enhancements. |
|
|
169
|
-
| `v0.9.4.6` | Tightens delete-heavy `dcim.device` cleanup planning to about 500 planned delete rows per 10k branch-change budget after live shard evidence showed the earlier estimate was still too high. |
|
|
170
|
-
| `v0.9.4.5` | Plans delete-heavy `dcim.device` cleanup shards with a conservative row budget so tag-scope prune runs do not pack thousands of cascading device deletes into one Branching shard. |
|
|
171
|
-
| `v0.9.4.4` | Clarifies large branching progress by clamping utilization display to 100% during intermediate accounting overshoots and showing current shard row progress in the ingestion UI. |
|
|
172
|
-
| `v0.9.4.3` | Converts NetBox protected-reference delete failures into dependency skips so large tag-scope prune/device cleanup runs continue without shard-failing delete rows. |
|
|
173
|
-
| `v0.9.4.1.1` | Keeps the shared 4.5/4.6 branch line, execution ledger, support logging, and scale hardening while preserving the read-only advisory surfaces from `v0.9.0`. |
|
|
174
|
-
| `v0.9.0` | Adds read-only analysis, workload preview, advisory summaries, and native log export for troubleshooting while keeping lifecycle enrichment and predict deferred. |
|
|
175
|
-
| `v0.8.6.3` | Hardens beta routing scope resolution, filters invalid BGP ASN rows in shipped NQE, skips positionless virtual-chassis rows conservatively, and lets fast bootstrap retain its diff baseline when only optional model issues remain. |
|
|
176
|
-
| `v0.8.6.2` | Hardens issue and job-log rendering for JSON safety when unexpected nested payload objects leak into failure data. |
|
|
177
|
-
| `v0.8.6.1` | Clarifies NQE map bulk edit labels and help text so operators use repository query paths and understand query IDs are resolved automatically during sync and diff execution. |
|
|
178
|
-
| `v0.8.6` | Publishes flattened built-in NQE to Forward org repositories, filters IPv4 host/any/loopback prefix artifacts, reports IP rows missing imported parent prefixes on full baselines, and prevents stale virtual-chassis/device/routing row failures from blocking unrelated models. |
|
|
179
|
-
| `v0.8.5` | Makes the beta routing and module maps broadly available by default, preserves the conservative bundled virtual chassis map, handles Forward repository query lookups that return a `queries` list, and makes failed sync activity show the terminal failure instead of stale row heartbeat text. |
|
|
180
|
-
| `v0.8.3` | Isolates stale or invalid per-model query output, rejects virtual-chassis rows missing `vc_position`, records row issues without aborting later multi-branch shards, and prevents dirty runs from becoming diff baselines. |
|
|
181
|
-
| `v0.8.2` | Adds portable repository `query_path` execution with Forward-backed selectors, true native bulk edit for publishing bundled NQE into the Forward Org Repository, binding selected maps to repository paths, restoring bundled raw NQE, and clearer skipping for IP address rows whose interface cannot be resolved. |
|
|
182
|
-
| `v0.8.1.1` | Emits `vc_position` in the built-in virtual chassis NQE map for vPC and MLAG memberships so NetBox does not reject virtual chassis device assignments without a member position. |
|
|
183
|
-
| `v0.8.1` | Runs fast bootstrap inside native NetBox change tracking, shows branchless ingestion changes from `ObjectChange` rows, updates fast-bootstrap counters from real object changes, warns about undersized worker timeouts, and retries transient Forward API HTTP timeouts/gateway responses. |
|
|
184
|
-
| `v0.8.0` | Adds an opt-in fast bootstrap direct-write backend for trusted large baselines, keeps NQE validation and row adapters shared with Branching, and skips LAG cable endpoints that NetBox cannot cable directly. |
|
|
185
|
-
| `v0.7.1` | Keeps the NetBox-native multi-branch workflow stable while hardening cable ingestion, retry handling, and shard re-planning for large runs. |
|
|
186
|
-
| `v0.7.0` | Splits the remaining sync orchestration, reporting, and validation helpers into dedicated boundaries, adds shard heartbeat visibility, and preserves the NetBox-native branch workflow. |
|
|
187
|
-
| `v0.6.5` | Adds audited validation force-allow overrides and routing evidence enrichment while reducing skipped routing rows through conservative NQE-side identity inference. |
|
|
188
|
-
| `v0.6.4` | Adds beta optional routing and peering imports for `netbox-routing` and `netbox-peering-manager`, including BGP peers, BGP address families, OSPF objects, peering sessions, routing diagnostics, and query-ID-aware built-in map handling. |
|
|
189
|
-
| `v0.6.3` | Models Forward aggregate interfaces as native NetBox LAGs, attaches member interfaces through `Interface.lag`, and keeps the MTU value sourced from Forward's normalized interface field. |
|
|
190
|
-
| `v0.6.2` | Canonicalizes duplicate global-table IP address rows by host IP before import and records row-scoped apply/delete failures as ingestion issues without aborting the rest of the shard. |
|
|
191
|
-
| `v0.6.1` | Filters interface IP rows that NetBox cannot assign, such as subnet network IDs and IPv4 broadcasts, while reporting aggregate diagnostics for filtered addresses. |
|
|
192
|
-
| `v0.6.0` | Adds beta native `dcim.module` import for chassis modules and similar bay-aware hardware, improves inventory item normalization, and avoids duplicate generic inventory rows when beta module sync is enabled. |
|
|
193
|
-
| `v0.5.9.1` | Keeps job logs visible during execution by persisting plugin log entries into the native NetBox job log tab while preserving the full plugin ingestion log view. |
|
|
194
|
-
| `v0.5.9` | Balances query preflight and workload fetch with bounded parallelism, reducing long planning pauses on large datasets. |
|
|
195
|
-
| `v0.5.8` | Defers event flushing until commit so large prefix ingestions do not trip transaction state changes mid-run. |
|
|
196
|
-
| `v0.5.5` | Applies a consistent model conflict policy for cable sync rows: skip occupied-interface conflicts, aggregate warning spam, and keep non-conflict updates/creates unchanged. |
|
|
197
|
-
| `v0.5.4` | Persists ingestion change counters so list/detail values stay consistent after branch merge cleanup, matching merge summaries. |
|
|
198
|
-
| `v0.5.3` | Surfaces preflight activity and elapsed phase timing on sync detail, emits early phase logs before ingestion rows, and sets source status to `Syncing` while runs are active. |
|
|
199
|
-
| `v0.5.2.1` | Fixes plugin admin version display and ships inferred cable query parser compatibility update (no `let` declarations) while preserving synthetic endpoint filtering. |
|
|
200
|
-
| `v0.4.0` | Corrects built-in IPv4/IPv6 prefix NQE filters to exclude host routes (`/32` and `/128`) from prefix import and validates the behavior against a live smoke dataset. |
|
|
201
|
-
| `v0.3.1` | Adds optional data-file-aware device type alias maps, a Device Type Library alias data-file builder, and documentation for the snapshot requirement while keeping the default no-data-file maps available. |
|
|
202
|
-
| `v0.3.0.1` | Fixes the validation-run list UI by removing unsupported edit actions from read-only validation records, and adds Playwright coverage for the validation-run list route. |
|
|
203
|
-
| `v0.3.0` | Adds the NetBox 4.5.8-validated harness architecture with first-class validation runs, drift policies, query-fetch boundaries, model-result reporting, and Playwright-covered UI workflow validation. |
|
|
204
|
-
| `v0.2.4` | Hardens native multi-branch resilience with adaptive shard splitting and retry on branch-budget overflow, plus model-density tracking to keep large initial syncs within NetBox branching guidance. |
|
|
205
|
-
| `v0.2.3` | Adds native sync preflight validation before full multi-branch planning so invalid model/query rows fail earlier in the UI/API run path. |
|
|
206
|
-
| `v0.2.2` | NQE-only correction release: filters zero-length prefixes, broadens interface coverage for IP assignment targets, and enforces inventory `part_id` length limits. |
|
|
207
|
-
| `v0.2.1` | Makes NetBox-native multi-branch execution the only UI/API sync path and exposes the branch budget in the sync form. |
|
|
208
|
-
| `v0.2.0` | Adds NetBox-native multi-branch baseline syncs for large datasets, uses NetBox outbound proxy routing for Forward API calls, and keeps branch event queues bounded during large imports. |
|
|
209
|
-
| `v0.1.6.0` | Adds explicit diff baselines, Forward `nqe-diffs` execution for eligible `query_id` maps, and updated large-dataset guidance for baseline versus incremental syncs. |
|
|
210
|
-
| `v0.1.5.1` | Patch release that validates and hardens null-VRF coalesce behavior and inventory-item serial bounds against the live dataset. |
|
|
211
|
-
| `v0.1.5` | Fixes null VRF coalesce handling, imports loopback interfaces for IP attachment, and hardens inventory-item identity fallbacks. |
|
|
212
|
-
| `v0.1.4.2` | CI/package patch release that applies repository formatting/import-order fixes and publishes a clean artifact line. |
|
|
213
|
-
| `v0.1.4.1` | Patch release that bounds built-in `dcim.virtualchassis` names/domains to NetBox field limits. |
|
|
214
|
-
| `v0.1.4` | Hardened built-in NQE mappings and docs for large real-world datasets. |
|
|
215
|
-
| `v0.1.3` | Enforced deterministic model identity contracts during sync ingestion. |
|
|
216
|
-
| `v0.1.2` | Improved ingestion safety, diagnostics, and compatibility with custom NetBox data. |
|
|
217
|
-
| `v0.1.1` | Added pagination, shared built-in NQE helpers, and release/doc cleanup. |
|
|
218
|
-
| `v0.1.0` | Initial unsupported NetBox plugin release with built-in Forward sync workflow and seeded NQE maps. |
|
|
200
|
+
</details>
|
|
219
201
|
|
|
220
202
|
## Support
|
|
221
203
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
204
|
+
This is a **field integration** maintained by a Forward Networks SE — a reference
|
|
205
|
+
integration, **not an officially supported Forward Networks product**, provided
|
|
206
|
+
as-is with no SLA. Supported NetBox and `netbox-branching` versions are listed in
|
|
207
|
+
the Release Compatibility table above; fixes target the latest released version.
|
|
225
208
|
|
|
226
209
|
- **Bugs / feature requests:** open a GitHub issue using the provided templates.
|
|
227
210
|
- **Security vulnerabilities:** report privately per [SECURITY.md](SECURITY.md) —
|
|
@@ -1,14 +1,74 @@
|
|
|
1
|
-
# Forward
|
|
1
|
+
# Forward Integration for NetBox
|
|
2
2
|
|
|
3
|
-
**Forward
|
|
3
|
+
**Forward Integration for NetBox** (`forward_netbox`) is a NetBox plugin that syncs Forward Networks inventory into NetBox.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://pypi.org/project/forward-netbox/)
|
|
6
|
+
[](https://github.com/forwardnetworks/forward-netbox/actions/workflows/ci.yml)
|
|
7
|
+
|
|
8
|
+
## Status
|
|
9
|
+
|
|
10
|
+
- **Support model:** field integration reference — **not** an officially
|
|
11
|
+
supported Forward Networks product.
|
|
12
|
+
- **Requires:** NetBox `4.6.4`, `netbox-branching` `1.1.0+`; Forward `26.6`
|
|
13
|
+
baseline for async NQE (full matrix in
|
|
14
|
+
[Release Compatibility](#release-compatibility)).
|
|
15
|
+
- **Distribution:** PyPI (`forward-netbox`) + GitHub releases.
|
|
16
|
+
|
|
17
|
+
## What It Does
|
|
18
|
+
|
|
19
|
+
It pulls your Forward-discovered inventory into NetBox — devices, interfaces, IP addresses, prefixes, VLANs, VRFs, cables, LAGs, MAC addresses, and inventory items. It runs Forward NQE against a chosen snapshot, stages every change in a `netbox_branching` branch so you can review the diff, then merges when it looks right.
|
|
20
|
+
|
|
21
|
+
On top of the import it adds scope control (sync only devices carrying chosen Forward tags), orphan pruning, per-device analysis (reachability, connectivity blast-radius, CVE exposure), a drift report, and snapshot selection.
|
|
22
|
+
|
|
23
|
+
## What It Does Not Do
|
|
24
|
+
|
|
25
|
+
- **It does not write back to Forward.** The sync is one-way, Forward → NetBox;
|
|
26
|
+
Forward stays the source of truth and the plugin keeps NetBox populated from
|
|
27
|
+
what Forward collected. (The drift report only *compares* the two.)
|
|
28
|
+
- **It is not a source of truth for Forward configuration or intent** — it
|
|
29
|
+
populates NetBox from Forward's collected snapshot, nothing more.
|
|
30
|
+
- **It does not require** the optional `netbox-routing` / `netbox-peering-manager`
|
|
31
|
+
plugins unless you enable the beta BGP/OSPF maps.
|
|
32
|
+
|
|
33
|
+
## Screenshots
|
|
34
|
+
|
|
35
|
+
**Sync — health, enabled models, and actions**
|
|
36
|
+
|
|
37
|
+

|
|
38
|
+
|
|
39
|
+
**Staged ingestion — progress, snapshot metrics, and issues**
|
|
40
|
+
|
|
41
|
+

|
|
42
|
+
|
|
43
|
+
**Drift report — per-model NetBox-vs-Forward divergence**
|
|
44
|
+
|
|
45
|
+

|
|
46
|
+
|
|
47
|
+
**Forward sources**
|
|
48
|
+
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
## Architecture
|
|
52
|
+
|
|
53
|
+
Forward NQE runs against a selected snapshot to fetch inventory, each model's
|
|
54
|
+
rows are staged into a `netbox_branching` branch as a reviewable per-model diff,
|
|
55
|
+
and you merge when the changes look correct. Large baselines can use a
|
|
56
|
+
`Fast bootstrap` direct-write backend; steady-state runs use Branching with
|
|
57
|
+
Forward `nqe-diffs` so every change is reviewable. See the
|
|
58
|
+
[Architecture Flow](docs/02_Reference/architecture-flow.md) reference for detail.
|
|
6
59
|
|
|
7
60
|
## Release Compatibility
|
|
8
61
|
|
|
62
|
+
Latest release requires NetBox `4.6.4` and `netbox-branching` `1.1.0+`. Expand for the full per-release history and notes.
|
|
63
|
+
|
|
64
|
+
<details>
|
|
65
|
+
<summary>Release compatibility history</summary>
|
|
66
|
+
|
|
9
67
|
| Plugin Release | NetBox Version | Status |
|
|
10
68
|
| --- | --- | --- |
|
|
11
|
-
| `v2.3.
|
|
69
|
+
| `v2.3.2` | `4.6.4` required; needs netbox-branching `1.1.0+` | Current release; Feature: optional import of Forward SNMP endpoints (e.g. Avocent console servers) as NetBox devices — off by default (`sync_endpoints`), enabled per source and scoped by the same device tags. |
|
|
70
|
+
| `v2.3.1` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.2`; |
|
|
71
|
+
| `v2.3.0` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.1`; GA/enterprise hardening: encrypted Forward credential at rest, PyPI Trusted Publishing + SBOM, Prometheus metrics + stuck-job alert, populated-DB upgrade test, dead-code removal (multi_branch/density-learning), reliability fixes (jittered/Retry-After backoff, SaaS rate clamp, PK-anchored device prune), and supported-product framing. Drop-in from 2.2.5 — stored credentials auto-encrypt on save; rotating SECRET_KEY requires re-entering them. |
|
|
12
72
|
| `v2.2.5` | `4.6.4` required; needs netbox-branching `1.1.0+` | Superseded by `v2.3.0`; Feature: operator-selectable **Sync Device Tags** — pick which Forward device tags (e.g. `Mgmt_*`) become NetBox device tags (replaces the hardcoded feature-tag set); Fix dependency-preview AttributeError + vsys job pile-up guard (hung pending); test/require NetBox 4.6.4 |
|
|
13
73
|
| `v2.2.4` | `4.6.3` required; needs netbox-branching `1.1.0+` | Superseded by `v2.2.5`; Hotfix: device-analysis NQE (bare foreach) errored refresh + CVE list; surface job errors into job.data |
|
|
14
74
|
| `v2.2.3` | `4.6.3` required; needs netbox-branching `1.1.0+` | Superseded by `v2.2.4`; Field-feedback fixes: delete-count labeling, vsys/vdom auto-link, skip empty VRFs, per-device CVE list, churn pinpoint, query-ID status clarify |
|
|
@@ -104,91 +164,14 @@ Forward 26.6 is the baseline for async NQE.
|
|
|
104
164
|
| `v0.3.0.1` | `4.5.8` validated; `4.5.x` only | Superseded by `v0.3.1` |
|
|
105
165
|
| `v0.3.0` | `4.5.8` validated; `4.5.x` only | Superseded by `v0.3.0.1` |
|
|
106
166
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
| Release | Summary |
|
|
110
|
-
| --- | --- |
|
|
111
|
-
| `v1.5.0.1` | Fixes platform NQE query (`normalizePlatformName`), adds `--overwrite` to validation-org repair, hardens org-publish commit to retry on 409 INVALID_CHANGE_PATH. |
|
|
112
|
-
| `v1.5.0` | Hardens ingest throughput: adaptive async-NQE poll backoff, ndjson streaming, webhook/event-rule signal suppression during apply, targeted validation on existing objects (skips DB-hitting uniqueness checks in both bulk engine paths), and async advanced-reachability trigger (FWD-53559). Full suite green on NetBox 4.5.9 and 4.6.2. |
|
|
113
|
-
| `v1.4.3` | Hardens query provenance with source-backed query-id repair during preflight, adds async execution path readiness for 26.6 with resilient NDJSON/JSONL result handling, and proves CIMC/APIC platform/type updates from command-source evidence while preserving prior 1.4 protections. |
|
|
114
|
-
| `v1.4.2` | Adds CIMC platform separation, visible query-drift repair and dependency preview on the sync detail page, and keeps module-bay merge hardening plus parent-interface description preservation. |
|
|
115
|
-
| `v1.4.1.1` | Prevents optional module sync from creating `dcim.modulebay` side-effect changes during merge, skips missing module bays with a readiness/import warning, and keeps LAG member rows from clearing existing parent interface descriptions. |
|
|
116
|
-
| `v1.4.1` | Publishes the 1.4 patch release line with query-ID drift remediation and support-bundle diagnostics on top of the parent-device contract and release surfaces. |
|
|
117
|
-
| `v1.3.6` | Enforces a hard parent-device sync contract so child models cannot run without `dcim.device`, preventing stale sync configs from skipping the device shard and breaking dependent imports. |
|
|
118
|
-
| `v1.3.5.5` | Adds compressed support-bundle ZIP downloads with optional password protection and folds live source/query-drift/data-file diagnostics into the troubleshooting bundle. |
|
|
119
|
-
| `v1.3.5.4` | Republishes the `v1.3.5.3` query-contract hardening as the prior patch release. |
|
|
120
|
-
| `v1.3.5.3` | Preserves the claimed-step and payload-compaction protections from `v1.3.5.2`, adds strict shipped-query parameter-contract validation, strips legacy tag aliases from runtime NQE payloads, and keeps support-bundle previews summary-only. |
|
|
121
|
-
| `v1.3.5.2` | Prevents shard execution drift by tying resume/overlap workers to the claimed execution step and compacts sync execution payloads (`plan_items`, workload previews, and advisory branch summaries) so large runs remain user-visible but lightweight in UI/log exports. |
|
|
122
|
-
| `v1.3.5.1` | Removes the raw `model_results` payload from sync telemetry summaries and stops unparameterized query IDs from inheriting source-level tag parameters, which keeps sync-detail rendering responsive while preserving the saved-query-ID path. |
|
|
123
|
-
| `v1.3.5` | Tightens the saved-query-ID path for 1.3.x, keeps shipped maps parameter-compatible with `forward_netbox_shard_keys`, and uses command-inventory signals to avoid misclassifying ACI platforms during repeat syncs. |
|
|
124
|
-
| `v1.3.4` | Makes non-retryable Branching merge errors operator-visible by persisting the failure reason before the job terminates, marks branches still stuck in `Merging` as `Failed`, preserves timeout/transient retry behavior, and adds disabled-by-default async NQE client support for the future Forward 26.6 execution API. |
|
|
125
|
-
| `v1.3.3` | Refreshes shipped NQE syntax so saved query IDs accept the standard `forward_netbox_shard_keys` parameter payload, republishes the saved validation-folder query set, and validates the affected saved query IDs against a live Forward SaaS dataset. |
|
|
126
|
-
| `v1.3.2` | Adds optional `netbox-cisco-aci` plugin support with disabled-by-default ACI fabric, pod, node, tenant, VRF, and filter maps; keeps deeper ACI policy maps conservative until source identity is proven; and hardens duplicate ACI node observations so repeat syncs remain no-op when source data is unchanged. |
|
|
127
|
-
| `v1.3.1` | Fixes repeat prefix sync accounting by treating unchanged NetBox `ipam.prefix` rows as unchanged, avoids dependency VRF metadata rewrites from prefix/IP/FHRP imports, removes the legacy sync column-filter shard path, and preserves the `v1.3.0` parameterized NQE path. |
|
|
128
|
-
| `v1.3.0` | Eliminates default Forward NQE column-filter shard fetches in favor of query-side `forward_netbox_shard_keys` parameters, keeps local shard safety filtering, and preserves branch boundaries while reducing Forward SaaS API/NQE pressure. |
|
|
129
|
-
| `v1.2.3` | Coalesces compatible sibling shard column-filter fetches into bounded EQUALS_ANY requests, caches prefetched sibling rows locally to avoid repeated Forward calls, and surfaces local Branching change-explainability summaries in support bundles and the ingestion UI. |
|
|
130
|
-
| `v1.2.2` | Adds operator-visible Forward API usage budgets/rate evidence in Sync Health and support bundles, extends repeat-sync no-op hardening across key adapters, and persists successful staged deletes into ingestion statistics so active delete shards are visible before merge accounting catches up. |
|
|
131
|
-
| `v1.2.1` | Fixes repeat prefix sync churn where otherwise unchanged `ipam.prefix` rows could be updated only because the VRF foreign key was re-resolved; built-in prefix maps now use exact `prefix + vrf` identity while prefix shard fetches still use parameterized NQE. |
|
|
132
|
-
| `v1.2.0` | Adds optional NetBox-native HSRP/VRRP FHRP import from Forward native FHRP state, bounded access/native interface VLAN assignment from existing site-scoped VLANs, keeps FHRP upgrade behavior safe for existing 1.1 IPAM data, and hardens current NetBox job-test compatibility. |
|
|
133
|
-
| `v1.1.1` | Adds optional NetBox-native HSRP/FHRP import from Forward native FHRP state, keeps FHRP upgrade behavior safe for existing 1.1 IPAM data, and hardens current NetBox job-test compatibility. |
|
|
134
|
-
| `v1.1.0` | Adds Forward SaaS API request pacing, parameterized prefix shard execution, single-pass interface NQE, configured max-shard persistence in smoke evidence, and release-validation gates for API/NQE scale validation. |
|
|
135
|
-
| `v1.0.0` | Introduced the first `v1.0.0` release line and initial API/NQE release validation flow before the 1.1 runtime and request-pacing enhancements. |
|
|
136
|
-
| `v0.9.4.6` | Tightens delete-heavy `dcim.device` cleanup planning to about 500 planned delete rows per 10k branch-change budget after live shard evidence showed the earlier estimate was still too high. |
|
|
137
|
-
| `v0.9.4.5` | Plans delete-heavy `dcim.device` cleanup shards with a conservative row budget so tag-scope prune runs do not pack thousands of cascading device deletes into one Branching shard. |
|
|
138
|
-
| `v0.9.4.4` | Clarifies large branching progress by clamping utilization display to 100% during intermediate accounting overshoots and showing current shard row progress in the ingestion UI. |
|
|
139
|
-
| `v0.9.4.3` | Converts NetBox protected-reference delete failures into dependency skips so large tag-scope prune/device cleanup runs continue without shard-failing delete rows. |
|
|
140
|
-
| `v0.9.4.1.1` | Keeps the shared 4.5/4.6 branch line, execution ledger, support logging, and scale hardening while preserving the read-only advisory surfaces from `v0.9.0`. |
|
|
141
|
-
| `v0.9.0` | Adds read-only analysis, workload preview, advisory summaries, and native log export for troubleshooting while keeping lifecycle enrichment and predict deferred. |
|
|
142
|
-
| `v0.8.6.3` | Hardens beta routing scope resolution, filters invalid BGP ASN rows in shipped NQE, skips positionless virtual-chassis rows conservatively, and lets fast bootstrap retain its diff baseline when only optional model issues remain. |
|
|
143
|
-
| `v0.8.6.2` | Hardens issue and job-log rendering for JSON safety when unexpected nested payload objects leak into failure data. |
|
|
144
|
-
| `v0.8.6.1` | Clarifies NQE map bulk edit labels and help text so operators use repository query paths and understand query IDs are resolved automatically during sync and diff execution. |
|
|
145
|
-
| `v0.8.6` | Publishes flattened built-in NQE to Forward org repositories, filters IPv4 host/any/loopback prefix artifacts, reports IP rows missing imported parent prefixes on full baselines, and prevents stale virtual-chassis/device/routing row failures from blocking unrelated models. |
|
|
146
|
-
| `v0.8.5` | Makes the beta routing and module maps broadly available by default, preserves the conservative bundled virtual chassis map, handles Forward repository query lookups that return a `queries` list, and makes failed sync activity show the terminal failure instead of stale row heartbeat text. |
|
|
147
|
-
| `v0.8.3` | Isolates stale or invalid per-model query output, rejects virtual-chassis rows missing `vc_position`, records row issues without aborting later multi-branch shards, and prevents dirty runs from becoming diff baselines. |
|
|
148
|
-
| `v0.8.2` | Adds portable repository `query_path` execution with Forward-backed selectors, true native bulk edit for publishing bundled NQE into the Forward Org Repository, binding selected maps to repository paths, restoring bundled raw NQE, and clearer skipping for IP address rows whose interface cannot be resolved. |
|
|
149
|
-
| `v0.8.1.1` | Emits `vc_position` in the built-in virtual chassis NQE map for vPC and MLAG memberships so NetBox does not reject virtual chassis device assignments without a member position. |
|
|
150
|
-
| `v0.8.1` | Runs fast bootstrap inside native NetBox change tracking, shows branchless ingestion changes from `ObjectChange` rows, updates fast-bootstrap counters from real object changes, warns about undersized worker timeouts, and retries transient Forward API HTTP timeouts/gateway responses. |
|
|
151
|
-
| `v0.8.0` | Adds an opt-in fast bootstrap direct-write backend for trusted large baselines, keeps NQE validation and row adapters shared with Branching, and skips LAG cable endpoints that NetBox cannot cable directly. |
|
|
152
|
-
| `v0.7.1` | Keeps the NetBox-native multi-branch workflow stable while hardening cable ingestion, retry handling, and shard re-planning for large runs. |
|
|
153
|
-
| `v0.7.0` | Splits the remaining sync orchestration, reporting, and validation helpers into dedicated boundaries, adds shard heartbeat visibility, and preserves the NetBox-native branch workflow. |
|
|
154
|
-
| `v0.6.5` | Adds audited validation force-allow overrides and routing evidence enrichment while reducing skipped routing rows through conservative NQE-side identity inference. |
|
|
155
|
-
| `v0.6.4` | Adds beta optional routing and peering imports for `netbox-routing` and `netbox-peering-manager`, including BGP peers, BGP address families, OSPF objects, peering sessions, routing diagnostics, and query-ID-aware built-in map handling. |
|
|
156
|
-
| `v0.6.3` | Models Forward aggregate interfaces as native NetBox LAGs, attaches member interfaces through `Interface.lag`, and keeps the MTU value sourced from Forward's normalized interface field. |
|
|
157
|
-
| `v0.6.2` | Canonicalizes duplicate global-table IP address rows by host IP before import and records row-scoped apply/delete failures as ingestion issues without aborting the rest of the shard. |
|
|
158
|
-
| `v0.6.1` | Filters interface IP rows that NetBox cannot assign, such as subnet network IDs and IPv4 broadcasts, while reporting aggregate diagnostics for filtered addresses. |
|
|
159
|
-
| `v0.6.0` | Adds beta native `dcim.module` import for chassis modules and similar bay-aware hardware, improves inventory item normalization, and avoids duplicate generic inventory rows when beta module sync is enabled. |
|
|
160
|
-
| `v0.5.9.1` | Keeps job logs visible during execution by persisting plugin log entries into the native NetBox job log tab while preserving the full plugin ingestion log view. |
|
|
161
|
-
| `v0.5.9` | Balances query preflight and workload fetch with bounded parallelism, reducing long planning pauses on large datasets. |
|
|
162
|
-
| `v0.5.8` | Defers event flushing until commit so large prefix ingestions do not trip transaction state changes mid-run. |
|
|
163
|
-
| `v0.5.5` | Applies a consistent model conflict policy for cable sync rows: skip occupied-interface conflicts, aggregate warning spam, and keep non-conflict updates/creates unchanged. |
|
|
164
|
-
| `v0.5.4` | Persists ingestion change counters so list/detail values stay consistent after branch merge cleanup, matching merge summaries. |
|
|
165
|
-
| `v0.5.3` | Surfaces preflight activity and elapsed phase timing on sync detail, emits early phase logs before ingestion rows, and sets source status to `Syncing` while runs are active. |
|
|
166
|
-
| `v0.5.2.1` | Fixes plugin admin version display and ships inferred cable query parser compatibility update (no `let` declarations) while preserving synthetic endpoint filtering. |
|
|
167
|
-
| `v0.4.0` | Corrects built-in IPv4/IPv6 prefix NQE filters to exclude host routes (`/32` and `/128`) from prefix import and validates the behavior against a live smoke dataset. |
|
|
168
|
-
| `v0.3.1` | Adds optional data-file-aware device type alias maps, a Device Type Library alias data-file builder, and documentation for the snapshot requirement while keeping the default no-data-file maps available. |
|
|
169
|
-
| `v0.3.0.1` | Fixes the validation-run list UI by removing unsupported edit actions from read-only validation records, and adds Playwright coverage for the validation-run list route. |
|
|
170
|
-
| `v0.3.0` | Adds the NetBox 4.5.8-validated harness architecture with first-class validation runs, drift policies, query-fetch boundaries, model-result reporting, and Playwright-covered UI workflow validation. |
|
|
171
|
-
| `v0.2.4` | Hardens native multi-branch resilience with adaptive shard splitting and retry on branch-budget overflow, plus model-density tracking to keep large initial syncs within NetBox branching guidance. |
|
|
172
|
-
| `v0.2.3` | Adds native sync preflight validation before full multi-branch planning so invalid model/query rows fail earlier in the UI/API run path. |
|
|
173
|
-
| `v0.2.2` | NQE-only correction release: filters zero-length prefixes, broadens interface coverage for IP assignment targets, and enforces inventory `part_id` length limits. |
|
|
174
|
-
| `v0.2.1` | Makes NetBox-native multi-branch execution the only UI/API sync path and exposes the branch budget in the sync form. |
|
|
175
|
-
| `v0.2.0` | Adds NetBox-native multi-branch baseline syncs for large datasets, uses NetBox outbound proxy routing for Forward API calls, and keeps branch event queues bounded during large imports. |
|
|
176
|
-
| `v0.1.6.0` | Adds explicit diff baselines, Forward `nqe-diffs` execution for eligible `query_id` maps, and updated large-dataset guidance for baseline versus incremental syncs. |
|
|
177
|
-
| `v0.1.5.1` | Patch release that validates and hardens null-VRF coalesce behavior and inventory-item serial bounds against the live dataset. |
|
|
178
|
-
| `v0.1.5` | Fixes null VRF coalesce handling, imports loopback interfaces for IP attachment, and hardens inventory-item identity fallbacks. |
|
|
179
|
-
| `v0.1.4.2` | CI/package patch release that applies repository formatting/import-order fixes and publishes a clean artifact line. |
|
|
180
|
-
| `v0.1.4.1` | Patch release that bounds built-in `dcim.virtualchassis` names/domains to NetBox field limits. |
|
|
181
|
-
| `v0.1.4` | Hardened built-in NQE mappings and docs for large real-world datasets. |
|
|
182
|
-
| `v0.1.3` | Enforced deterministic model identity contracts during sync ingestion. |
|
|
183
|
-
| `v0.1.2` | Improved ingestion safety, diagnostics, and compatibility with custom NetBox data. |
|
|
184
|
-
| `v0.1.1` | Added pagination, shared built-in NQE helpers, and release/doc cleanup. |
|
|
185
|
-
| `v0.1.0` | Initial unsupported NetBox plugin release with built-in Forward sync workflow and seeded NQE maps. |
|
|
167
|
+
</details>
|
|
186
168
|
|
|
187
169
|
## Support
|
|
188
170
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
171
|
+
This is a **field integration** maintained by a Forward Networks SE — a reference
|
|
172
|
+
integration, **not an officially supported Forward Networks product**, provided
|
|
173
|
+
as-is with no SLA. Supported NetBox and `netbox-branching` versions are listed in
|
|
174
|
+
the Release Compatibility table above; fixes target the latest released version.
|
|
192
175
|
|
|
193
176
|
- **Bugs / feature requests:** open a GitHub issue using the provided templates.
|
|
194
177
|
- **Security vulnerabilities:** report privately per [SECURITY.md](SECURITY.md) —
|
|
@@ -6,9 +6,9 @@ except ModuleNotFoundError: # pragma: no cover - tooling imports outside NetBox
|
|
|
6
6
|
|
|
7
7
|
class NetboxForwardConfig(PluginConfig):
|
|
8
8
|
name = "forward_netbox"
|
|
9
|
-
verbose_name = "Forward
|
|
9
|
+
verbose_name = "Forward"
|
|
10
10
|
description = "Sync Forward data into NetBox using built-in NQE queries."
|
|
11
|
-
version = "2.3.
|
|
11
|
+
version = "2.3.2"
|
|
12
12
|
base_url = "forward"
|
|
13
13
|
min_version = "4.6.4"
|
|
14
14
|
|
|
@@ -436,6 +436,16 @@ class ForwardSourceForm(NetBoxModelForm):
|
|
|
436
436
|
"filtered in NetBox."
|
|
437
437
|
),
|
|
438
438
|
)
|
|
439
|
+
self.fields["sync_endpoints"] = forms.BooleanField(
|
|
440
|
+
required=False,
|
|
441
|
+
label="Import SNMP Endpoints as Devices",
|
|
442
|
+
help_text=(
|
|
443
|
+
"Also import Forward SNMP endpoints (generic SSH/SNMP devices "
|
|
444
|
+
"Forward collects but does not model as first-class devices, "
|
|
445
|
+
"e.g. Avocent console servers) as NetBox devices, scoped by the "
|
|
446
|
+
"same device tags."
|
|
447
|
+
),
|
|
448
|
+
)
|
|
439
449
|
self.fields["sync_device_tags"] = FlexibleMultipleChoiceField(
|
|
440
450
|
required=False,
|
|
441
451
|
choices=(),
|
|
@@ -605,6 +615,7 @@ class ForwardSourceForm(NetBoxModelForm):
|
|
|
605
615
|
self.fields["device_tag_include_tags"].initial = include_initial
|
|
606
616
|
self.fields["device_tag_exclude_tags"].initial = exclude_initial
|
|
607
617
|
self.fields["sync_device_tags"].initial = sync_tags_initial
|
|
618
|
+
self.fields["sync_endpoints"].initial = bool(parameters.get("sync_endpoints"))
|
|
608
619
|
self.fields["device_tag_include_tags"].choices = [
|
|
609
620
|
(tag, tag) for tag in include_initial
|
|
610
621
|
]
|
|
@@ -840,6 +851,7 @@ class ForwardSourceForm(NetBoxModelForm):
|
|
|
840
851
|
),
|
|
841
852
|
"apply_device_scope_tags": bool(cleaned.get("apply_device_scope_tags")),
|
|
842
853
|
"sync_device_tags": sync_device_tags,
|
|
854
|
+
"sync_endpoints": bool(cleaned.get("sync_endpoints")),
|
|
843
855
|
}
|
|
844
856
|
self.instance.type = source_type
|
|
845
857
|
self.instance.url = (
|
|
@@ -1033,6 +1045,7 @@ class ForwardSourceForm(NetBoxModelForm):
|
|
|
1033
1045
|
self.cleaned_data.get("apply_device_scope_tags")
|
|
1034
1046
|
),
|
|
1035
1047
|
"sync_device_tags": sync_device_tags,
|
|
1048
|
+
"sync_endpoints": bool(self.cleaned_data.get("sync_endpoints")),
|
|
1036
1049
|
}
|
|
1037
1050
|
self.instance.status = ForwardSourceStatusChoices.NEW
|
|
1038
1051
|
return super().save(*args, **kwargs)
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @intent Devices collected by Forward (plus optional SNMP endpoints)
|
|
3
|
+
* @description Devices to add or update in NetBox via POST/PATCH to
|
|
4
|
+
* /api/dcim/devices/. When sync_endpoints is true, generic SNMP endpoints that
|
|
5
|
+
* Forward collects but does not model as first-class devices (e.g. Avocent
|
|
6
|
+
* console servers) are also emitted as device rows, identified from standard
|
|
7
|
+
* MIB-2 (sysName/sysDescr/sysObjectId) with per-vendor overlays, and scoped by
|
|
8
|
+
* the same device tags.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import "netbox_utilities";
|
|
12
|
+
|
|
13
|
+
@query
|
|
14
|
+
f(forward_netbox_shard_keys: List<String>, sync_endpoints: Bool, device_tag_include_tags: List<String>, device_tag_include_match: String, device_tag_exclude_tags: List<String>) =
|
|
15
|
+
foreach row in (
|
|
16
|
+
(
|
|
17
|
+
foreach device in network.devices
|
|
18
|
+
where device.snapshotInfo.result == DeviceSnapshotResult.completed
|
|
19
|
+
where device.platform.vendor != Vendor.FORWARD_CUSTOM
|
|
20
|
+
where isEmpty(forward_netbox_shard_keys) || device.name in forward_netbox_shard_keys
|
|
21
|
+
let model = toString(device.platform.model)
|
|
22
|
+
let role_name = replace(toString(device.platform.deviceType), "DeviceType.", "")
|
|
23
|
+
let site_name = if isPresent(device.locationName) then toLowerCase(device.locationName) else "unknown"
|
|
24
|
+
let platform_name = normalizeDevicePlatformName(device)
|
|
25
|
+
let manufacturer_name = canonicalManufacturerName(device.platform.vendor)
|
|
26
|
+
let manufacturer_slug = slugify(manufacturer_name)
|
|
27
|
+
select {
|
|
28
|
+
name: device.name,
|
|
29
|
+
manufacturer: manufacturer_name,
|
|
30
|
+
device_type: model,
|
|
31
|
+
device_type_slug: slugifyNetboxModel(model),
|
|
32
|
+
site: site_name,
|
|
33
|
+
site_slug: slugify(site_name),
|
|
34
|
+
role: role_name,
|
|
35
|
+
role_slug: slugify(role_name),
|
|
36
|
+
role_color: "9e9e9e",
|
|
37
|
+
platform: platform_name,
|
|
38
|
+
platform_slug: slugify(platform_name),
|
|
39
|
+
status: "active",
|
|
40
|
+
manufacturer_slug: manufacturer_slug
|
|
41
|
+
}
|
|
42
|
+
)
|
|
43
|
+
+
|
|
44
|
+
(
|
|
45
|
+
// SNMP endpoints (opt-in): generic SSH/SNMP devices Forward collects but
|
|
46
|
+
// does not model. Generic identity from MIB-2; Avocent overlay by enterprise
|
|
47
|
+
// OID 10418. Scoped by the same device tags (endpoints carry tagNames).
|
|
48
|
+
foreach endpoint in network.endpoints
|
|
49
|
+
where sync_endpoints
|
|
50
|
+
where !isEmpty(endpoint.snmpOutputs)
|
|
51
|
+
where isEmpty(device_tag_include_tags)
|
|
52
|
+
|| (device_tag_include_match == "all"
|
|
53
|
+
&& all(foreach tag in device_tag_include_tags select tag in endpoint.tagNames))
|
|
54
|
+
|| (device_tag_include_match != "all"
|
|
55
|
+
&& any(foreach tag in device_tag_include_tags select tag in endpoint.tagNames))
|
|
56
|
+
where isEmpty(device_tag_exclude_tags)
|
|
57
|
+
|| !any(foreach tag in device_tag_exclude_tags select tag in endpoint.tagNames)
|
|
58
|
+
let sysDescrOpt = max(foreach o in endpoint.snmpOutputs where o.requestedOid == "1.3.6.1.2.1.1.1" select max(foreach e in o.rawOidEntries select e.rawValue))
|
|
59
|
+
let sysObjIdOpt = max(foreach o in endpoint.snmpOutputs where o.requestedOid == "1.3.6.1.2.1.1.2" select max(foreach e in o.rawOidEntries select e.rawValue))
|
|
60
|
+
let sysDescr = if isPresent(sysDescrOpt) then sysDescrOpt else "SNMP Endpoint"
|
|
61
|
+
let isAvocent = matches(if isPresent(sysObjIdOpt) then sysObjIdOpt else "", "*10418*")
|
|
62
|
+
let ep_manuf = if isAvocent then "Avocent" else replaceRegexMatches(sysDescr, re` .*`, "")
|
|
63
|
+
let ep_role = if isAvocent then "Console Server" else "SNMP Endpoint"
|
|
64
|
+
let ep_site = if isPresent(endpoint.locationName) then toLowerCase(endpoint.locationName) else "unknown"
|
|
65
|
+
select {
|
|
66
|
+
name: endpoint.name,
|
|
67
|
+
manufacturer: ep_manuf,
|
|
68
|
+
device_type: sysDescr,
|
|
69
|
+
device_type_slug: slugifyNetboxModel(sysDescr),
|
|
70
|
+
site: ep_site,
|
|
71
|
+
site_slug: slugify(ep_site),
|
|
72
|
+
role: ep_role,
|
|
73
|
+
role_slug: slugify(ep_role),
|
|
74
|
+
role_color: "9e9e9e",
|
|
75
|
+
platform: ep_manuf,
|
|
76
|
+
platform_slug: slugify(ep_manuf),
|
|
77
|
+
status: "active",
|
|
78
|
+
manufacturer_slug: slugify(ep_manuf)
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
select row;
|
|
@@ -11,6 +11,16 @@
|
|
|
11
11
|
{% endblock extra_controls %}
|
|
12
12
|
|
|
13
13
|
{% block content %}
|
|
14
|
+
{% if drift_stale %}
|
|
15
|
+
<div class="alert alert-warning d-flex align-items-center" role="alert">
|
|
16
|
+
<i class="mdi mdi-alert me-2" aria-hidden="true"></i>
|
|
17
|
+
<div>
|
|
18
|
+
{% trans "This drift is computed from a dependency preview, but a newer sync has run since — the numbers below are stale." %}
|
|
19
|
+
{% trans "Preview:" %} {{ preview_at|placeholder }} · {% trans "Last sync:" %} {{ last_sync_at|placeholder }}.
|
|
20
|
+
{% trans "Re-run Preview Dependencies for current drift." %}
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
{% endif %}
|
|
14
24
|
<div class="row mb-3">
|
|
15
25
|
<div class="col col-md-4">
|
|
16
26
|
<div class="card">
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{% load static %}
|
|
2
2
|
{% load i18n %}
|
|
3
3
|
{% comment %}
|
|
4
|
-
Forward
|
|
4
|
+
Forward Integration for NetBox brand bar. Self-contained, theme-aware (logo wordmark
|
|
5
5
|
uses currentColor), no global NetBox style overrides. ff3506 is Forward's accent.
|
|
6
6
|
{% endcomment %}
|
|
7
7
|
<style>
|
|
@@ -10,8 +10,8 @@ uses currentColor), no global NetBox style overrides. ff3506 is Forward's accent
|
|
|
10
10
|
.fwd-brand-bar .fwd-name{font-weight:600;font-size:.8rem;letter-spacing:.01em;}
|
|
11
11
|
.fwd-brand-bar .fwd-tag{font-size:.72rem;opacity:.6;margin-left:auto;}
|
|
12
12
|
</style>
|
|
13
|
-
<div class="fwd-brand-bar" title="Forward
|
|
13
|
+
<div class="fwd-brand-bar" title="Forward Integration for NetBox">
|
|
14
14
|
<img class="fwd-logo" src="{% static 'forward_netbox/img/fn-logo.svg' %}" alt="Forward">
|
|
15
|
-
<span class="fwd-name">{% trans "
|
|
15
|
+
<span class="fwd-name">{% trans "Forward" %}</span>
|
|
16
16
|
<span class="fwd-tag">{% trans "Forward Networks · NetBox" %}</span>
|
|
17
17
|
</div>
|
|
@@ -3,14 +3,14 @@ from django.test import TestCase
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class BrandBarTemplateTest(TestCase):
|
|
6
|
-
"""The Forward
|
|
6
|
+
"""The Forward Integration for NetBox brand bar must render the logo + label, and
|
|
7
7
|
must NOT leak its template comment as visible text (a multi-line {# #} comment
|
|
8
8
|
is not a comment in Django and rendered literally on the page)."""
|
|
9
9
|
|
|
10
10
|
def test_brand_bar_renders_without_leaking_comment(self):
|
|
11
11
|
html = render_to_string("forward_netbox/inc/brand_bar.html")
|
|
12
12
|
self.assertIn("fwd-brand-bar", html)
|
|
13
|
-
self.assertIn("
|
|
13
|
+
self.assertIn(">Forward</span>", html)
|
|
14
14
|
self.assertIn("fn-logo.svg", html)
|
|
15
15
|
# The {% comment %} block must be stripped — none of its words appear.
|
|
16
16
|
self.assertNotIn("Self-contained", html)
|