Juniper XML/RPC Learnings - Platform Detection¶
Key Discovery¶
While implementing the uri
and unique_identifier
methods to fix the UUID warning (issue #3), we discovered that Juniper's official Ruby library (ruby-junos-ez-stdlib
) exclusively uses XML/RPC for all device interactions.
Research Findings¶
1. Juniper's Official Approach¶
From analyzing ruby-junos-ez-stdlib
:
# Chassis information (including serial number)
inv_info = ndev.rpc.get_chassis_inventory
facts[:serialnumber] = chassis.xpath('serial-number').text
# Version information
swver = ndev.rpc.command "show version"
facts[:version] = swver.xpath('//junos-version').text
Key insight: Juniper NEVER uses regex parsing of text output in their official library.
2. CLI to XML/RPC Mapping¶
CLI Command | XML RPC | Output via SSH |
---|---|---|
show chassis hardware |
<get-chassis-inventory> |
Add \| display xml |
show version |
<get-software-information> |
Add \| display xml |
show system information |
<get-system-information> |
Add \| display xml |
Important: show chassis hardware | display xml
produces identical output to the RPC call.
3. Current Implementation vs Best Practice¶
Aspect | Current (Text + Regex) | Juniper Official (XML) |
---|---|---|
Reliability | Brittle - format changes break regex | Stable - structured data |
Maintenance | Complex regex patterns | Simple XPath queries |
Compatibility | Works on all versions | Works on all modern JunOS |
Performance | Slightly faster | Slightly slower (XML parsing) |
Future-proof | No - CLI output can change | Yes - XML schema is stable |
4. Protocol Differences¶
- Juniper stdlib: Uses NETCONF protocol (native XML)
- Train-juniper: Uses SSH protocol (text by default)
- Bridge: SSH can get same XML with
| display xml
Decision: Adopt XML Approach¶
We will update our platform detection to use XML output, following Juniper's official patterns. This ensures:
- Stability: XML schema rarely changes
- Compatibility: Matches official Juniper automation
- Maintainability: No complex regex patterns
- Reliability: Structured data parsing
Implementation Pattern¶
# New pattern following Juniper's approach
def detect_junos_serial
detect_attribute('junos_serial', 'show chassis hardware | display xml') { |output|
extract_serial_from_xml(output)
}
end
def extract_serial_from_xml(output)
require 'rexml/document'
doc = REXML::Document.new(output)
# Use same XPath as Juniper's official library
serial_element = doc.elements['//chassis/serial-number']
serial_element&.text&.strip
rescue StandardError => e
logger&.debug("XML parsing failed: #{e.message}")
nil
end
Affected Components¶
Platform Module (lib/train-juniper/platform.rb
)¶
detect_junos_version
- Should use XMLdetect_junos_architecture
- Should use XMLdetect_junos_serial
- Must use XML (current work)
Mock Responses (lib/train-juniper/helpers/mock_responses.rb
)¶
- All mock responses need XML versions
- Keep text versions for backward compatibility
Tests¶
- Platform tests need XML fixtures
- Connection tests need XML responses
- Mock infrastructure needs updating
Benefits of This Approach¶
- Following Industry Standards: Aligning with Juniper's official automation approach
- Better Error Handling: XML parsing errors are clearer than regex mismatches
- Easier Debugging: Can validate XML structure independently
- Future Features: Easy to extract additional fields from XML
- Cross-Platform: Same code works via NETCONF or SSH
Risks and Mitigation¶
Risk | Mitigation |
---|---|
Older JunOS without XML support | Implement text fallback |
XML parsing overhead | Minimal impact, benefits outweigh |
Breaking existing code | Gradual migration, keep text methods |
Test suite updates | Update incrementally |