Repository: ansible/ansible
Pull request: Fix gather facts ignoring gather_subsets config
 fixes #58728


##### ISSUE TYPE
<!--- Pick one below and delete the rest -->
- Bugfix Pull Request

##### COMPONENT NAME
<!--- Write the short name of the module, plugin, task or feature below -->
gather_facts

Problem statement:
'gather_subset' setting in ansible.cfg and ansible/roles are ignored
##### SUMMARY
'gather_subset' setting in ansible.cfg and ansible/roles are ignored

##### ISSUE TYPE
- Bug Report

##### COMPONENT NAME
fact gathering

##### ANSIBLE VERSION
```
ansible 2.8.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
```

##### CONFIGURATION
```
ANSIBLE_PIPELINING(/etc/ansible/ansible.cfg) = True
ANSIBLE_SSH_CONTROL_PATH(/etc/ansible/ansible.cfg) = %(directory)s/ans-ssh-%%h-%%p-%%r
ANSIBLE_SSH_RETRIES(/etc/ansible/ansible.cfg) = 1
DEFAULT_CALLBACK_WHITELIST(/etc/ansible/ansible.cfg) = [u'profile_tasks', u'grafana_annotations']
DEFAULT_FORKS(/etc/ansible/ansible.cfg) = 500
DEFAULT_GATHERING(/etc/ansible/ansible.cfg) = smart
DEFAULT_GATHER_SUBSET(/etc/ansible/ansible.cfg) = [u'!hardware', u'!ohai', u'!facter', u'!virtual', u'!network']
DEFAULT_GATHER_TIMEOUT(/etc/ansible/ansible.cfg) = 10
DEFAULT_HOST_LIST(/etc/ansible/ansible.cfg) = [u'/etc/ansible/inventory']
DEFAULT_SCP_IF_SSH(/etc/ansible/ansible.cfg) = True
DEFAULT_TIMEOUT(/etc/ansible/ansible.cfg) = 15
```

##### OS / ENVIRONMENT
```
CentOS Linux release 7.6.1810 (Core)
```


##### STEPS TO REPRODUCE
```
I have the following settings in my ansible.cfg:
...
gathering = smart
gather_subset = min
...

and also tried to set following within my role:
...
- name: 'test fact gahtering'
  setup:
    gather_subset: 'min'
...

but still all facts are gathered during a playbook run.

        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "xen", 
        "gather_subset": [
            "all"

As a workaround I set the default value to 'min' within:
"/usr/lib/python2.7/site-packages/ansible/modules/system/setup.py". 
That works.

def main():
    module = AnsibleModule(
        argument_spec=dict(
            gather_subset=dict(default=["min"], required=False, type='list'),
```

##### EXPECTED RESULTS
gather_subset setting should be loaded from ansible.cfg or within role if set.


##### ACTUAL RESULTS
gather_subset within ansible.cfg and role are ignored and all facts are gathered

```
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "xen", 
        "gather_subset": [
            "all"
```

Hints from issue discussion:
Files identified in the description:
None

If these files are inaccurate, please update the `component name` section of the description or use the `!component` bot command.

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: components_banner --->
needs_info
I believe I'm getting the same thing. If I define `gather_subset = !hardware` in `/etc/ansible/ansible.cfg`, Ansible ignores it.

Ansible Control Node Info: `CentOS Linux release 7.6.1810 (Core)`

~~~
[root@059ef6ed871e inventories]# ansible-config dump -c /etc/ansible/ansible.cfg --only-changed
DEFAULT_GATHER_SUBSET(/etc/ansible/ansible.cfg) = [u'!hardware']
~~~

~~~
ansible-playbook 2.8.1
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible-playbook
  python version = 2.7.5 (default, Jun 20 2019, 20:27:34) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /etc/ansible/inventories/test as it did not pass it's verify_file() method
script declined parsing /etc/ansible/inventories/test as it did not pass it's verify_file() method
auto declined parsing /etc/ansible/inventories/test as it did not pass it's verify_file() method
Parsed /etc/ansible/inventories/test inventory source with ini plugin
~~~

Snippet of output from `ansible-playbook test.yml -i test -vvv`:

