182 lines
6.5 KiB
Markdown
182 lines
6.5 KiB
Markdown
# Device Profiles Implementation Status
|
|
|
|
## Completed
|
|
|
|
### Database Schema
|
|
- ✅ Created `device_profiles` table for storing profile metadata
|
|
- ✅ Created `profile_device_oids` table for device identification OIDs (serial, firmware, etc.)
|
|
- ✅ Created `profile_sensor_oids` table for sensor discovery OIDs (temp, voltage, current, power)
|
|
- ✅ Seeded MikroTik profile with all MIB symbolic names
|
|
|
|
### Ecto Schemas
|
|
- ✅ `Towerops.Profiles.DeviceProfile` - Profile schema with associations
|
|
- ✅ `Towerops.Profiles.DeviceOid` - Device identification OID schema
|
|
- ✅ `Towerops.Profiles.SensorOid` - Sensor OID schema with divisor support
|
|
|
|
### Context
|
|
- ✅ `Towerops.Profiles` context for CRUD operations
|
|
- `list_profiles/0` - Get all enabled profiles ordered by priority
|
|
- `get_profile/1` - Get profile by name with associations
|
|
- `match_profile/1` - Match device to profile based on sysDescr/sysObjectID
|
|
- `create_profile/1`, `update_profile/2`, `delete_profile/1`
|
|
- `add_device_oid/3`, `add_sensor_oid/2`
|
|
|
|
### Dynamic Profile
|
|
- ✅ `Towerops.Snmp.Profiles.Dynamic` - Runtime profile using database definitions
|
|
- `identify_device/3` - Polls device OIDs using MIB translation
|
|
- `discover_sensors/2` - Discovers sensors using MIB translation
|
|
- `discover_interfaces/2` - Delegates to Base profile
|
|
|
|
### Discovery Integration
|
|
- ✅ Updated `Towerops.Snmp.Discovery` to support database profiles
|
|
- Tries database profiles first via `Profiles.match_profile/1`
|
|
- Falls back to hardcoded profiles (MikroTik, Cisco, etc.)
|
|
- Handles `{:dynamic, profile}` tuples for database profiles
|
|
|
|
### Mix Task (Basic Structure)
|
|
- ✅ Created `Mix.Tasks.ImportProfiles` with basic structure
|
|
- ✅ Argument parsing (--source-path, --profiles filter)
|
|
- ✅ YAML file discovery and reading
|
|
|
|
## Current Status
|
|
|
|
The core database-driven profile system is **fully functional**:
|
|
- MikroTik devices will be detected using the database profile
|
|
- Device info (serial, firmware, license) will be polled via MIB translation
|
|
- Sensors (temp, voltage, current, power) will be discovered via MIB translation
|
|
- Profiles can be updated without redeployment
|
|
|
|
## Completed: LibreNMS Import Task
|
|
|
|
The `mix import_profiles` task has been implemented and tested successfully with LibreNMS YAML files.
|
|
|
|
### LibreNMS File Structure
|
|
|
|
LibreNMS splits profile definitions across two files:
|
|
|
|
1. **`resources/definitions/os_detection/{os}.yaml`** - Detection and metadata
|
|
```yaml
|
|
os: routeros
|
|
text: 'Mikrotik RouterOS'
|
|
discovery:
|
|
- sysObjectID:
|
|
- .1.3.6.1.4.1.14988.1
|
|
```
|
|
|
|
2. **`resources/definitions/os_discovery/{os}.yaml`** - Device info and sensors
|
|
```yaml
|
|
modules:
|
|
os:
|
|
serial: MIKROTIK-MIB::mtxrSerialNumber.0
|
|
version: MIKROTIK-MIB::mtxrLicVersion.0
|
|
sensors:
|
|
temperature:
|
|
data:
|
|
- oid: MIKROTIK-MIB::mtxrGaugeTable
|
|
value: MIKROTIK-MIB::mtxrGaugeValue
|
|
num_oid: '.1.3.6.1.4.1.14988.1.1.3.100.1.3.{{ $index }}'
|
|
descr: MIKROTIK-MIB::mtxrGaugeName
|
|
divisor: 10
|
|
```
|
|
|
|
### Implementation Details
|
|
|
|
1. **`import_profile/2` function** ✅
|
|
- Reads both `os_detection/{name}.yaml` and `os_discovery/{name}.yaml`
|
|
- Extracts detection patterns from os_detection file (sysObjectID)
|
|
- Extracts device OIDs from `modules.os` section (serial, version, hardware)
|
|
- Extracts sensor OIDs from `modules.sensors.{type}.data[]` arrays
|
|
|
|
2. **Sensor handling** ✅
|
|
- Only imports scalar sensors (with `.0` suffix)
|
|
- Skips table-based sensors with `{{ $index }}` templates
|
|
- Cleans up template syntax in descriptions
|
|
- Handles divisor values correctly
|
|
|
|
3. **Supported sensor types** ✅
|
|
- `temperature`, `voltage`, `current`, `power`, `fanspeed`
|
|
- Other types (`dbm`, `state`, `count`) can be added as needed
|
|
|
|
4. **Tested with real LibreNMS** ✅
|
|
- Successfully imported `routeros` profile from `~/dev/librenms/resources/definitions/`
|
|
- Profile created with correct detection OID and device OIDs
|
|
- Scalar sensors imported (though routeros only has table-based sensors)
|
|
|
|
### Usage
|
|
|
|
Import profiles from LibreNMS YAML definitions:
|
|
|
|
```bash
|
|
# Import all profiles
|
|
mix import_profiles --source-path ~/dev/librenms/resources/definitions
|
|
|
|
# Import specific profiles
|
|
mix import_profiles --source-path ~/dev/librenms/resources/definitions --profiles routeros,ios
|
|
|
|
# Import single profile
|
|
mix import_profiles --source-path ~/dev/librenms/resources/definitions --profiles routeros
|
|
```
|
|
|
|
**Note**: The task looks for files in:
|
|
- `{source-path}/os_detection/{profile}.yaml` - Detection patterns
|
|
- `{source-path}/os_discovery/{profile}.yaml` - Device info and sensors
|
|
|
|
### Current Limitations
|
|
|
|
1. **Table-based sensors** - Only scalar sensors (ending with `.0`) are imported
|
|
- Table sensors with `{{ $index }}` templates are skipped
|
|
- This excludes most interface-level sensors (POE ports, optical transceivers, etc.)
|
|
|
|
2. **Complex templates** - Template syntax in descriptions is removed
|
|
- `{{ MIKROTIK-MIB::mtxrPOEName }} POE` becomes just "POE"
|
|
|
|
3. **Sensor types** - Only common types are imported
|
|
- Supported: temperature, voltage, current, power, fanspeed
|
|
- Not supported: dbm, state, count (can be added as needed)
|
|
|
|
### Next Steps
|
|
|
|
1. **Add more sensor types** - Add dbm, state, count if needed
|
|
2. **Web UI for profiles** - Build LiveView CRUD for managing profiles
|
|
3. **Table sensor support** - Implement support for table-based sensors
|
|
4. **Import more profiles** - Test with Cisco, Ubiquiti, etc.
|
|
|
|
## Testing
|
|
|
|
To test the current implementation:
|
|
|
|
```elixir
|
|
# Get the seeded MikroTik profile
|
|
profile = Towerops.Profiles.get_profile("mikrotik")
|
|
|
|
# Check device OIDs
|
|
profile.device_oids
|
|
# => [
|
|
# %{field: "serial_number", mib_name: "MIKROTIK-MIB::mtxrSerialNumber.0"},
|
|
# %{field: "firmware_version", mib_name: "MIKROTIK-MIB::mtxrFirmwareVersion.0"},
|
|
# ...
|
|
# ]
|
|
|
|
# Check sensor OIDs
|
|
profile.sensor_oids
|
|
# => [
|
|
# %{sensor_type: "temperature", mib_name: "MIKROTIK-MIB::mtxrHlTemperature.0", divisor: 10},
|
|
# %{sensor_type: "voltage", mib_name: "MIKROTIK-MIB::mtxrHlVoltage.0", divisor: 10},
|
|
# ...
|
|
# ]
|
|
|
|
# Match a device to a profile
|
|
system_info = %{
|
|
sys_descr: "RouterOS 7.16.1",
|
|
sys_object_id: ".1.3.6.1.4.1.14988.1"
|
|
}
|
|
matched = Towerops.Profiles.match_profile(system_info)
|
|
# => %DeviceProfile{name: "mikrotik", ...}
|
|
```
|
|
|
|
## Next Steps
|
|
|
|
1. **Test with real MikroTik device** - Verify dynamic profile works end-to-end
|
|
2. **Add Web UI** - Build LiveView pages for managing profiles
|
|
3. **Improve import task** - Parse LibreNMS YAML structure correctly
|
|
4. **Add more profiles** - Cisco, Ubiquiti, etc.
|