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
pull/51386/head
Nathaniel Case 6 years ago committed by GitHub
parent bd44db141a
commit 9336281a60
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

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

@ -278,6 +278,22 @@ class CliconfBase(AnsiblePlugin):
} }
:return: capability as json string :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 pass
def commit(self, comment=None): def commit(self, comment=None):

@ -55,7 +55,7 @@ class Cliconf(CliconfBase):
return device_info return device_info
@enable_mode @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'): if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source) return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running': 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) return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self): def get_capabilities(self):
result = {} result = super(Cliconf, self).get_capabilities()
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
return json.dumps(result) return json.dumps(result)

@ -56,7 +56,7 @@ class Cliconf(CliconfBase):
return device_info return device_info
@enable_mode @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'): if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source) return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running': 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) return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self): def get_capabilities(self):
result = {} result = super(Cliconf, self).get_capabilities()
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
return json.dumps(result) return json.dumps(result)

@ -53,7 +53,7 @@ class Cliconf(CliconfBase):
return device_info return device_info
@enable_mode @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'): if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source) return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running': 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) return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self): def get_capabilities(self):
result = {} result = super(Cliconf, self).get_capabilities()
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
return json.dumps(result) return json.dumps(result)

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

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

@ -57,7 +57,7 @@ class Cliconf(CliconfBase):
return device_info return device_info
@enable_mode @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'): if source not in ('running', 'startup'):
return self.invalid_params("fetching configuration from %s is not supported" % source) return self.invalid_params("fetching configuration from %s is not supported" % source)
if source == 'running': 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) return self.send_command(command=command, prompt=prompt, answer=answer, sendonly=sendonly, check_all=check_all)
def get_capabilities(self): def get_capabilities(self):
result = {} result = super(Cliconf, self).get_capabilities()
result['rpc'] = self.get_base_rpc()
result['network_api'] = 'cliconf'
result['device_info'] = self.get_device_info()
return json.dumps(result) return json.dumps(result)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Loading…
Cancel
Save