Skip to content

Oxidized Import Tool

Oxidized Import Tool: Automated Device Migration to rConfig V8

Section titled “Oxidized Import Tool: Automated Device Migration to rConfig V8”

The Oxidized Import Tool enables seamless migration of network devices from Oxidized to rConfig V8. This command-line utility automates the process of mapping device types, parsing Oxidized host files, and importing devices with proper templates, credentials, and configurations—eliminating manual data entry and ensuring consistency across your device inventory.

Available in rConfig V8. This tool significantly reduces migration time by automating device type mapping and bulk imports.

While Oxidized excels at configuration collection, rConfig V8 provides a comprehensive network configuration management platform with:

Advanced scheduling: Flexible task scheduling with cron-based timing and dependency management

Template engine: Configuration snippet deployment across device groups with variable substitution

Compliance auditing: Policy-based configuration validation with automated remediation workflows

Rich reporting: Detailed analytics, change tracking, and configuration comparison tools

Role-based access: Granular permission controls for team collaboration and audit compliance

The Oxidized Import Tool makes this transition seamless with automated device onboarding.

The import process follows three steps:

  1. Create device type mappings: Define how Oxidized device types translate to rConfig templates, vendors, and categories
  2. Load devices from Oxidized: Parse the Oxidized hosts file and generate import-ready JSON
  3. Import devices to rConfig: Bulk import devices with validated configurations and immediate backup scheduling

The import tool uses the following file locations:

  • Mappings file: storage/app/rconfig/oxidized_mappings.json
  • Temporary files: storage/app/rconfig/tempdir/
  • Import JSON files: storage/app/rconfig/tempdir/rconfig_import_YYYY-MM-DD_HH-mm-ss.json
  • Failure logs: storage/app/rconfig/tempdir/oxidized_import_failures_YYYY-MM-DD_HH-mm-ss.txt

These directories are created automatically if they don’t exist.

Before importing devices, ensure you have:

  • Oxidized hosts file (router.db or equivalent)
  • Administrator access to rConfig V8
  • Device templates configured in rConfig matching your Oxidized device types
  • At least one credential set created in rConfig (required for devices without embedded credentials)
  • Connection profiles or credential sets created in rConfig
  • SSH/command-line access to the rConfig server

All three commands support interactive menu mode when run without arguments:

Terminal window
# Launch interactive menu
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-load-devices
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices

The menus provide guided workflows with help text and validation at each step.

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings
  • --list - Display all existing device type mappings
  • --add - Create a new device type mapping interactively
  • --edit=TYPE - Modify an existing mapping for specified device type
  • --delete=TYPE - Remove a device type mapping
  • --info - Display command help and usage information
Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --add

You’ll be prompted to provide:

Oxidized device type: The device type from your Oxidized configuration (e.g., ios, asa, nxos)

rConfig device type: The internal device type name (e.g., cisco_ios)

rConfig template: The device template ID to use for this device type

Vendor: The vendor ID associated with this device type

Category: The category ID for organizing devices

Tags: Multi-select tags for device classification (use Space to select, Enter to confirm)

Prompts: Device enable and main prompts (use {device_name} as placeholder)

The command uses an interactive multi-select menu for tags:

  • Press Space to select/deselect tags
  • Press Enter to confirm selection
  • If no tags are selected, the first available tag is automatically assigned
  • Tags are stored by ID in the mapping
Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --list

Output displays all configured mappings:

=== IOS ===
rConfig Type: cisco_ios
Template ID: 1
Vendor ID: 1
Category ID: 2
Prompts:
- device_enable_prompt: {device_name}>
- device_main_prompt: {device_name}#
Tags: 5, 8
Terminal window
# Edit existing mapping
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --edit=ios
# Delete mapping
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --delete=ios

CAUTION: Accurate mappings are critical for successful imports. Verify template, vendor, and category IDs exist in rConfig before creating mappings.

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-load-devices /path/to/oxidized/router.db

The command automatically checks for required mappings and credentials:

  • If no mappings file exists, you’ll be prompted to create mappings first
  • If no credential sets exist in rConfig, the import will halt with instructions to create one

Important: If your Oxidized file contains devices without embedded credentials, you’ll be prompted to select a default credential set:

