Repository: ansible/ansible

Issue:
Add ethtool data to facts
##### ISSUE TYPE
- Feature Idea
  ##### ANSIBLE VERSION

```
ansible 2.0.1.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
and
ansible 2.1.0.0
  config file = 
  configured module search path = Default w/o overrides
```
##### CONFIGURATION
##### OS / ENVIRONMENT

Fedora 23 and RHEL72
##### SUMMARY

Capture ehttool data in interface facts.
##### EXPECTED RESULTS

```
    "ansible_br_ex": {
        "active": true,
        "device": "br-ex",
        "ethtool": {
            "busy-poll": "off [fixed]",
            "fcoe-mtu": "off [fixed]",
            "generic-receive-offload": "on",
            "generic-segmentation-offload": "on",
            "highdma": "on",
            "large-receive-offload": "off [fixed]",
   ... removed
```
##### ACTUAL RESULTS

```
    "ansible_br_ex": {
        "active": true,
        "device": "br-ex",
    ... removed
```



Discussion:

Resolving patch:
diff --git a/lib/ansible/module_utils/facts.py b/lib/ansible/module_utils/facts.py
--- a/lib/ansible/module_utils/facts.py
+++ b/lib/ansible/module_utils/facts.py
@@ -182,7 +182,7 @@ def __init__(self, module, load_on_init=True, cached_facts=None):
         if not cached_facts:
             self.facts = {}
         else:
-            self.facts = cached_facts    
+            self.facts = cached_facts
         ### TODO: Eventually, these should all get moved to populate().  But
         # some of the values are currently being used by other subclasses (for
         # instance, os_family and distribution).  Have to sort out what to do
@@ -1321,7 +1321,7 @@ def get_device_facts(self):
                         part['sectorsize'] = get_file_content(part_sysdir + "/queue/hw_sector_size",512)
                     part['size'] = self.module.pretty_bytes((float(part['sectors']) * float(part['sectorsize'])))
                     self.get_holders(part, part_sysdir)
-        
+
                     d['partitions'][partname] = part
 
             d['rotational'] = get_file_content(sysdir + "/queue/rotational")
@@ -2271,6 +2271,25 @@ def parse_ip_output(output, secondary=False):
             parse_ip_output(primary_data)
             parse_ip_output(secondary_data, secondary=True)
 
+            def parse_ethtool_output(device,output):
+                interfaces[device]['features'] = {}
+                for line in output.strip().split('\n'):
+                    if not line:
+                        continue
+                    if line.endswith(":") :
+                        continue
+                    key,value = line.split(": ")
+                    if not value :
+                        continue
+                    interfaces[device]['features'][key.strip().replace('-','_')] = value.strip()
+
+            ethtool_path = self.module.get_bin_path("ethtool")
+            if ethtool_path:
+                args = [ethtool_path, '-k', device]
+                rc, stdout, stderr = self.module.run_command(args)
+                ethtool_data = stdout
+                parse_ethtool_output(device,ethtool_data)
+
         # replace : by _ in interface name since they are hard to use in template
         new_interfaces = {}
         for i in interfaces:


Test patch: