fixes error when 'delete ...' config command is specified but doesn't exist (#5064)
The junos_config module will generate an exception if a 'delete ...' config command is attempted to be loaded into a device configuration. This change will first check to see if the delete command is valid and filter it out of the change set if it is not valid. fixes #5040
This commit is contained in:
parent
aa82f48dc8
commit
da4c11241f
1 changed files with 48 additions and 0 deletions
|
@ -169,6 +169,7 @@ import ansible.module_utils.junos
|
||||||
|
|
||||||
from ansible.module_utils.basic import get_exception
|
from ansible.module_utils.basic import get_exception
|
||||||
from ansible.module_utils.network import NetworkModule, NetworkError
|
from ansible.module_utils.network import NetworkModule, NetworkError
|
||||||
|
from ansible.module_utils.netcfg import NetworkConfig
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_COMMENT = 'configured by junos_config'
|
DEFAULT_COMMENT = 'configured by junos_config'
|
||||||
|
@ -192,6 +193,46 @@ def guess_format(config):
|
||||||
|
|
||||||
return 'text'
|
return 'text'
|
||||||
|
|
||||||
|
def config_to_commands(config):
|
||||||
|
set_format = config.startswith('set') or config.startswith('delete')
|
||||||
|
candidate = NetworkConfig(indent=4, contents=config, device_os='junos')
|
||||||
|
if not set_format:
|
||||||
|
candidate = [c.line for c in candidate.items]
|
||||||
|
commands = list()
|
||||||
|
# this filters out less specific lines
|
||||||
|
for item in candidate:
|
||||||
|
for index, entry in enumerate(commands):
|
||||||
|
if item.startswith(entry):
|
||||||
|
del commands[index]
|
||||||
|
break
|
||||||
|
commands.append(item)
|
||||||
|
|
||||||
|
else:
|
||||||
|
commands = str(candidate).split('\n')
|
||||||
|
|
||||||
|
return commands
|
||||||
|
|
||||||
|
def diff_commands(commands, config):
|
||||||
|
config = [str(c).replace("'", '') for c in config]
|
||||||
|
|
||||||
|
updates = list()
|
||||||
|
visited = set()
|
||||||
|
|
||||||
|
for item in commands:
|
||||||
|
if not item.startswith('set') and not item.startswith('delete'):
|
||||||
|
raise ValueError('line must start with either `set` or `delete`')
|
||||||
|
|
||||||
|
elif item.startswith('set') and item[4:] not in config:
|
||||||
|
updates.append(item)
|
||||||
|
|
||||||
|
elif item.startswith('delete'):
|
||||||
|
for entry in config:
|
||||||
|
if entry.startswith(item[7:]) and item not in visited:
|
||||||
|
updates.append(item)
|
||||||
|
visited.add(item)
|
||||||
|
|
||||||
|
return updates
|
||||||
|
|
||||||
def load_config(module, result):
|
def load_config(module, result):
|
||||||
candidate = module.params['lines'] or module.params['src']
|
candidate = module.params['lines'] or module.params['src']
|
||||||
|
|
||||||
|
@ -207,6 +248,13 @@ def load_config(module, result):
|
||||||
config_format = 'set'
|
config_format = 'set'
|
||||||
kwargs['config_format'] = config_format
|
kwargs['config_format'] = config_format
|
||||||
|
|
||||||
|
# this is done to filter out `delete ...` statements which map to
|
||||||
|
# nothing in the config as that will cause an exception to be raised
|
||||||
|
if config_format == 'set':
|
||||||
|
config = module.config.get_config()
|
||||||
|
config = config_to_commands(config)
|
||||||
|
candidate = diff_commands(candidate, config)
|
||||||
|
|
||||||
diff = module.config.load_config(candidate, **kwargs)
|
diff = module.config.load_config(candidate, **kwargs)
|
||||||
|
|
||||||
if diff:
|
if diff:
|
||||||
|
|
Loading…
Reference in a new issue