Adding Devices
EnterpriseAdd devices to the NetStacks Controller manually, via CSV or JSON import, or through NetBox sync for centralized inventory management.
Overview
The device inventory described here is part of the NetStacks Controller (Enterprise). Before you can capture configurations, run automation, or poll a device over SNMP, the device must exist in the Controller inventory.
Device management is the foundation of the NetStacks Controller. The inventory stores each device's connection details — hostname or IP address, SSH port, protocol, platform type, and an optional credential association — so the rest of the platform can operate without repeated manual input.
The Controller supports three methods for adding devices:
- Manual entry — Add a single device through the Admin UI with full control over every field.
- Bulk import — Bulk-add devices from a CSV file or a JSON array exported from spreadsheets, CMDBs, or other systems.
- NetBox sync — Pull device inventory from one or more NetBox instances automatically, with filter-based device selection.
A separate SecureCRT import path exists in the standalone Terminal app for migrating saved sessions — see Connecting to Devices. It is described under the Step-by-Step section below and is not part of the Controller inventory API.
A single, accurate device inventory eliminates the spreadsheet sprawl that plagues most network teams. Every credential lookup, config snapshot, and automation job references the same device record, so changes propagate everywhere automatically.
How It Works
When you add a device, the Controller creates a record in PostgreSQL that stores the device's connection parameters and metadata. Each record includes fields for name, host, port, protocol, device type, manufacturer, model, platform, site, serial number, asset tag, tags, and custom metadata.
Device Record Structure
The core device model tracks both connection details and organizational metadata:
- Connection fields —
host(IP or hostname),port(default 22),protocol(defaults tossh), anddevice_type(the platform driver string likecisco_ios). - Credential association —
default_credential_idlinks to a credential in the vault, andsnmp_credential_idlinks to SNMP credentials for polling. - Source tracking — The
sourcefield records how the device was added (manual,csv,json,netbox), andnetbox_idstores the original NetBox device ID for synced devices. - Organizational metadata —
site,manufacturer,model,serial_number,asset_tag, andtagsfor filtering and grouping. - Polling —
poll_enabled(default off) andpoll_interval_minutes(default 15) control SNMP polling for the device.
Hardware Resources & SNMP Monitoring
Devices with an SNMP credential assigned can surface hardware resource data such as CPU utilization, memory usage, and interface status with traffic rates. See SNMP Communities for configuring SNMP credentials and Network Discovery for populating interface and neighbor data.
Credential Association
Devices are linked to credentials through the credential vault. When the Controller connects to a device for config collection or automation, it retrieves the credential from the vault, decrypts it using the master key, and uses it to authenticate. Credentials are never stored in the device record itself — only a UUID reference is kept.
Connect Commands
Each device can optionally store connect_commands — a list of CLI commands run automatically after connecting. This is useful for devices requiring an initial enable or system-view command.
Step-by-Step Guide
Manual Device Entry
- Navigate to Devices in the Admin UI sidebar.
- Click Add Device.
- Enter the Name — use a descriptive hostname that includes the device function and location (e.g.,
core-rtr-01.dc-east). - Enter the Host — the management IP address or resolvable hostname (e.g.,
10.1.0.1). - Select the Device Type (e.g.,
cisco_ios,juniper_junos,arista_eos). - Set the Port if different from the default (22).
- Assign a Credential from the vault, or leave blank to assign later.
- Optionally fill in manufacturer, model, site, serial number, asset tag, and tags for organizational tracking.
- Click Save.
Use a consistent naming scheme across your fleet. A common pattern is function-location-number — for example core-rtr-01, dist-sw-03, fw-edge-02. This makes filtering and bulk operations much easier. Device names must be unique within your organization.
CSV Bulk Import
- Prepare a CSV file with the required columns:
name,host,device_type. Optional columns areport,manufacturer,model,platform,site, anddescription. - Navigate to Devices and choose the CSV import option, or post the file to the import API (see Code Examples).
- Upload your CSV file or paste the CSV content directly.
- The Controller validates each row and reports how many devices were imported, how many failed, and the specific error for each failed row (including the row number).
CSV and JSON imports map a fixed set of columns: name, host, port, device_type, manufacturer, model, platform, site, and description. The protocol defaults to ssh. Credentials, tags, serial number, and asset tag are not set by import — assign those afterward via the Admin UI or the device API.
SecureCRT Session Import (Terminal app)
The standalone Terminal app can import saved sessions from a SecureCRT XML session export. This is a Terminal feature for populating the connect dialog — it is separate from the Controller inventory API.
- In SecureCRT, export your sessions to XML (VanDyke session export format).
- In the Terminal app, import the exported XML file.
- The parser reads each session's name, host, port, and protocol (
sshortelnet) and preserves the folder structure. - Assign credentials from the NetStacks vault after import — credentials are not read from the SecureCRT file.
Only SecureCRT XML session exports are supported. INI exports are not parsed. SecureCRT files do not carry a NetStacks device_type, so set the platform after import where needed.
Code Examples
All device endpoints are mounted under /api/devices and require an authenticated admin token. Replace localhost:3000 with your Controller host.
CSV Import Template
A CSV file for importing a typical multi-vendor data center:
name,host,device_type,port,manufacturer,model,platform,site,description
core-rtr-01,10.1.0.1,cisco_ios,22,Cisco,ISR 4451,ios,dc-east,Core router - East DC
core-rtr-02,10.1.0.2,cisco_ios,22,Cisco,ISR 4451,ios,dc-east,Core router - East DC redundant
dist-sw-01,10.1.1.1,cisco_nxos,22,Cisco,Nexus 9300,nxos,dc-east,Distribution switch - Row A
dist-sw-02,10.1.1.2,cisco_nxos,22,Cisco,Nexus 9300,nxos,dc-east,Distribution switch - Row B
leaf-sw-01,10.1.2.1,arista_eos,22,Arista,7050X3,eos,dc-east,Leaf switch - Rack 01
leaf-sw-02,10.1.2.2,arista_eos,22,Arista,7050X3,eos,dc-east,Leaf switch - Rack 02
wan-rtr-01,10.2.0.1,juniper_junos,22,Juniper,MX204,junos,dc-west,WAN router - West DC
mgmt-sw-01,10.1.3.1,hp_procurve,22,HPE,Aruba 2930F,procurve,dc-east,Management switchAdd a Device via REST API
Create a device with POST /api/devices:
curl -X POST http://localhost:3000/api/devices \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"name": "core-rtr-03",
"host": "10.3.0.1",
"port": 22,
"device_type": "cisco_ios",
"manufacturer": "Cisco",
"model": "Catalyst 8300",
"site": "dc-west",
"description": "Core router - West DC",
"tags": ["core", "production", "west"],
"default_credential_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}'Import Devices from CSV via API
curl -X POST http://localhost:3000/api/devices/import/csv \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: text/csv" \
--data-binary @devices.csvImport Devices from JSON via API
POST /api/devices/import/json accepts a JSON array of rows using the same fields as the CSV importer:
curl -X POST http://localhost:3000/api/devices/import/json \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '[
{
"name": "spine-sw-01",
"host": "10.4.0.1",
"device_type": "arista_eos",
"manufacturer": "Arista",
"model": "7280R3",
"platform": "eos",
"site": "dc-north"
},
{
"name": "spine-sw-02",
"host": "10.4.0.2",
"device_type": "arista_eos",
"manufacturer": "Arista",
"model": "7280R3",
"platform": "eos",
"site": "dc-north"
}
]'Sync from NetBox via API
Trigger a NetBox sync with POST /api/devices/sync/netbox. See NetBox Integration for full details on sources, filters, and field mapping.
curl -X POST http://localhost:3000/api/devices/sync/netbox \
-H "Authorization: Bearer ${TOKEN}" \
-H "Content-Type: application/json" \
-d '{
"netbox_url": "https://netbox.example.com",
"token": "${NETBOX_TOKEN}",
"filters": {
"status": "active",
"site": "dc-east",
"has_primary_ip": true
}
}'Test a Device Credential via API
POST /api/devices/{device_id}/test-credential attempts an SSH connection and returns a success flag and a message:
curl -X POST http://localhost:3000/api/devices/${DEVICE_ID}/test-credential \
-H "Authorization: Bearer ${TOKEN}"
# Example response:
# { "success": true, "message": "SSH connection successful" }Device Fields Reference
| Field | Required | Default | Description |
|---|---|---|---|
name | Yes | — | Unique device identifier within the organization |
host | Yes | — | Management IP address or resolvable hostname |
device_type | Yes | — | Platform driver string (e.g., cisco_ios, juniper_junos) |
port | No | 22 | SSH port number |
protocol | No | ssh | Connection protocol |
manufacturer | No | — | Device vendor (Cisco, Juniper, Arista, etc.) |
model | No | — | Hardware model (ISR 4451, Nexus 9300, MX204, etc.) |
platform | No | — | Platform string (ios, nxos, junos, eos, etc.) |
site | No | — | Physical site or location identifier |
serial_number | No | — | Hardware serial number (API/manual only) |
asset_tag | No | — | Organization asset tracking tag (API/manual only) |
tags | No | [] | Array of string tags (API/manual only) |
default_credential_id | No | — | UUID of the credential in the vault |
snmp_credential_id | No | — | UUID of the SNMP credential used for polling |
poll_enabled | No | false | Enable scheduled SNMP polling |
poll_interval_minutes | No | 15 | SNMP poll interval in minutes |
description | No | — | Free-text description of the device |
Questions & Answers
- Q: How do I add a device to NetStacks?
- A: In the Controller Admin UI, navigate to Devices and click Add Device. Enter the device name, management IP or hostname, select the device type (e.g.,
cisco_ios), and optionally assign a credential from the vault. Click Save. You can also add devices in bulk via CSV import, JSON import, or NetBox sync. - Q: What fields are required when adding a device?
- A: Three fields are required:
name(a unique identifier),host(management IP address or hostname), anddevice_type(the platform driver string such ascisco_ios,juniper_junos, orarista_eos). The port defaults to 22 and the protocol defaults tossh. - Q: How do I import devices from a CSV file?
- A: Create a CSV file with at least
name,host, anddevice_typecolumns, then import it through the Admin UI or post it toPOST /api/devices/import/csvwith aContent-Type: text/csvheader. The response reports how many rows were imported, how many failed, and the error for each failed row (including the row number). A JSON-array equivalent is available atPOST /api/devices/import/json. - Q: Can I import sessions from SecureCRT?
- A: Yes, but it is a feature of the standalone Terminal app, not the Controller inventory. The Terminal imports a SecureCRT XML session export (VanDyke format), reading each session's name, host, port, and protocol while preserving the folder tree. INI exports are not supported, and credentials are not read from the file — assign credentials from the NetStacks vault afterward.
- Q: What is the base path for the device API?
- A: All device endpoints are mounted under
/api/devices— for examplePOST /api/devicesto create a device,/api/devices/import/csvand/import/jsonfor bulk import, and/api/devices/sync/netboxfor NetBox sync. They require an authenticated admin token. - Q: How are credentials associated with devices?
- A: Each device has an optional
default_credential_idfield that links to a credential stored in the encrypted vault. When the Controller connects for config collection or automation, it retrieves and decrypts the credential on the fly. Credentials are never stored in the device record — only a UUID reference. - Q: How do I test connectivity after adding a device?
- A: Use Test Connection in the device view, or call
POST /api/devices/{device_id}/test-credential. The Controller attempts an SSH connection with the assigned credential and returns asuccessflag and a message (for exampleSSH connection successful). The test reports authentication success or failure only; it does not perform device-type detection. A bulk variant is available at/api/devices/bulk/test-credentials. - Q: Is there a maximum number of devices supported?
- A: There is no hard limit on the number of devices in the inventory. The Controller is designed for environments managing hundreds to thousands of devices. Performance depends on your PostgreSQL instance and available memory; large fleets should use paginated API queries.
Troubleshooting
Device won't connect after adding
If the device appears in the inventory but connection tests fail, check these common causes:
- Wrong credentials — Verify the assigned credential has the correct username and password or SSH key. Test manually with
ssh [email protected]from the Controller host. - Incorrect IP or hostname — Verify the host field points to the management interface, not a data-plane address.
- Firewall blocking SSH — Confirm the Controller can reach the device on the configured port. Run
nc -zv 10.1.0.1 22from the Controller host. - Wrong port — Some devices use non-standard SSH ports (e.g., 2222). Update the port field accordingly.
CSV import fails with column errors
The CSV parser requires exact, lowercase column names: name, host, device_type, port, manufacturer, model, platform, site, description. The three required columns (name, host, device_type) must be present. Rows that fail to parse or create are reported individually with the offending row number while valid rows still import.
Duplicate device name error
Device names must be unique within your organization. If an import reports a duplicate-name error (Device with this name already exists), rename the conflicting device in the source file or update the existing record first. The error includes the row number and device name.
SecureCRT import does not detect device types
SecureCRT XML exports do not contain a NetStacks platform type. After importing in the Terminal app, set the correct device type (e.g., cisco_ios, juniper_junos) for full platform-specific functionality. INI exports are not supported — export as XML.
Related Features
These features extend device management with platform awareness, integrations, and fleet-wide operations:
- Device Types — Supported platforms, auto-detection, and platform driver details
- NetBox Integration — Sync device inventory from NetBox instances automatically
- Credential Vault — Encrypted credential storage and device credential association
- Bulk Operations — Perform actions across multiple devices at once
- Config Snapshots — Capture and store device configurations for backup and comparison
- Connecting to Devices — SecureCRT session import and connecting from the Terminal app