lldp: Handling attributes that are defined multiple times (#9657)
* lldp: Ignoring values for keys already defined This fixes crashes when the lldpctl output has lines for unknown tlvs that redefine a key in the middle of the nested dict data structure. * lldp: handling attributes that are defined multiple times - Fix crash caused by certain lldpctl output where an attribute is defined as branch and leaf - Adds multivalues parameter to control behavior when lldpctl outputs an attribute multiple times * lldp: using isinstance instead of type * Link to Github PR Apply suggestions from code review Co-authored-by: Felix Fontein <felix@fontein.de> * lldp: only push value to subkey in multivalues mode To provide backwards compatibility values that are defined as a attribute and also as a path element are only pushed to the 'value' subkey when using the new multivalues mode. --------- Co-authored-by: Felix Fontein <felix@fontein.de>pull/9805/head
parent
217a18839d
commit
2b6f4ba299
|
@ -0,0 +1,4 @@
|
|||
bugfixes:
|
||||
- lldp - fix crash caused by certain lldpctl output where an attribute is defined as branch and leaf (https://github.com/ansible-collections/community.general/pull/9657).
|
||||
minor_changes:
|
||||
- lldp - adds ``multivalues`` parameter to control behavior when lldpctl outputs an attribute multiple times (https://github.com/ansible-collections/community.general/pull/9657).
|
|
@ -22,7 +22,12 @@ attributes:
|
|||
support: none
|
||||
diff_mode:
|
||||
support: none
|
||||
options: {}
|
||||
options:
|
||||
multivalues:
|
||||
description: If lldpctl outputs an attribute multiple time represent all values as a list.
|
||||
required: false
|
||||
type: bool
|
||||
default: false
|
||||
author: "Andy Hill (@andyhky)"
|
||||
notes:
|
||||
- Requires C(lldpd) running and LLDP enabled on switches.
|
||||
|
@ -53,26 +58,49 @@ def gather_lldp(module):
|
|||
if output:
|
||||
output_dict = {}
|
||||
current_dict = {}
|
||||
lldp_entries = output.split("\n")
|
||||
lldp_entries = output.strip().split("\n")
|
||||
|
||||
final = ""
|
||||
for entry in lldp_entries:
|
||||
if entry.startswith('lldp'):
|
||||
path, value = entry.strip().split("=", 1)
|
||||
path = path.split(".")
|
||||
path_components, final = path[:-1], path[-1]
|
||||
elif final in current_dict and isinstance(current_dict[final], str):
|
||||
current_dict[final] += '\n' + entry
|
||||
continue
|
||||
elif final in current_dict and isinstance(current_dict[final], list):
|
||||
current_dict[final][-1] += '\n' + entry
|
||||
continue
|
||||
else:
|
||||
value = current_dict[final] + '\n' + entry
|
||||
continue
|
||||
|
||||
current_dict = output_dict
|
||||
for path_component in path_components:
|
||||
current_dict[path_component] = current_dict.get(path_component, {})
|
||||
if not isinstance(current_dict[path_component], dict):
|
||||
current_dict[path_component] = {'value': current_dict[path_component]}
|
||||
current_dict = current_dict[path_component]
|
||||
current_dict[final] = value
|
||||
|
||||
if final in current_dict and isinstance(current_dict[final], dict) and module.params['multivalues']:
|
||||
current_dict = current_dict[final]
|
||||
final = 'value'
|
||||
|
||||
if final not in current_dict or not module.params['multivalues']:
|
||||
current_dict[final] = value
|
||||
elif isinstance(current_dict[final], str):
|
||||
current_dict[final] = [current_dict[final], value]
|
||||
elif isinstance(current_dict[final], list):
|
||||
current_dict[final].append(value)
|
||||
|
||||
return output_dict
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule({})
|
||||
module_args = dict(
|
||||
multivalues=dict(type='bool', required=False, default=False)
|
||||
)
|
||||
module = AnsibleModule(module_args)
|
||||
|
||||
lldp_output = gather_lldp(module)
|
||||
try:
|
||||
|
|
Loading…
Reference in New Issue