I've got a Python (3.10) script using the PyEZ library to connect to Junos devices and commit various display set commands. Although both these steps are successful, when having committed the candidate configuration I get an RpcTimeoutError no matter what timeout value I set for the Device class and inside the commit() method of the Config class. I just don't get why this happens. The commit is done way before the 5 minutes are over and the commit_config() method should therefore return True.
The display set commands I commit:
delete interfaces ge-0/0/0 unit 500
delete class-of-service interfaces ge-0/0/0 unit 500
delete routing-options rib inet6.0 static route <ipv6 route>,
The error:
Error: RpcTimeoutError(host: hostname, cmd: commit-configuration, timeout: 360)
Relevant code is below:
DEVICE_TIMEOUT = 360 # RPC timeout value in seconds
DEVICE_AUTOPROBE = 15
class JunosDeviceConfigurator:
def __init__(self, user=NETCONF_USER, password=NETCONF_PASSWD) -> None:
self.user = user
self.password = password
self.device = None
Device.auto_probe = DEVICE_AUTOPROBE
Device.timeout = DEVICE_TIMEOUT
def connect(self) -> bool:
try:
self.device = Device(
host=self._hostname,
user=self.user,
passwd=self.password,
port=22, huge_tree=True,
gather_facts=True,
timeout=DEVICE_TIMEOUT)
self.device.open()
self.device.timeout = DEVICE_TIMEOUT
self.logger.info(f'Connected to {self._hostname}')
return True
except ConnectRefusedError as err:
self.logger.error(f'Connection refused to {self._hostname}: {str(err)}')
return False
except ConnectError as err:
self.logger.error(f'Connection to {self._hostname} failed: {str(err)}')
return False
except Exception as err:
self.logger.error(f'Error connecting to {self._hostname}: {str(err)}')
return False
def commit_config(self, commands: list, mode = 'exclusive'):
if not self.device:
self.connect()
try:
with Config(self.device, mode=mode) as cu:
for command in commands:
cu.load(command, format='set')
cu.commit(timeout=DEVICE_TIMEOUT)
return True
except Exception as e:
self.logger.error(f'Error: {str(e)}')
return False
I created a workaround to handle "fake" RPC timeouts. The method checks for a candidate configuration, if the output of cu.diff() is None, then the method returns True, otherwise there's a real RPC timeout and it will returns False after two retries. Here's the final code:
Any suggestions to improve this code are always welcome, but this "fix" will help me in the short run..