Repository: ansible/ansible

Issue:
(P1)nxos_facts: module fails for n3k platforms
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
<!--- Name of the module/plugin/task/feature -->
- nxos_facts

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.4.0 (devel 85e7e342b0) last updated 2017/07/20 13:45:02 (GMT -400)
  config file = None
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /root/agents-ci/ansible/lib/ansible
  executable location = /root/agents-ci/ansible/bin/ansible
  python version = 2.7.6 (default, Oct 26 2016, 20:30:19) [GCC 4.8.4]
```

##### OS / ENVIRONMENT
<!---
Mention the OS you are running Ansible from, and the OS you are
managing, or say “N/A” for anything that is not platform-specific.
Also mention the specific version of what you are trying to control,
e.g. if this is a network bug the version of firmware on the network device.
-->
- Ansible Server : Ubuntu 14.04
- Device: Nexus 3548

##### SUMMARY
<!--- Explain the problem briefly -->
Traceback seen on Nexus 3k platforms.
```
he full traceback is:
Traceback (most recent call last):
  File "/tmp/ansible_GDri4V/ansible_module_nxos_facts.py", line 520, in <module>
    main()
  File "/tmp/ansible_GDri4V/ansible_module_nxos_facts.py", line 503, in main
    inst.populate()
  File "/tmp/ansible_GDri4V/ansible_module_nxos_facts.py", line 403, in populate
    self.facts['_power_supply_info'] = self.parse_power_supply_info(data)
  File "/tmp/ansible_GDri4V/ansible_module_nxos_facts.py", line 434, in parse_power_supply_info
    data = data['powersup']['TABLE_psinfo']['ROW_psinfo']
KeyError: 'TABLE_psinfo'
```
Example output of `show environment | json` for a Nexus 3k is:

```
{"powersup": {"voltage_level": "12", "TABLE_psinfo_n3k": {"ROW_psinfo_n3k": [{"psnum": "1", "psmodel": "--", "input_type": "--", "watts": "--", "amps": "--", "ps_status": "fail/not-powered-up"}, {"psnum": "2", "psmodel": "N2200-PAC-400W", "input_type": "AC", "watts
": "396.00", "amps": "33.00", "ps_status": "ok"}]}, "TABLE_mod_pow_info_n3k": {"ROW_mod_pow_info_n3k": {"modnum": "1", "mod_model": "N3K-C3548P-10G", "watts_requested": "348.00", "amps_requested": "29.00", "watts_alloced": "348.00", "amps_alloced": "29.00", "modsta
tus": "powered-up"}}, "power_summary_n3k": {"ps_redun_mode": "Redundant", "ps_redun_op_mode": "Non-redundant", "tot_pow_capacity": "396.00 W", "reserve_sup": "348.00 W", "pow_used_by_mods": "0.00 W", "available_pow": "48.00 W"}}, "fandetails": {"TABLE_faninfo": {"R
OW_faninfo": [{"fanname": "Fan1(sys_fan1)", "fanmodel": "NXA-FAN-30CFM-F", "fanhwver": "0.0", "fandir": "front-to-back", "fanstatus": "Ok"}, {"fanname": "Fan2(sys_fan2)", "fanmodel": "NXA-FAN-30CFM-F", "fanhwver": "0.0", "fandir": "front-to-back", "fanstatus": "Ok"
}, {"fanname": "Fan3(sys_fan3)", "fanmodel": "NXA-FAN-30CFM-F", "fanhwver": "0.0", "fandir": "front-to-back", "fanstatus": "Ok"}, {"fanname": "Fan4(sys_fan4)", "fanmodel": "NXA-FAN-30CFM-F", "fanhwver": "0.0", "fandir": "front-to-back", "fanstatus": "Ok"}, {"fannam
e": "Fan_in_PS1", "fanmodel": "N2200-PAC-400W", "fanhwver": "--", "fandir": "front-to-back", "fanstatus": "Shutdown"}, {"fanname": "Fan_in_PS2", "fanmodel": "N2200-PAC-400W", "fanhwver": "--", "fandir": "front-to-back", "fanstatus": "Ok"}]}, "TABLE_fan_zone_speed":
 {"ROW_fan_zone_speed": {"zone": "1", "speed": "0x28"}}, "fan_filter_status": "NotSupported"}, "TABLE_tempinfo": {"ROW_tempinfo": [{"tempmod": "1", "sensor": "ASIC", "majthres": "92", "minthres": "85", "curtemp": "57", "alarmstatus": "Ok"}, {"tempmod": "1", "sensor
": "INTAKE", "majthres": "45", "minthres": "31", "curtemp": "22", "alarmstatus": "Ok"}, {"tempmod": "1", "sensor": "ASIC", "majthres": "110", "minthres": "90", "curtemp": "57", "alarmstatus": "Ok"}, {"tempmod": "1", "sensor": "INTAKE", "majthres": "70", "minthres":
 "40", "curtemp": "22", "alarmstatus": "Ok"}]}}
```
##### STEPS TO REPRODUCE
<!---
For bugs, show exactly how to reproduce the problem, using a minimal test-case.
For new features, show how the feature would be used.
-->

<!--- Paste example playbooks or commands between quotes below -->
```yaml
- nxos_facts:
    gather_subset:
      - "!hardware"
```

<!--- You can also paste gist.github.com links for larger files -->

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
Expected play to apply clean.

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->
Traceback as seen above.



Discussion:
cc @GGabriele @jedelman8 @mikewiebe @privateip @rcarrillocruz @trishnaguha
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->
@rahushen What version of nxos does your 3k run? 

needs_info
@rahushen We are only testing and developing on 7k. Are you able to provide a fix for this issue on 3k?

Resolving patch:
diff --git a/lib/ansible/modules/network/nxos/nxos_facts.py b/lib/ansible/modules/network/nxos/nxos_facts.py
--- a/lib/ansible/modules/network/nxos/nxos_facts.py
+++ b/lib/ansible/modules/network/nxos/nxos_facts.py
@@ -431,7 +431,10 @@ def parse_fan_info(self, data):
         return objects
 
     def parse_power_supply_info(self, data):
-        data = data['powersup']['TABLE_psinfo']['ROW_psinfo']
+        if data.get('powersup').get('TABLE_psinfo_n3k'):
+            data = data['powersup']['TABLE_psinfo_n3k']['ROW_psinfo_n3k']
+        else:
+            data = data['powersup']['TABLE_psinfo']['ROW_psinfo']
         objects = list(self.transform_iterable(data, self.POWERSUP_MAP))
         return objects
 


Test patch: