Junos 'EZ' automation library for remotely managing and automating Juniper Networks Junos devices through NETCONF protocol
—
Device facts gathering system providing comprehensive device information including hardware details, software versions, chassis information, routing engine details, and network interface data automatically collected during device connection.
Access to comprehensive device facts through the facts property, providing structured information about device hardware, software, and operational status.
@property
def facts(self) -> dict:
"""
Device facts dictionary containing comprehensive device information.
Standard facts keys:
- hostname: Device hostname
- model: Device model/platform
- serialnumber: Chassis serial number
- version: Software version string
- personality: Device personality (MX, EX, SRX, etc.)
- switch_style: Switch style (BRIDGE_DOMAIN, VLAN, etc.)
- master: Master routing engine status
- vc_capable: Virtual chassis capable
- vc_mode: Virtual chassis mode
- vc_fabric: Virtual chassis fabric status
- 2RE: Dual routing engine status
- domain: Configuration domain
- re_info: Routing engine information
- ifd_style: Interface style
- current_re: Current routing engine info
- fpc: Flexible PIC Concentrator information
- srx_cluster: SRX cluster status (SRX devices only)
- srx_cluster_id: SRX cluster ID (SRX devices only)
- srx_cluster_redundancy_group: SRX cluster redundancy group
Returns:
- dict: Device facts dictionary
"""Methods for refreshing device facts, useful when device state may have changed or when custom fact gathering is required.
def facts_refresh(self, **kwargs):
"""
Refresh device facts by re-gathering information from device.
Parameters:
- **kwargs: Optional fact gathering parameters
- keys (list): Specific fact keys to refresh
- timeout (int): Timeout for fact gathering operations
Updates the device facts dictionary with current information.
Raises:
- RpcError: Fact gathering RPC failed
- RpcTimeoutError: Fact gathering timed out
"""Direct access to commonly used device facts through individual properties for convenience and backward compatibility.
@property
def hostname(self) -> str:
"""Device hostname from system configuration or facts"""
@property
def uptime(self) -> int:
"""Device uptime in seconds"""
@property
def master(self) -> bool:
"""True if connected to master routing engine"""
@property
def re_name(self) -> str:
"""Current routing engine name (re0, re1, etc.)"""Structured access to software version information with parsing and comparison capabilities.
class version_info:
"""
Software version information parsing and representation.
Provides structured access to Junos software version components
including major/minor versions, build information, and type.
"""
def __init__(self, verstr):
"""
Parse version string into structured components.
Parameters:
- verstr (str): Version string to parse (e.g., "21.4R3.15")
"""
@property
def major(self) -> tuple:
"""Major version components (year, quarter)"""
@property
def minor(self) -> int:
"""Minor version number"""
@property
def type(self) -> str:
"""Version type (R, I, F, etc.)"""
@property
def build(self) -> int:
"""Build number"""
def __str__(self) -> str:
"""String representation of version"""
def __repr__(self) -> str:
"""Developer representation of version"""Access to legacy facts system for backward compatibility, though new code should use the standard facts dictionary.
@property
def ofacts(self) -> dict:
"""
Legacy operational facts dictionary (deprecated).
Provided for backward compatibility. New code should use
the 'facts' property instead.
Returns:
- dict: Legacy facts dictionary
"""from jnpr.junos import Device
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Access individual facts
print(f"Hostname: {dev.facts['hostname']}")
print(f"Model: {dev.facts['model']}")
print(f"Serial Number: {dev.facts['serialnumber']}")
print(f"Software Version: {dev.facts['version']}")
print(f"Device Personality: {dev.facts['personality']}")
# Check device capabilities
print(f"Virtual Chassis Capable: {dev.facts['vc_capable']}")
print(f"Dual RE: {dev.facts['2RE']}")
print(f"Master RE: {dev.facts['master']}")
dev.close()from jnpr.junos import Device
import json
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Display all facts in formatted JSON
print("Device Facts:")
print(json.dumps(dev.facts, indent=2, default=str))
dev.close()from jnpr.junos import Device
from jnpr.junos.facts.swver import version_info
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Parse version information
version = version_info(dev.facts['version'])
print(f"Full Version: {version}")
print(f"Major Version: {version.major}")
print(f"Minor Version: {version.minor}")
print(f"Version Type: {version.type}")
print(f"Build Number: {version.build}")
# Version comparison example
if version.major >= (21, 4):
print("Running Junos 21.4 or later")
dev.close()from jnpr.junos import Device
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Initial facts
print(f"Initial uptime: {dev.uptime} seconds")
# Wait some time or after configuration changes...
import time
time.sleep(60)
# Refresh facts to get updated information
dev.facts_refresh()
print(f"Updated uptime: {dev.uptime} seconds")
dev.close()from jnpr.junos import Device
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Check routing engine details
if dev.facts['2RE']:
print("Dual routing engine system")
print(f"Current RE: {dev.re_name}")
print(f"Master status: {dev.master}")
# Access detailed RE information
if 're_info' in dev.facts:
for re_name, re_info in dev.facts['re_info'].items():
print(f"RE {re_name}:")
print(f" Status: {re_info.get('status', 'unknown')}")
print(f" Model: {re_info.get('model', 'unknown')}")
print(f" Uptime: {re_info.get('up_time', 'unknown')}")
else:
print("Single routing engine system")
print(f"RE Name: {dev.re_name}")
dev.close()from jnpr.junos import Device
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Check device type and capabilities
device_type = dev.facts['personality']
print(f"Device Type: {device_type}")
if device_type == 'SRX_BRANCH':
print("SRX Series branch device")
if 'srx_cluster' in dev.facts:
print(f"Cluster Status: {dev.facts['srx_cluster']}")
if dev.facts['srx_cluster']:
print(f"Cluster ID: {dev.facts['srx_cluster_id']}")
print(f"Redundancy Group: {dev.facts['srx_cluster_redundancy_group']}")
elif device_type in ['MX', 'MX_MASTER', 'MX_BACKUP']:
print("MX Series device")
print(f"Switch Style: {dev.facts['switch_style']}")
elif device_type in ['EX', 'EX_MASTER', 'EX_BACKUP']:
print("EX Series switch")
if dev.facts['vc_capable']:
print(f"Virtual Chassis Mode: {dev.facts['vc_mode']}")
print(f"VC Fabric: {dev.facts['vc_fabric']}")
dev.close()from jnpr.junos import Device
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
# Refresh only specific facts (implementation dependent)
try:
dev.facts_refresh(keys=['hostname', 'uptime', 'version'])
print("Refreshed key facts successfully")
except Exception as e:
print(f"Facts refresh error: {e}")
dev.close()from jnpr.junos import Device
from jnpr.junos.utils.config import Config
dev = Device(host='router1.example.com', user='admin', passwd='secret')
dev.open()
dev.bind(cu=Config)
# Configure based on device facts
model = dev.facts['model']
hostname = dev.facts['hostname']
if model.startswith('EX'):
# EX switch specific configuration
config = f'''
set system host-name {hostname}-switch
set vlans vlan100 vlan-id 100
set vlans vlan100 description "Data VLAN"
'''
elif model.startswith('SRX'):
# SRX firewall specific configuration
config = f'''
set system host-name {hostname}-firewall
set security zones security-zone trust interfaces ge-0/0/1
set security zones security-zone untrust interfaces ge-0/0/0
'''
else:
# Generic router configuration
config = f'''
set system host-name {hostname}-router
set interfaces lo0 unit 0 family inet address 192.168.255.1/32
'''
print(f"Applying configuration for {model} device")
dev.cu.load(config, format='set')
dev.cu.commit(comment=f'Model-specific configuration for {model}')
dev.close()# Facts dictionary type
FactsDict = dict[str, any] # Device facts with standard and device-specific keys
# Version information type
VersionInfo = object # version_info class instance
# Routing engine information
REInfo = dict[str, dict[str, any]] # RE name to RE details mapping
# FPC information
FPCInfo = dict[str, dict[str, any]] # FPC slot to FPC details mapping
# Standard fact keys (commonly available)
StandardFactKeys = [
'hostname', 'model', 'serialnumber', 'version', 'personality',
'switch_style', 'master', 'vc_capable', 'vc_mode', 'vc_fabric',
'2RE', 'domain', 're_info', 'ifd_style', 'current_re', 'fpc'
]Install with Tessl CLI
npx tessl i tessl/pypi-junos-eznc