Skip to content

Import devices from Oxidized into rConfig V8 Core

The Oxidized Import Tool migrates network devices from Oxidized into rConfig V8 Core using the command line. After reading this page, you can map Oxidized device types to rConfig templates, parse the Oxidized hosts file, validate each device, and bulk import the devices with their vendors, categories, tags, prompts, and credentials.

Use this tool when you are moving an existing Oxidized deployment to rConfig V8 Core and want to onboard devices in bulk rather than adding them by hand. It suits a one-time migration or a phased cut-over where Oxidized and rConfig run in parallel while you validate connectivity. For a handful of devices, adding them through the UI is usually quicker.

Before importing devices, ensure you have:

  • An Oxidized hosts file (router.db or equivalent)
  • Administrator access to rConfig V8 Core
  • Device templates configured in rConfig that match 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

The import runs in three commands, each a distinct stage:

  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.

All three commands support an interactive menu when run without arguments, with guided prompts and validation at each step:

Terminal window
php /var/www/html/rconfig/artisan rconfig:oxidized-device-mappings
php /var/www/html/rconfig/artisan rconfig:oxidized-load-devices
php /var/www/html/rconfig/artisan rconfig:oxidized-import-devices

The import tool uses these file locations, creating directories automatically if they do not exist:

  • 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
  1. Run the mappings command:

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

    Available options:

    • --list - Display all existing device type mappings
    • --add - Create a new device type mapping interactively
    • --edit=TYPE - Modify an existing mapping for the specified device type
    • --delete=TYPE - Remove a device type mapping
    • --info - Display command help and usage information
  2. Add a new mapping:

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

    Provide each value when prompted:

    • Oxidized device type: the device type from your Oxidized configuration (for example ios, asa, nxos)
    • rConfig device type: the internal device type name (for example 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 organising devices
    • Tags: multi-select tags for device classification (Space to select, Enter to confirm)
    • Prompts: device enable and main prompts (use {device_name} as the placeholder)
  3. Select tags in the interactive multi-select menu:

    • Press Space to select or deselect tags
    • Press Enter to confirm the selection
    • If no tags are selected, the first available tag is assigned automatically
    • Tags are stored by ID in the mapping
  4. List existing mappings to verify them:

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

    The 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
  5. Edit or delete a mapping by device type:

    Terminal window
    php /var/www/html/rconfig/artisan rconfig:oxidized-device-mappings --edit=ios
    php /var/www/html/rconfig/artisan rconfig:oxidized-device-mappings --delete=ios
  1. Run the load command against your Oxidized hosts file:

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

    The command checks prerequisites automatically. If no mappings file exists, it prompts you to create mappings first. If no credential sets exist in rConfig, the load halts with instructions to create one.

  2. Select a default credential set when prompted. If your Oxidized file contains devices without embedded credentials, the command asks which credential set to apply to those devices:

    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 is applied to every device that has no username and password in the Oxidized file.

The Oxidized hosts file uses this 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

Each device passes through these stages, and any device that fails is logged to the failures file:

  1. File validation: verifies the hosts file exists and is readable
  2. Prerequisite checks: confirms the mappings file and credential sets exist
  3. Device parsing: extracts hostname, device type, and optional credentials
  4. DNS resolution: resolves each hostname to an 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 the default credential set
  8. JSON generation: creates the timestamped rconfig_import_YYYY-MM-DD_HH-mm-ss.json
  9. Error logging: records validation failures to the timestamped failures file

The command writes two 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
}
]

The device_cred_id value controls credential handling:

  • device_cred_id = 0: the device uses embedded credentials (the username and password in the JSON)
  • device_cred_id > 0: the device uses the specified credential set ID from rConfig
  1. Run the import command against the generated JSON file:

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

    Run without a file path to use the interactive menu:

    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

    The latest file option finds and uses the most recent JSON file in the temp directory. The select file option lists every available import file with its filename, modification date and time, file size, and device count.

    Available options:

    • --group=ID - Assign all imported devices to the specified device group (default: 1)
    • --dry-run - Preview the import without modifying the database
    • --info - Display command help and usage information
  2. Preview the import with a dry run before committing:

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

    The 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.
  3. Run the production import, optionally targeting a device group:

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

    The summary reports imported and skipped counts:

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