~~~
ok: [CentOS2] => {
    "ansible_facts": {
        "ansible_apparmor": {
            "status": "disabled"
        },
        "ansible_architecture": "x86_64",
        "ansible_bios_date": "12/01/2006",
        "ansible_bios_version": "VirtualBox",
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-4.4.0-142-generic",
            "ro": true,
            "root": "UUID=bfe21d0f-b019-4593-b044-1678f6cc66b7"
        },
        "ansible_date_time": {
            "date": "2019-07-18",
            "day": "18",
            "epoch": "1563480306",
            "hour": "20",
            "iso8601": "2019-07-18T20:05:06Z",
            "iso8601_basic": "20190718T200506178149",
            "iso8601_basic_short": "20190718T200506",
            "iso8601_micro": "2019-07-18T20:05:06.178202Z",
            "minute": "05",
            "month": "07",
            "second": "06",
            "time": "20:05:06",
            "tz": "UTC",
            "tz_offset": "+0000",
            "weekday": "Thursday",
            "weekday_number": "4",
            "weeknumber": "28",
            "year": "2019"
        },
        "ansible_device_links": {
            "ids": {
                "sda": [
                    "ata-VBOX_HARDDISK_VB9136164d-92c8d867"
                ],
                "sda1": [
                    "ata-VBOX_HARDDISK_VB9136164d-92c8d867-part1"
                ],
                "sda2": [
                    "ata-VBOX_HARDDISK_VB9136164d-92c8d867-part2"
                ],
                "sr0": [
                    "ata-VBOX_CD-ROM_VB2-01700376"
                ]
            },
            "labels": {},
            "masters": {},
            "uuids": {
                "sda1": [
                    "bfe21d0f-b019-4593-b044-1678f6cc66b7"
                ]
            }
	},
	"ansible_devices": {
            "loop0": {
                "holders": [],
                "host": "",
                "links": {
                    "ids": [],
~~~

Output from when I explicitly define `gather_subset: '!hardware'`:

~~~
ok: [CentOS2] => {
    "ansible_facts": {
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-4.4.0-142-generic", 
            "ro": true, 
            "root": "UUID=bfe21d0f-b019-4593-b044-1678f6cc66b7"
        }, 
        "ansible_date_time": {
            "date": "2019-07-18", 
            "day": "18", 
            "epoch": "1563480792", 
            "hour": "20", 
            "iso8601": "2019-07-18T20:13:12Z", 
            "iso8601_basic": "20190718T201312561901", 
            "iso8601_basic_short": "20190718T201312", 
            "iso8601_micro": "2019-07-18T20:13:12.561957Z", 
            "minute": "13", 
            "month": "07", 
            "second": "12", 
            "time": "20:13:12", 
            "tz": "UTC", 
            "tz_offset": "+0000", 
            "weekday": "Thursday", 
            "weekday_number": "4", 
            "weeknumber": "28", 
            "year": "2019"
        }, 
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7", 
        "ansible_dns": {
            "nameservers": [
                "8.8.8.8"
            ]
        }, 
        "ansible_domain": "", 
        "ansible_effective_group_id": 0, 
        "ansible_effective_user_id": 0, 
        "ansible_env": {
            "HOME": "/root", 
            "LANG": "en_US.UTF-8", 
            "LOGNAME": "root", 
            "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:", 
            "MAIL": "/var/mail/root", 
            "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", 
            "PWD": "/root", 
            "SHELL": "/bin/bash", 
            "SHLVL": "2", 
            "SSH_CLIENT": "172.17.0.1 51108 22", 
            "SSH_CONNECTION": "172.17.0.1 51108 172.17.0.7 22", 
            "SSH_TTY": "/dev/pts/1", 
            "TERM": "xterm", 
            "USER": "root", 
            "XDG_RUNTIME_DIR": "/run/user/0", 
            "XDG_SESSION_ID": "28", 
            "_": "/usr/bin/python"
        }, 
        "ansible_fips": false, 
        "ansible_fqdn": "CentOS2", 
        "ansible_hostname": "CentOS2", 
        "ansible_kernel": "4.4.0-142-generic", 
        "ansible_local": {}, 
        "ansible_lsb": {}, 
        "ansible_machine": "x86_64", 
        "ansible_machine_id": "407f52e8ea764070a44c24941d31cd62", 
        "ansible_nodename": "CentOS2", 
        "ansible_os_family": "RedHat", 
        "ansible_pkg_mgr": "yum", 
        "ansible_proc_cmdline": {
            "BOOT_IMAGE": "/boot/vmlinuz-4.4.0-142-generic", 
            "ro": true, 
            "root": "UUID=bfe21d0f-b019-4593-b044-1678f6cc66b7"
        }, 
        "ansible_python": {
            "executable": "/usr/bin/python", 
            "has_sslcontext": true, 
            "type": "CPython", 
            "version": {
                "major": 2, 
                "micro": 5, 
                "minor": 7, 
                "releaselevel": "final", 
                "serial": 0
            }, 
            "version_info": [
                2, 
                7, 
                5, 
                "final", 
                0
            ]
        }, 
        "ansible_python_version": "2.7.5", 
        "ansible_real_group_id": 0, 
        "ansible_real_user_id": 0, 
        "ansible_selinux": {
            "status": "Missing selinux Python library"
        }, 
        "ansible_selinux_python_present": false, 
        "ansible_service_mgr": "systemd", 
        "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBKKOjpuP5FDwxMBET0um6dEdtkJPWYynFuTmyWAjIp6Z0wCNmZg7lvLk60s6xfhKEOrCQnujcEEeQYkBqb5FPag=", 
        "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIBRHTglQ9v4otldwpitTBz8l1uIWbWsK90L4iUzPLkz1", 
        "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQDFhjXy7s6LqUQf3NdcWMPgiGB+nByONM23X+VJY+mjFEKHYwL3fRstlTy0bEqTHbEUEHojd5gVrZ+NZByEQ4cdfog6hRxmy4VTfeW3CEmCxb7COoUiq30wd86Tata66syVBblfZgaMkGdeFKZpJA/WtL+GpWcZf8TFsqsA8WACqHUFQNlk8F8K9wPrN0CkMsWW5Zs7LtSZrZ3pzyJvqacKG1IZ95h3LnHABDpwCSNvnH+lT2WQpvK6Y3NemiPhWkCfWolHtS8R56xwLnu88BqP5p8GHzn01kRPTFFQfg922ivDlXoSDeitwPbq4LLVwrVWjxTdV//BAyKxnSxqJVv5", 
        "ansible_system": "Linux", 
        "ansible_system_capabilities": [
            "cap_chown", 
            "cap_dac_override", 
            "cap_dac_read_search", 
            "cap_fowner", 
            "cap_fsetid", 
            "cap_kill", 
            "cap_setgid", 
            "cap_setuid", 
            "cap_setpcap", 
            "cap_linux_immutable", 
            "cap_net_bind_service", 
            "cap_net_broadcast", 
            "cap_net_admin", 
            "cap_net_raw", 
            "cap_ipc_lock", 
            "cap_ipc_owner", 
            "cap_sys_module", 
            "cap_sys_rawio", 
            "cap_sys_chroot", 
            "cap_sys_ptrace", 
            "cap_sys_pacct", 
            "cap_sys_admin", 
            "cap_sys_boot", 
            "cap_sys_nice", 
            "cap_sys_resource", 
            "cap_sys_time", 
            "cap_sys_tty_config", 
            "cap_mknod", 
            "cap_lease", 
            "cap_audit_write", 
            "cap_audit_control", 
            "cap_setfcap", 
            "cap_mac_override", 
            "cap_mac_admin", 
            "cap_syslog", 
            "35", 
            "36", 
            "37+eip"
        ], 
        "ansible_system_capabilities_enforced": "True", 
        "ansible_user_dir": "/root", 
        "ansible_user_gecos": "root", 
        "ansible_user_gid": 0, 
        "ansible_user_id": "root", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 0, 
        "ansible_userspace_architecture": "x86_64", 
        "ansible_userspace_bits": "64", 
        "discovered_interpreter_python": "/usr/bin/python", 
        "gather_subset": [
            "!hardware"
        ], 
        "module_setup": true
    }, 
    "changed": false
}
~~~

I tested this on both 2.8.0 and 2.8.1 and I get the same result. If I define `gather_subset: '!hardware'` explicitly in my playbook, Ansible follows it. 2.7.9 and previous releases seem to work without playbook modification.

Commit message: Fix gather facts ignoring gather_subsets config

 fixes #58728

Patch to review:
diff --git a/changelogs/fragments/gather_subset_defaults.yml b/changelogs/fragments/gather_subset_defaults.yml
new file mode 100644
index 00000000000000..7db2ef753afa42
--- /dev/null
+++ b/changelogs/fragments/gather_subset_defaults.yml
@@ -0,0 +1,2 @@
+bugfixes:
+    - Gather facts should use gather_subset config by default.
diff --git a/lib/ansible/playbook/play.py b/lib/ansible/playbook/play.py
index 2eb0c743750512..68f64db4cfab96 100644
--- a/lib/ansible/playbook/play.py
+++ b/lib/ansible/playbook/play.py
@@ -57,7 +57,7 @@ class Play(Base, Taggable, CollectionSearch):
 
     # Facts
     _gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
-    _gather_subset = FieldAttribute(isa='list', default=None, listof=string_types, always_post_validate=True)
+    _gather_subset = FieldAttribute(isa='list', default=C.DEFAULT_GATHER_SUBSET, listof=string_types, always_post_validate=True)
     _gather_timeout = FieldAttribute(isa='int', default=C.DEFAULT_GATHER_TIMEOUT, always_post_validate=True)
     _fact_path = FieldAttribute(isa='string', default=C.DEFAULT_FACT_PATH)
 


Code review comments:
diff_hunk: @@ -57,7 +57,7 @@ class Play(Base, Taggable, CollectionSearch):
 
     # Facts
     _gather_facts = FieldAttribute(isa='bool', default=None, always_post_validate=True)
-    _gather_subset = FieldAttribute(isa='list', default=None, listof=string_types, always_post_validate=True)
+    _gather_subset = FieldAttribute(isa='list', default=C.DEFAULT_GATHER_SUBSET, listof=string_types, always_post_validate=True)
path: lib/ansible/playbook/play.py
text: @user1:
How about - 

```suggestion
    _gather_subset = FieldAttribute(isa='list', default=(lambda: C.DEFAULT_GATHER_SUBSET), listof=string_types, always_post_validate=True)
```

@author:
~why?~ nvmd .. list attribute