diff --git a/changelogs/fragments/9657-lldp-handling-attributes-defined-multiple-times.yml b/changelogs/fragments/9657-lldp-handling-attributes-defined-multiple-times.yml new file mode 100644 index 00000000000..d98e68439de --- /dev/null +++ b/changelogs/fragments/9657-lldp-handling-attributes-defined-multiple-times.yml @@ -0,0 +1,4 @@ +bugfixes: + - lldp - fix crash caused by certain lldpctl output where an attribute is defined as branch and leaf +minor_changes: + - lldp - adds ``multivalues`` parameter to control behavior when lldpctl outputs an attribute multiple times diff --git a/plugins/modules/lldp.py b/plugins/modules/lldp.py index baefb09d912..8b3d2856b92 100644 --- a/plugins/modules/lldp.py +++ b/plugins/modules/lldp.py @@ -22,7 +22,12 @@ 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,7 +58,7 @@ def gather_lldp(module): if output: output_dict = {} current_dict = {} - lldp_entries = output.split("\n") + lldp_entries = output.strip().split("\n") for entry in lldp_entries: if entry.startswith('lldp'): @@ -61,18 +66,35 @@ def gather_lldp(module): path = path.split(".") path_components, final = path[:-1], path[-1] else: - value = current_dict[final] + '\n' + entry + 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 type(current_dict[path_component]) is not 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 type(current_dict[final]) is dict: + current_dict = current_dict[final] + final = 'value' + + if final not in current_dict or not module.params['multivalues']: + current_dict[final] = value + elif type(current_dict[final]) is str: + current_dict[final] = [current_dict[final], value] + elif type(current_dict[final]) is list: + current_dict[final].append(value) + return output_dict def main(): - module = AnsibleModule({}) + module_args = dict( + multivalues=dict(type='bool', equired=False, default=False) + ) + module = AnsibleModule(module_args) lldp_output = gather_lldp(module) try: