Standardize cliconf get_capabilities (#51147)

* Standardize cliconf get_capabilities

* Check for capabilities before querying them

* Try to be more helpful when unexpected things are found in get_capabilities

* Add flags param to get_config for compatibility
This commit is contained in:
Nathaniel Case 2019-01-28 08:24:44 -05:00 committed by GitHub
parent bd44db141a
commit 9336281a60
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 82 additions and 143 deletions

View file

@ -195,43 +195,27 @@ from ansible.module_utils.connection import Connection
from ansible.module_utils._text import to_text
def validate_args(module, capabilities):
def validate_args(module, device_operations):
"""validate param if it is supported on the platform
"""
if (module.params['replace'] and
not capabilities['device_operations']['supports_replace']):
module.fail_json(msg='replace is not supported on this platform')
feature_list = [
'replace', 'rollback', 'commit_comment', 'defaults', 'multiline_delimiter',
'diff_replace', 'diff_match', 'diff_ignore_lines',
]
if (module.params['rollback'] is not None and
not capabilities['device_operations']['supports_rollback']):
module.fail_json(msg='rollback is not supported on this platform')
if (module.params['commit_comment'] and
not capabilities['device_operations']['supports_commit_comment']):
module.fail_json(msg='commit_comment is not supported on this platform')
if (module.params['defaults'] and
not capabilities['device_operations']['supports_defaults']):
module.fail_json(msg='defaults is not supported on this platform')
if (module.params['multiline_delimiter'] and
not capabilities['device_operations']['supports_multiline_delimiter']):
module.fail_json(msg='multiline_delimiter is not supported on this platform')
if (module.params['diff_replace'] and
not capabilities['device_operations']['supports_diff_replace']):
module.fail_json(msg='diff_replace is not supported on this platform')
if (module.params['diff_match'] and
not capabilities['device_operations']['supports_diff_match']):
module.fail_json(msg='diff_match is not supported on this platform')
if (module.params['diff_ignore_lines'] and
not capabilities['device_operations']['supports_diff_ignore_lines']):
module.fail_json(msg='diff_ignore_lines is not supported on this platform')
for feature in feature_list:
if module.params[feature]:
supports_feature = device_operations.get('supports_%s' % feature)
if supports_feature is None:
module.fail_json(
"This platform does not specify whether %s is supported or not. "
"Please report an issue against this platform's cliconf plugin." % feature
)
elif not supports_feature:
module.fail_json(msg='Option %s is not supported on this platform' % feature)
def run(module, capabilities, connection, candidate, running, rollback_id):
def run(module, device_operations, connection, candidate, running, rollback_id):
result = {}
resp = {}
config_diff = []
@ -256,7 +240,7 @@ def run(module, capabilities, connection, candidate, running, rollback_id):
if 'diff' in resp:
result['changed'] = True
elif capabilities['device_operations']['supports_onbox_diff']:
elif device_operations.get('supports_onbox_diff'):
if diff_replace:
module.warn('diff_replace is ignored as the device supports onbox diff')
if diff_match:
@ -274,7 +258,7 @@ def run(module, capabilities, connection, candidate, running, rollback_id):
if 'diff' in resp:
result['changed'] = True
elif capabilities['device_operations']['supports_generate_diff']:
elif device_operations.get('supports_generate_diff'):
kwargs = {'candidate': candidate, 'running': running}
if diff_match:
kwargs.update({'diff_match': diff_match})
@ -361,7 +345,10 @@ def main():
capabilities = module.from_json(connection.get_capabilities())
if capabilities:
validate_args(module, capabilities)
device_operations = capabilities.get('device_operations', dict())
validate_args(module, device_operations)
else:
device_operations = dict()
if module.params['defaults']:
if 'get_default_flag' in capabilities.get('rpc'):
@ -381,7 +368,7 @@ def main():
if candidate or rollback_id:
try:
result.update(run(module, capabilities, connection, candidate, running, rollback_id))
result.update(run(module, device_operations, connection, candidate, running, rollback_id))
except Exception as exc:
module.fail_json(msg=to_text(exc))

View file

@ -278,6 +278,22 @@ class CliconfBase(AnsiblePlugin):
}
:return: capability as json string
"""
result = {}
result['rpc'] = self.get_base_rpc()
result['device_info'] = self.get_device_info()
result['network_api'] = 'cliconf'
return result
@abstractmethod
def get_device_info(self):
"""Returns basic information about the network device.
This method will provide basic information about the device such as OS version and model
name. This data is expected to be used to fill the 'device_info' key in get_capabilities()
above.
:return: dictionary of device information
"""
pass
def commit(self, comment=None):

View file

@ -55,7 +55,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running':
@ -73,8 +73,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -56,7 +56,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running':
@ -74,8 +74,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -53,7 +53,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running':
@ -71,8 +71,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -86,8 +86,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -65,7 +65,7 @@ class Cliconf(CliconfBase):
return "NA"
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
msg = "fetching configuration from %s is not supported"
return self.invalid_params(msg % source)
@ -84,8 +84,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -57,7 +57,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running':
@ -75,8 +75,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -57,7 +57,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
# if source == 'running':
@ -75,8 +75,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -57,7 +57,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source)
# if source == 'running':
@ -75,8 +75,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -38,7 +38,7 @@ class Cliconf(CliconfBase):
return device_info
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
return self.send_command('show configuration commands')
def edit_config(self, candidate=None, commit=True, replace=False, comment=None):
@ -59,8 +59,6 @@ class Cliconf(CliconfBase):
self.send_command('discard')
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc() + ['commit', 'discard_changes']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['commit', 'discard_changes']
return json.dumps(result)

View file

@ -103,10 +103,8 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = dict()
result['rpc'] = self.get_base_rpc() + ['run_commands']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['run_commands']
return json.dumps(result)
def run_commands(self, commands=None, check_rc=True):

View file

@ -52,7 +52,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running', 'startup'):
msg = "fetching configuration from %s is not supported"
return self.invalid_params(msg % source)
@ -71,8 +71,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -272,13 +272,10 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = {}
rpc_list = ['commit', 'discard_changes', 'get_diff', 'run_commands', 'supports_sessions']
result['rpc'] = self.get_base_rpc() + rpc_list
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['commit', 'discard_changes', 'get_diff', 'run_commands', 'supports_sessions']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
result['network_api'] = 'cliconf'
return json.dumps(result)

View file

@ -114,10 +114,7 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)

View file

@ -230,10 +230,8 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = dict()
result['rpc'] = self.get_base_rpc() + ['edit_banner', 'get_diff', 'run_commands', 'get_defaults_flag']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['edit_banner', 'get_diff', 'run_commands', 'get_defaults_flag']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)

View file

@ -234,10 +234,8 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc() + ['commit', 'discard_changes', 'get_diff', 'configure', 'exit']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['commit', 'discard_changes', 'get_diff', 'configure', 'exit']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)

View file

@ -74,8 +74,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -229,10 +229,8 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = dict()
result['rpc'] = self.get_base_rpc() + ['commit', 'discard_changes', 'run_commands', 'compare_configuration', 'validate', 'get_diff']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['commit', 'discard_changes', 'run_commands', 'compare_configuration', 'validate', 'get_diff']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)

View file

@ -99,8 +99,5 @@ class Cliconf(CliconfBase):
return self.send_command(command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -244,12 +244,10 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc() + ['get_diff', 'run_commands']
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['get_diff', 'run_commands']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
result['network_api'] = 'cliconf'
return json.dumps(result)

View file

@ -49,7 +49,7 @@ class Cliconf(CliconfBase):
return device_info
@enable_mode
def get_config(self, source='running', format='text'):
def get_config(self, source='running', format='text', flags=None):
if source not in ('running',):
return self.invalid_params("fetching configuration from %s is not supported" % source)
cmd = 'show running-config'
@ -64,8 +64,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -65,8 +65,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -91,8 +91,5 @@ class Cliconf(CliconfBase):
return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
return json.dumps(result)

View file

@ -192,10 +192,8 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = dict()
result['rpc'] = self.get_base_rpc() + ['get_diff', 'run_commands', 'get_defaults_flag']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['get_diff', 'run_commands', 'get_defaults_flag']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)

View file

@ -241,10 +241,8 @@ class Cliconf(CliconfBase):
}
def get_capabilities(self):
result = {}
result['rpc'] = self.get_base_rpc() + ['commit', 'discard_changes', 'get_diff', 'run_commands']
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
result = super(Cliconf, self).get_capabilities()
result['rpc'] += ['commit', 'discard_changes', 'get_diff', 'run_commands']
result['device_operations'] = self.get_device_operations()
result.update(self.get_option_values())
return json.dumps(result)