Select a default credential to use for all devices that don't have specific credentials in the Oxidized file:
Which credential would you like to use as default?
ID #1: Production SSH Credentials (Main production credentials)
ID #2: Lab Credentials (Testing environment)

This credential set will be applied to all devices that don’t have username/password in the Oxidized file.

The Oxidized hosts file uses the following format:

hostname:device_type[:username:password[:enable_password]]

Examples:

# Basic format (uses default credential set)
router1.example.com:ios
switch2.example.com:nxos
# With embedded credentials (no credential set needed)
router3.example.com:ios:admin:SecurePass123
firewall1.example.com:asa:admin:SecurePass123:EnablePass456
# Mixed configurations
core-sw-01.example.com:nxos:netadmin:Password1
edge-rtr-05.example.com:ios

During loading, each device is validated for:

  1. DNS resolution: Hostname must resolve to a valid IP address
  2. SSH connectivity: Device must be reachable on port 22
  3. Device type mapping: The device type must have a configured mapping

Devices that fail validation are logged to the failures file.

  1. File validation: Verifies hosts file exists and is readable
  2. Prerequisite checks: Confirms mappings file and credential sets exist
  3. Device parsing: Extracts hostname, device type, and optional credentials
  4. DNS resolution: Resolves each hostname to IP address
  5. SSH connectivity test: Verifies port 22 is accessible
  6. Mapping application: Applies device type mappings to each device
  7. Credential handling: Assigns embedded credentials or prompts for default credential set
  8. JSON generation: Creates timestamped rconfig_import_YYYY-MM-DD_HH-mm-ss.json
  9. Error logging: Records validation failures to timestamped failures file

The command creates timestamped files:

Success file: storage/app/rconfig/tempdir/rconfig_import_2025-01-25_14-30-45.json

Failures file: storage/app/rconfig/tempdir/oxidized_import_failures_2025-01-25_14-30-45.txt

Example JSON output:

[
{
"device_name": "router1.example.com",
"device_ip": "192.168.1.1",
"device_model": "cisco_ios",
"template_id": 1,
"vendor_id": 1,
"device_category_id": 2,
"prompts": {
"device_enable_prompt": "router1.example.com>",
"device_main_prompt": "router1.example.com#"
},
"tags": [5, 8],
"device_cred_id": 1,
"connection_type": "ssh",
"port": 22
},
{
"device_name": "router2.example.com",
"device_ip": "192.168.1.2",
"device_model": "cisco_ios",
"template_id": 1,
"vendor_id": 1,
"device_category_id": 2,
"prompts": {
"device_enable_prompt": "router2.example.com>",
"device_main_prompt": "router2.example.com#"
},
"tags": [5, 8],
"device_cred_id": 0,
"device_username": "admin",
"device_password": "SecurePass123",
"device_enable_password": null,
"connection_type": "ssh",
"port": 22
}
]
  • device_cred_id = 0: Device uses embedded credentials (username/password in JSON)
  • device_cred_id > 0: Device uses the specified credential set ID from rConfig

NOTE: The {device_name} placeholder in prompts is automatically replaced with the actual device hostname during the loading process.

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices /path/to/rconfig_import.json

When run without a file path, the command offers several options:

What would you like to do?
Show information about this command
Import devices from a JSON file
Import from the latest available JSON file
Select from all available import files
Exit

Latest file mode: Automatically finds and uses the most recent JSON file in the temp directory

Select file mode: Displays all available import files with:

  • Filename
  • Modification date/time
  • File size
  • Device count
  • --group=ID - Assign all imported devices to specified device group (default: 1)
  • --dry-run - Preview import without modifying database
  • --info - Display command help and usage information

NOTE: The --skip-existing option mentioned in the documentation is not implemented in the current code. Duplicate devices are automatically skipped during import.

  1. JSON validation: Verifies file structure and required fields
  2. Device validation: Checks each device for:
    • Required fields (device_name, device_ip, device_model, template_id, vendor_id, device_category_id, prompts)
    • Valid template, vendor, and category IDs in database
    • Valid credential set ID (if using credential sets)
    • Valid IP address format
    • Device username/password (if device_cred_id = 0)
    • Duplicate detection by hostname or IP
  3. Transaction-based import: All valid devices imported in a single database transaction
  4. Device creation: Creates device records with mapped configurations
  5. Relationship linking: Associates tags, vendors, categories, templates, and default role (role ID 1)
  6. Duplicate handling: Automatically skips devices that already exist
  7. Summary report: Displays import statistics

