handle config as text in load and merge functions

This commit is contained in:
Pieprzycki Piotr 2018-04-08 00:23:04 +02:00
parent 4d52216866
commit 47227d1cf0
1 changed files with 67 additions and 39 deletions

View File

@ -22,6 +22,7 @@ Read napalm.readthedocs.org for more information.
import re import re
import os import os
import tempfile
import vyattaconfparser import vyattaconfparser
@ -33,8 +34,9 @@ from netmiko import SCPConn
import napalm.base.constants as C import napalm.base.constants as C
from napalm.base.utils import py23_compat from napalm.base.utils import py23_compat
from napalm.base.base import NetworkDriver from napalm.base.base import NetworkDriver
from napalm.base.exceptions import ConnectionException, \ from napalm.base.exceptions import ConnectionException, MergeConfigException, \
MergeConfigException, ReplaceConfigException ReplaceConfigException, CommitError, \
CommandErrorException
class VyOSDriver(NetworkDriver): class VyOSDriver(NetworkDriver):
@ -121,53 +123,73 @@ class VyOSDriver(NetworkDriver):
Due to the OS nature, we do not Due to the OS nature, we do not
support a replace using a configuration string. support a replace using a configuration string.
""" """
if filename is not None: if not filename and not config:
if os.path.exists(filename) is True: raise ReplaceConfigException('filename or config param must be provided.')
self._scp_client.scp_transfer_file(filename, self._DEST_FILENAME)
self.device.send_command("cp "+self._BOOT_FILENAME+" "+self._BACKUP_FILENAME)
output_loadcmd = self.device.send_config_set(['load '+self._DEST_FILENAME])
match_loaded = re.findall("Load complete.", output_loadcmd)
match_notchanged = re.findall("No configuration changes to commit", output_loadcmd)
match_failed = re.findall("Failed to parse specified config file", output_loadcmd)
if match_failed: if filename is None:
temp_file = tempfile.NamedTemporaryFile()
temp_file.write(config)
temp_file.flush()
cfg_filename = temp_file.name
else:
cfg_filename = filename
if os.path.exists(cfg_filename) is True:
self._scp_client.scp_transfer_file(cfg_filename, self._DEST_FILENAME)
self.device.send_command("cp "+self._BOOT_FILENAME+" "+self._BACKUP_FILENAME)
output_loadcmd = self.device.send_config_set(['load '+self._DEST_FILENAME])
match_loaded = re.findall("Load complete.", output_loadcmd)
match_notchanged = re.findall("No configuration changes to commit", output_loadcmd)
match_failed = re.findall("Failed to parse specified config file", output_loadcmd)
if match_failed:
raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd)
if not match_loaded:
if not match_notchanged:
raise ReplaceConfigException("Failed replace config: " raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd) + output_loadcmd)
if not match_loaded:
if not match_notchanged:
raise ReplaceConfigException("Failed replace config: "
+ output_loadcmd)
else:
raise ReplaceConfigException("config file is not found")
else: else:
raise ReplaceConfigException("no configuration found") raise ReplaceConfigException("config file is not found")
def load_merge_candidate(self, filename=None, config=None): def load_merge_candidate(self, filename=None, config=None):
""" """
Only configuration in set-format is supported with load_merge_candidate. Only configuration in set-format is supported with load_merge_candidate.
""" """
if filename is not None:
if os.path.exists(filename) is True:
with open(filename) as f:
self.device.send_command("cp "+self._BOOT_FILENAME+" "
+ self._BACKUP_FILENAME)
self._new_config = f.read()
cfg = [x for x in self._new_config.split("\n") if x is not ""]
output_loadcmd = self.device.send_config_set(cfg)
match_setfailed = re.findall("Delete failed", output_loadcmd)
match_delfailed = re.findall("Set failed", output_loadcmd)
if match_setfailed or match_delfailed: if not filename and not config:
raise MergeConfigException("Failed merge config: " raise MergeConfigException('filename or config param must be provided.')
+ output_loadcmd)
else: if filename is None:
raise MergeConfigException("config file is not found") temp_file = tempfile.NamedTemporaryFile()
elif config is not None: temp_file.write(config)
self._new_config = config temp_file.flush()
cfg_filename = temp_file.name
else: else:
raise MergeConfigException("no configuration found") cfg_filename = filename
if os.path.exists(cfg_filename) is True:
with open(cfg_filename) as f:
self.device.send_command("cp "+self._BOOT_FILENAME+" "
+ self._BACKUP_FILENAME)
self._new_config = f.read()
cfg = [x for x in self._new_config.split("\n") if x is not ""]
output_loadcmd = self.device.send_config_set(cfg)
match_setfailed = re.findall("Delete failed", output_loadcmd)
match_delfailed = re.findall("Set failed", output_loadcmd)
if match_setfailed or match_delfailed:
raise MergeConfigException("Failed merge config: "
+ output_loadcmd)
else:
raise MergeConfigException("config file is not found")
def discard_config(self): def discard_config(self):
self.device.exit_config_mode() self.device.exit_config_mode()
@ -183,8 +205,12 @@ class VyOSDriver(NetworkDriver):
return diff return diff
def commit_config(self): def commit_config(self):
if self.device.commit(): try:
self.device.send_config_set(['save']) self.device.commit()
except ValueError:
raise CommitError("Failed to commit config on the device")
self.device.send_config_set(['save'])
self.device.exit_config_mode() self.device.exit_config_mode()
def rollback(self): def rollback(self):
@ -478,6 +504,8 @@ class VyOSDriver(NetworkDriver):
received_prefixes = int(state_prefix) received_prefixes = int(state_prefix)
is_up = True is_up = True
except ValueError: except ValueError:
state_prefix = -1
received_prefixes = -1
is_up = False is_up = False
if bgp_version == "4": if bgp_version == "4":