Each device must pass these checks, and the whole import runs inside a single database transaction:

  • Required fields: device_name, device_ip (valid IP format), device_model, template_id, vendor_id, device_category_id, and prompts (must contain device_enable_prompt and device_main_prompt)
  • Template, vendor, and category IDs must exist in the database
  • Credentials: if device_cred_id = 0, device_username and device_password are required; if device_cred_id > 0, the credential set must exist
  • Duplicate detection: no existing device with the same device_name or device_ip

For each valid device, rConfig creates the device record and links its tags, vendor, category, template, and the default role (role ID 1).

Terminal window
# Step 1: Create device type mappings (interactive mode)
php /var/www/html/rconfig/artisan rconfig:oxidized-device-mappings --add
# Verify mappings
php /var/www/html/rconfig/artisan rconfig:oxidized-device-mappings --list
# Step 2: Load devices from the Oxidized hosts file
php /var/www/html/rconfig/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/rconfig/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/rconfig/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/rconfig/artisan rconfig:oxidized-import-devices
# Select: "Import from the latest available JSON file"

This is usually DNS resolution. Devices are logged to the failures file with “Failed to resolve hostname” when the rConfig server cannot resolve them.

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

Resolve it by adding entries to /etc/hosts, configuring DNS servers in /etc/resolv.conf, or using IP addresses instead of hostnames in the Oxidized file.

Why do devices fail with SSH connectivity errors?

Section titled “Why do devices fail with SSH connectivity errors?”

Devices logged with “Failed to connect to SSH (port 22)” are not reachable from the rConfig server.

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

Common causes are a firewall blocking port 22 from the rConfig server, devices that are not reachable from the rConfig server network, or SSH disabled on the device.

Device loading fails with “Invalid hosts file format” or some devices are missing from the JSON output. Check for blank lines or malformed entries:

Terminal window
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 line that does not match the expected format.

Why are devices being skipped as duplicates?

Section titled “Why are devices being skipped as duplicates?”

Validation shows “Device with same name or IP already exists”. Duplicates are skipped automatically during import. Search for the device name or IP under Devices in rConfig and delete the existing record if you need to re-import, or remove the duplicate from the JSON file before importing.

Why are prompts showing a literal {device_name}?

Section titled “Why are prompts showing a literal {device_name}?”

If devices import with literal {device_name} in their prompts, the device name replacement failed during loading. Confirm the mapping file uses the {device_name} placeholder correctly, then regenerate the JSON:

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

Why does the import fail with a JSON error?

Section titled “Why does the import fail with a JSON error?”

The import fails with “Invalid JSON structure” when the file is malformed. Validate the syntax, then regenerate if needed:

Terminal window
python -m json.tool /path/to/rconfig_import.json
jq . /path/to/rconfig_import.json

The import fails with “Import failed: [error message]” and zero devices are imported. Because every import is transactional, any error rolls back all changes. Check the application log and re-run with --dry-run to find the offending device:

Terminal window
tail -f storage/logs/laravel.log
php /var/www/html/rconfig/artisan rconfig:oxidized-import-devices \
--dry-run \
/path/to/file.json
  • Create all device type mappings before loading the hosts file, so devices do not fail validation at import time.
  • Pre-create connection profiles and credential sets in rConfig before importing devices.
  • Verify DNS and connectivity from the rConfig server before starting the import.
  • Review the failures log after loading to identify and fix issues early.
  • Always run --dry-run first to preview changes and catch errors before the production import.
  • Keep copies of your JSON import files for audit trails and potential rollbacks.
  • For large deployments (500+ devices), split the hosts file into smaller batches for easier troubleshooting.
  • Use the latest file option when re-importing after fixes, to avoid retyping paths.

After a successful import:

  1. Verify the device inventory: navigate to Devices and confirm all devices imported correctly.
  2. Review credentials: check that devices have the right credential assignments.
  3. Test connectivity: use the device debug command to verify connection to sample devices.
  4. Check relationships: verify tags, vendors, categories, and templates are assigned correctly.
  5. Review skipped devices: investigate why devices were skipped (usually duplicates).
  6. Clean up temp files: archive or remove old import JSON files and failure logs.
  7. Organise devices: create device groups and apply bulk settings as needed.
  8. Configure schedules: set up automated backup schedules for your device groups.