For each imported device, the following relationships are established:

  • Tags: Many-to-many relationship with selected tags
  • Vendor: Many-to-many relationship (single vendor)
  • Category: Many-to-many relationship (single category)
  • Template: Many-to-many relationship (single template)
  • Role: Default role ID 1 is assigned to all devices

Each device must pass these validation checks:

Required fields:

  • device_name
  • device_ip (must be valid IP format)
  • device_model
  • template_id (must exist in database)
  • vendor_id (must exist in database)
  • device_category_id (must exist in database)
  • prompts (must contain device_enable_prompt and device_main_prompt)

Credential validation:

  • If device_cred_id = 0: device_username and device_password are required
  • If device_cred_id > 0: credential set must exist in database

Duplicate detection:

  • No existing device with same device_name
  • No existing device with same device_ip

Test the import without making changes:

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices \
--dry-run \
/path/to/rconfig_import.json

Output shows validation results and which devices would be imported:

Running in dry-run mode - no database changes will be made
Validating devices ████████████████████ 100%
45 devices failed validation:
Device: router1.example.com
- Template ID 99 not found
Continue with 155 valid devices? (yes/no)
Dry run completed. 155 devices would be imported.

Execute the actual import:

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices \
--group=5 \
/path/to/rconfig_import.json

Import results:

Found 200 devices in the import file
Validating devices ████████████████████ 100%
Importing devices ████████████████████ 100%
Import completed successfully!
Imported: 195 devices
Skipped: 5 devices (already exist)

NOTE: All imports use database transactions. If any error occurs during import, all changes are rolled back automatically.

Terminal window
# Step 1: Create device type mappings (interactive mode)
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --add
# Verify mappings
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --list
# Step 2: Load devices from Oxidized hosts file
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-load-devices \
/opt/oxidized/router.db
# Review the generated JSON and failures log
cat storage/app/rconfig/tempdir/rconfig_import_2025-01-25_14-30-45.json
cat storage/app/rconfig/tempdir/oxidized_import_failures_2025-01-25_14-30-45.txt
# Step 3: Preview import (dry run)
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices \
--dry-run \
storage/app/rconfig/tempdir/rconfig_import_2025-01-25_14-30-45.json
# Step 4: Execute production import
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices \
--group=1 \
storage/app/rconfig/tempdir/rconfig_import_2025-01-25_14-30-45.json
# Or use the latest file automatically
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices
# Select: "Import from the latest available JSON file"

Symptoms:

  • Error during device loading: “No device credentials found in the system”
  • Import halts before processing devices

Resolution:

Create at least one credential set in rConfig:

  • Navigate to Settings > Credentials
  • Create a new credential set with valid SSH credentials
  • Re-run the load devices command

Symptoms:

  • Error during device loading: “No mapping found for device type ‘xyz’”
  • Devices logged to failures file with “Unknown device type” message

Resolution:

Create missing mapping:

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --add

List existing mappings to verify:

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --list

Symptoms:

  • Import fails with “Template ID X does not exist”
  • Validation shows “Vendor ID X not found”
  • Database constraint violation errors

Resolution:

Verify IDs exist in rConfig:

  • Navigate to Settings > Templates (or Vendors/Categories)
  • Note the correct ID numbers
  • Update mapping with correct IDs:
Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-device-mappings --edit=ios

Symptoms:

  • Devices logged to failures file with “Failed to resolve hostname”
  • Zero devices in generated JSON despite valid hosts file

Resolution:

Verify DNS is working on the rConfig server:

Terminal window
# Test DNS resolution
nslookup router1.example.com
# Or use host command
host router1.example.com

Options to resolve:

  • Add entries to /etc/hosts for devices
  • Configure proper DNS servers in /etc/resolv.conf
  • Use IP addresses instead of hostnames in Oxidized file

Symptoms:

  • Devices logged to failures file with “Failed to connect to SSH (port 22)”
  • Partial import with many failures

