From 109bc89bbec05453db12ec433220a84819ea1a0d Mon Sep 17 00:00:00 2001 From: saichint Date: Sun, 4 Feb 2018 21:29:13 -0800 Subject: [PATCH] fix nxos_ospf_vrf issues (#35616) --- .../modules/network/nxos/nxos_ospf_vrf.py | 148 +++++++++++------- .../nxos_ospf_vrf/tests/common/sanity.yaml | 72 ++++++++- 2 files changed, 155 insertions(+), 65 deletions(-) diff --git a/lib/ansible/modules/network/nxos/nxos_ospf_vrf.py b/lib/ansible/modules/network/nxos/nxos_ospf_vrf.py index ca4380e4d9..c2b037bdcc 100644 --- a/lib/ansible/modules/network/nxos/nxos_ospf_vrf.py +++ b/lib/ansible/modules/network/nxos/nxos_ospf_vrf.py @@ -180,42 +180,14 @@ PARAM_TO_DEFAULT_KEYMAP = { 'timer_throttle_spf_start': '200', 'timer_throttle_spf_max': '5000', 'timer_throttle_spf_hold': '1000', - 'auto_cost': '40000' + 'auto_cost': '40000', + 'default_metric': '', + 'passive_interface': False, + 'router_id': '', + 'log_adjacency': '', } -def get_value(arg, config, module): - command = PARAM_TO_COMMAND_KEYMAP.get(arg) - command_re = re.compile(r'(?:{0}\s)(?P.*)$'.format(command), re.M) - value = '' - - if command in config: - if arg == 'log_adjacency': - if 'log-adjacency-changes detail' in config: - value = 'detail' - else: - value = 'log' - elif arg == 'passive_interface': - if 'passive-interface default' in config: - value = True - else: - value = False - else: - value_list = command_re.search(config).group('value').split() - if 'hold' in arg: - value = value_list[1] - elif 'max' in arg: - value = value_list[2] - elif 'auto' in arg: - if 'Gbps' in value_list: - value = str(int(value_list[0]) * 1000) - else: - value = value_list[0] - else: - value = value_list[0] - return value - - def get_existing(module, args): existing = {} netcfg = CustomNetworkConfig(indent=2, contents=get_config(module)) @@ -225,6 +197,10 @@ def get_existing(module, args): parents.append('vrf {0}'.format(module.params['vrf'])) config = netcfg.get_section(parents) + for arg in args: + if arg not in ['ospf', 'vrf']: + existing[arg] = PARAM_TO_DEFAULT_KEYMAP.get(arg) + if config: if module.params['vrf'] == 'default': splitted_config = config.splitlines() @@ -236,10 +212,35 @@ def get_existing(module, args): if vrf_index: config = '\n'.join(splitted_config[0:vrf_index]) - for arg in args: - if arg not in ['ospf', 'vrf']: - existing[arg] = get_value(arg, config, module) - + splitted_config = config.splitlines() + for line in splitted_config: + if 'passive' in line: + existing['passive_interface'] = True + elif 'router-id' in line: + existing['router_id'] = re.search(r'router-id (\S+)', line).group(1) + elif 'metric' in line: + existing['default_metric'] = re.search(r'default-metric (\S+)', line).group(1) + elif 'adjacency' in line: + log = re.search(r'log-adjacency-changes(?: (\S+))?', line).group(1) + if log: + existing['log_adjacency'] = log + else: + existing['log_adjacency'] = 'log' + elif 'auto' in line: + cost = re.search(r'auto-cost reference-bandwidth (\d+) (\S+)', line).group(1) + if 'Gbps' in line: + cost *= 1000 + existing['auto_cost'] = str(cost) + elif 'timers throttle lsa' in line: + tmp = re.search(r'timers throttle lsa (\S+) (\S+) (\S+)', line) + existing['timer_throttle_lsa_start'] = tmp.group(1) + existing['timer_throttle_lsa_hold'] = tmp.group(2) + existing['timer_throttle_lsa_max'] = tmp.group(3) + elif 'timers throttle spf' in line: + tmp = re.search(r'timers throttle spf (\S+) (\S+) (\S+)', line) + existing['timer_throttle_spf_start'] = tmp.group(1) + existing['timer_throttle_spf_hold'] = tmp.group(2) + existing['timer_throttle_spf_max'] = tmp.group(3) existing['vrf'] = module.params['vrf'] existing['ospf'] = module.params['ospf'] @@ -255,6 +256,13 @@ def apply_key_map(key_map, table): return new_dict +def get_timer_prd(key, proposed): + if proposed.get(key): + return proposed.get(key) + else: + return PARAM_TO_DEFAULT_KEYMAP.get(key) + + def state_present(module, existing, proposed, candidate): commands = list() proposed_commands = apply_key_map(PARAM_TO_COMMAND_KEYMAP, proposed) @@ -271,23 +279,25 @@ def state_present(module, existing, proposed, candidate): else: commands.append('no {0}'.format(key)) - elif value == 'default': - if existing_commands.get(key): + elif value == 'default' or value == '': + if key == 'log-adjacency-changes': + commands.append('no {0}'.format(key)) + elif existing_commands.get(key): existing_value = existing_commands.get(key) commands.append('no {0} {1}'.format(key, existing_value)) else: if key == 'timers throttle lsa': command = '{0} {1} {2} {3}'.format( key, - proposed['timer_throttle_lsa_start'], - proposed['timer_throttle_lsa_hold'], - proposed['timer_throttle_lsa_max']) + get_timer_prd('timer_throttle_lsa_start', proposed), + get_timer_prd('timer_throttle_lsa_hold', proposed), + get_timer_prd('timer_throttle_lsa_max', proposed)) elif key == 'timers throttle spf': command = '{0} {1} {2} {3}'.format( key, - proposed['timer_throttle_spf_start'], - proposed['timer_throttle_spf_hold'], - proposed['timer_throttle_spf_max']) + get_timer_prd('timer_throttle_spf_start', proposed), + get_timer_prd('timer_throttle_spf_hold', proposed), + get_timer_prd('timer_throttle_spf_max', proposed)) elif key == 'log-adjacency-changes': if value == 'log': command = key @@ -322,25 +332,47 @@ def state_absent(module, existing, proposed, candidate): if key == 'passive-interface default': command = 'no {0}'.format(key) elif key == 'timers throttle lsa': - command = 'no {0} {1} {2} {3}'.format( - key, - existing['timer_throttle_lsa_start'], - existing['timer_throttle_lsa_hold'], - existing['timer_throttle_lsa_max']) + if (existing['timer_throttle_lsa_start'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_lsa_start') or + existing['timer_throttle_lsa_hold'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_lsa_hold') or + existing['timer_throttle_lsa_max'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_lsa_max')): + command = 'no {0} {1} {2} {3}'.format( + key, + existing['timer_throttle_lsa_start'], + existing['timer_throttle_lsa_hold'], + existing['timer_throttle_lsa_max']) elif key == 'timers throttle spf': - command = 'no {0} {1} {2} {3}'.format( - key, - existing['timer_throttle_spf_start'], - existing['timer_throttle_spf_hold'], - existing['timer_throttle_spf_max']) + if (existing['timer_throttle_spf_start'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_spf_start') or + existing['timer_throttle_spf_hold'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_spf_hold') or + existing['timer_throttle_spf_max'] != + PARAM_TO_DEFAULT_KEYMAP.get('timer_throttle_spf_max')): + command = 'no {0} {1} {2} {3}'.format( + key, + existing['timer_throttle_spf_start'], + existing['timer_throttle_spf_hold'], + existing['timer_throttle_spf_max']) + elif key == 'log-adjacency-changes': + command = 'no {0}'.format(key) + elif key == 'auto-cost reference-bandwidth': + if value != PARAM_TO_DEFAULT_KEYMAP.get('auto_cost'): + command = 'no {0}'.format(key) + else: + command = None else: existing_value = existing_commands.get(key) command = 'no {0} {1}'.format(key, existing_value) - if command not in commands: - commands.append(command) + if command: + if command not in commands: + commands.append(command) else: - commands = ['no vrf {0}'.format(module.params['vrf'])] + if (existing.get('vrf') and + existing.get('vrf') == module.params['vrf']): + commands = ['no vrf {0}'.format(module.params['vrf'])] if commands: candidate.add(commands, parents=parents) diff --git a/test/integration/targets/nxos_ospf_vrf/tests/common/sanity.yaml b/test/integration/targets/nxos_ospf_vrf/tests/common/sanity.yaml index 9535c2ea0a..3d8b0a6c5d 100644 --- a/test/integration/targets/nxos_ospf_vrf/tests/common/sanity.yaml +++ b/test/integration/targets/nxos_ospf_vrf/tests/common/sanity.yaml @@ -39,15 +39,65 @@ that: - "result.changed == false" - rescue: - - name: "Disable feature OSPF" - nxos_feature: - feature: ospf - state: disabled + - name: Configure ospf vrf + nxos_ospf_vrf: &config1 + ospf: 2 + auto_cost: 5000 + timer_throttle_spf_hold: 1100 + timer_throttle_lsa_max: 2222 + default_metric: 1000 + log_adjacency: log + vrf: default + passive_interface: true + state: present provider: "{{ connection }}" - ignore_errors: yes + register: result + + - assert: *true + + - name: "Check Idempotence" + nxos_ospf_vrf: *config1 + register: result + + - assert: *false + + - name: Configure ospf vrf + nxos_ospf_vrf: &config2 + ospf: 2 + auto_cost: default + default_metric: default + log_adjacency: default + timer_throttle_spf_hold: default + passive_interface: false + vrf: default + state: present + provider: "{{ connection }}" + register: result + + - assert: *true + + - name: "Check Idempotence" + nxos_ospf_vrf: *config2 + register: result + + - assert: *false + + - name: Unconfigure ospf vrf + nxos_ospf_vrf: &unconfig1 + ospf: 2 + vrf: default + state: absent + provider: "{{ connection }}" + register: result + + - assert: *true + + - name: "Check Idempotence" + nxos_ospf_vrf: *unconfig1 + register: result + + - assert: *false - always: - name: Unconfigure ospf vrf nxos_ospf_vrf: &unconfig ospf: 1 @@ -64,4 +114,12 @@ - assert: *false + always: + - name: "Disable feature OSPF" + nxos_feature: + feature: ospf + state: disabled + provider: "{{ connection }}" + ignore_errors: yes + - debug: msg="END connection={{ ansible_connection }} nxos_ospf_vrf sanity test"