towerops/PROFILES_README.md

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.