Resolution:

Check network connectivity:

Terminal window
# Test SSH port connectivity
nc -zv 192.168.1.1 22
# Or use telnet
telnet 192.168.1.1 22

Common causes:

  • Firewall blocking port 22 from rConfig server
  • Devices not actually reachable from rConfig server network
  • SSH disabled on devices

Symptoms:

  • Device loading fails with “Invalid hosts file format”
  • Some devices missing from JSON output

Resolution:

Verify hosts file format:

Terminal window
# Check for blank lines or malformed entries
cat /opt/oxidized/router.db | grep -v '^#' | grep -v '^$'
# Valid format examples:
# hostname:device_type
# hostname:device_type:username:password
# hostname:device_type:username:password:enable_password

Remove or fix any lines that don’t match the expected format.

Symptoms:

  • Validation shows “Device with same name or IP already exists”
  • Import skips devices that should be imported

Resolution:

Duplicates are automatically skipped during import. To handle duplicates:

Check existing devices:

  • Navigate to Devices in rConfig
  • Search for the device name or IP
  • Delete the existing device if needed

Review validation output: The validation shows which device ID already exists

Manual cleanup: Remove duplicates from JSON file before import if needed

Symptoms:

  • Devices imported with literal {device_name} in prompts
  • Connection issues due to incorrect prompt detection

Resolution:

This indicates the device name replacement failed. Check:

  • Mapping file has {device_name} placeholder correctly
  • Device loading command completed successfully
  • Regenerate JSON with correct mapping:
Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-load-devices \
/opt/oxidized/router.db

Symptoms:

  • Import command fails with “Invalid JSON structure”
  • Parse errors when reading import file

Resolution:

Validate JSON syntax:

Terminal window
# Check JSON is valid
python -m json.tool /path/to/rconfig_import.json
# Or use jq
jq . /path/to/rconfig_import.json

If errors found, regenerate JSON:

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-load-devices \
/opt/oxidized/router.db

Symptoms:

  • Import fails with “Import failed: [error message]”
  • Zero devices imported despite validation passing
  • Database unchanged

Resolution:

All imports use transactions for safety. If any error occurs, all changes roll back. Check:

Application logs:

Terminal window
tail -f storage/logs/laravel.log

Database constraints: Ensure all foreign key relationships are valid

Re-run with dry-run: Identify which device is causing the failure

Terminal window
php /var/www/html/rconfig8/current/artisan rconfig:oxidized-import-devices \
--dry-run \
/path/to/file.json

Use interactive menus for first-time users: The guided menus provide helpful context and validation

Create mappings first: Configure all device type mappings before loading the hosts file to avoid import failures

Pre-create credential sets: Set up connection profiles and credential sets in rConfig before importing devices

Test DNS and connectivity: Verify devices are reachable from the rConfig server before starting import

Review failures log: After loading devices, check the failures file to identify and fix issues

Use dry-run mode: Always use --dry-run first to preview changes and catch errors before production import

Backup regularly: Keep copies of your JSON import files for audit trails and potential rollbacks

Import in batches: For large deployments (500+ devices), consider splitting hosts file into smaller batches for easier troubleshooting

Verify mappings: Double-check that template, vendor, and category IDs are correct—typos cause import failures

Check timestamped files: The tool creates timestamped files, so you can track multiple import attempts

Use latest file feature: When re-importing after fixes, use the “latest file” option to avoid typing paths

Review validation output: Pay attention to validation messages—they indicate exactly what needs to be fixed

Monitor database transactions: Large imports are atomic—they either fully succeed or fully roll back

After successful import:

  1. Verify device inventory: Navigate to Devices and confirm all devices imported correctly
  2. Review credentials: Check that devices have appropriate credential assignments
  3. Test connectivity: Use device debug command to verify connection to sample devices
  4. Check relationships: Verify tags, vendors, categories, and templates are correctly assigned
  5. Review skipped devices: Investigate why devices were skipped (usually duplicates)
  6. Clean up temp files: Optionally archive or remove old import JSON files and failure logs
  7. Organize devices: Create device groups and apply bulk settings as needed
  8. Configure schedules: Set up automated backup schedules for device groups
  9. Enable compliance: Apply compliance policies to imported devices