Repository: ansible/ansible

Issue:
reconcile_inventory needs work - grouped hosts still in 'ungrouped'
##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
reconcile_inventory

##### ANSIBLE VERSION
```
ansible-playbook 2.5.0 (devel d2cb676c4c) last updated 2017/10/25 15:40:22 (GMT +100)
  config file = /private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/ansible.cfg
  configured module search path = [u'/Users/lynchg/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/lynchg/git/github.com/ansible/ansible/lib/ansible
  executable location = /Users/lynchg/git/github.com/ansible/ansible/bin/ansible-playbook
  python version = 2.7.13 (default, Dec 18 2016, 07:03:34) [GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)]
```

##### CONFIGURATION
```
INVENTORY_ENABLED(/private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/ansible.cfg) = ['ini', 'constructed']
```

##### OS / ENVIRONMENT
MacOS

##### SUMMARY
when using keyed_groups with the constructed plugin, affected hosts aren't removed from the 'ungrouped' group

##### STEPS TO REPRODUCE
https://gist.github.com/halberom/e7791aa22c7dd1ef3f1ece3c815b4af8

##### EXPECTED RESULTS
All grouped hosts are removed from group `ungrouped`

##### ACTUAL RESULTS
No change to the group


Discussion:
Including output (with recent changes to devel)
```
ansible host5 -i hosts -i dynamic.config -m debug -a 'var=groups'
host5 | SUCCESS => {
    "changed": false,
    "groups": {
        "all": [
            "host1",
            "host2",
            "host3",
            "host4",
            "host5"
        ],
        "foo_bar": [
            "host2"
        ],
        "foo_foo": [
            "host5",
            "host3"
        ],
        "foo_none": [
            "host4",
            "host1"
        ],
        "ungrouped": [
            "host1",
            "host2",
            "host3",
            "host4",
            "host5"
        ]
    }
}
```
ANSIBLE_DEBUG=1 ansible host5 -i hosts -i dynamic.config -m debug -a 'var=groups'
```
 21608 1508943449.87683: starting run
 21608 1508943450.04356: Added group all to inventory
 21608 1508943450.04366: Added group ungrouped to inventory
 21608 1508943450.04373: Group all now contains ungrouped
 21608 1508943450.04581: Loading InventoryModule 'ini' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/inventory/ini.py
 21608 1508943450.04607: Loading InventoryModule 'constructed' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/inventory/constructed.py
 21608 1508943450.04681: Loading CacheModule 'memory' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/cache/memory.py
 21608 1508943450.04696: Examining possible inventory source: /private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/hosts
 21608 1508943450.04702: Attempting to use plugin ini (/Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/inventory/ini.py)
 21608 1508943450.04907: set inventory_file for host1
 21608 1508943450.04918: set inventory_dir for host1
 21608 1508943450.04924: Added host host1 to inventory
 21608 1508943450.04930: Added host host1 to group ungrouped
 21608 1508943450.04946: set inventory_file for host2
 21608 1508943450.04954: set inventory_dir for host2
 21608 1508943450.04958: Added host host2 to inventory
 21608 1508943450.04964: Added host host2 to group ungrouped
 21608 1508943450.04968: set foo for host2
 21608 1508943450.04981: set inventory_file for host3
 21608 1508943450.04989: set inventory_dir for host3
 21608 1508943450.04993: Added host host3 to inventory
 21608 1508943450.04998: Added host host3 to group ungrouped
 21608 1508943450.05003: set foo for host3
 21608 1508943450.05012: set inventory_file for host4
 21608 1508943450.05019: set inventory_dir for host4
 21608 1508943450.05024: Added host host4 to inventory
 21608 1508943450.05029: Added host host4 to group ungrouped
 21608 1508943450.06275: set inventory_file for host5
 21608 1508943450.06289: set inventory_dir for host5
 21608 1508943450.06296: Added host host5 to inventory
 21608 1508943450.06304: Added host host5 to group ungrouped
 21608 1508943450.06311: set foo for host5
 21608 1508943450.06321: Examining possible inventory source: /private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/dynamic.config
 21608 1508943450.06328: Attempting to use plugin ini (/Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/inventory/ini.py)
 21608 1508943450.06394: /private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/dynamic.config did not meet ini requirements
 21608 1508943450.06399: Attempting to use plugin constructed (/Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/inventory/constructed.py)
 21608 1508943450.06416: Loading data from /private/tmp/ansible/e7791aa22c7dd1ef3f1ece3c815b4af8/dynamic.config
 21608 1508943450.08051: Loading FilterModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/core.py
 21608 1508943450.09321: Loading FilterModule 'ipaddr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/ipaddr.py
 21608 1508943450.09371: Loading FilterModule 'json_query' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/json_query.py
 21608 1508943450.09403: Loading FilterModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/mathstuff.py
 21608 1508943450.09481: Loading FilterModule 'network' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/network.py
 21608 1508943450.09506: Loading FilterModule 'urlsplit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/urlsplit.py
 21608 1508943450.10066: Loading TestModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/core.py
 21608 1508943450.10126: Loading TestModule 'files' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/files.py
 21608 1508943450.10158: Loading TestModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/mathstuff.py
 21608 1508943450.10414: Added group foo_foo to inventory
 21608 1508943450.10421: Group foo_foo now contains host5
 21608 1508943450.10510: Added group foo_none to inventory
 21608 1508943450.10518: Group foo_none now contains host4
 21608 1508943450.10601: Group foo_foo now contains host3
 21608 1508943450.10680: Added group foo_bar to inventory
 21608 1508943450.10687: Group foo_bar now contains host2
 21608 1508943450.10760: Group foo_none now contains host1
 21608 1508943450.10767: Reconcile groups and hosts in inventory.
 21608 1508943450.10776: Group all now contains foo_none
 21608 1508943450.10784: Group all now contains foo_foo
 21608 1508943450.10792: Group all now contains foo_bar
 21608 1508943450.10797: Group all now contains host5
 21608 1508943450.10804: Group all now contains host4
 21608 1508943450.10811: Group all now contains host3
 21608 1508943450.10816: Group all now contains host2
 21608 1508943450.10823: Group all now contains host1
 21608 1508943450.10835: Loading CacheModule 'memory' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/cache/memory.py (found_in_cache=True, class_only=False)
 21608 1508943450.18920: Loading CallbackModule 'minimal' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/minimal.py
 21608 1508943450.19140: assigned :doc
 21608 1508943450.19216: Loading CallbackModule 'actionable' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/actionable.py (found_in_cache=False, class_only=True)
 21608 1508943450.19531: assigned :doc
 21608 1508943450.19566: Loading CallbackModule 'context_demo' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/context_demo.py (found_in_cache=False, class_only=True)
 21608 1508943450.19742: assigned :doc
 21608 1508943450.19775: Loading CallbackModule 'debug' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/debug.py (found_in_cache=False, class_only=True)
 21608 1508943450.19955: assigned :doc
 21608 1508943450.19966: Loading CallbackModule 'default' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/default.py (found_in_cache=False, class_only=True)
 21608 1508943450.20435: assigned :doc
 21608 1508943450.20522: Loading CallbackModule 'dense' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/dense.py (found_in_cache=False, class_only=True)
 21608 1508943450.20960: assigned :doc
 21608 1508943450.21026: Loading CallbackModule 'foreman' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/foreman.py (found_in_cache=False, class_only=True)
 21608 1508943450.21709: assigned :doc
 21608 1508943450.21729: Loaded config def from plugin (callback/foreman)
 21608 1508943450.21757: Loading CallbackModule 'full_skip' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/full_skip.py (found_in_cache=False, class_only=True)
 21608 1508943450.21954: assigned :doc
 21608 1508943450.22905: Loading CallbackModule 'hipchat' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/hipchat.py (found_in_cache=False, class_only=True)
 21608 1508943450.23600: assigned :doc
 21608 1508943450.23620: Loaded config def from plugin (callback/hipchat)
 21608 1508943450.23670: Loading CallbackModule 'jabber' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/jabber.py (found_in_cache=False, class_only=True)
 21608 1508943450.24300: assigned :doc
 21608 1508943450.24313: Loaded config def from plugin (callback/jabber)
 21608 1508943450.24341: Loading CallbackModule 'json' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/json.py (found_in_cache=False, class_only=True)
 21608 1508943450.24506: assigned :doc
 21608 1508943450.24560: Loading CallbackModule 'junit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/junit.py (found_in_cache=False, class_only=True)
 21608 1508943450.25198: assigned :doc
 21608 1508943450.25219: Loaded config def from plugin (callback/junit)
 21608 1508943450.25251: Loading CallbackModule 'log_plays' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/log_plays.py (found_in_cache=False, class_only=True)
 21608 1508943450.25464: assigned :doc
 21608 1508943450.25533: Loading CallbackModule 'logentries' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/logentries.py (found_in_cache=False, class_only=True)
 21608 1508943450.26776: assigned :doc
 21608 1508943450.26785: assigned :plainexamples
 21608 1508943450.26812: Loaded config def from plugin (callback/logentries)
 21608 1508943450.26858: Loading CallbackModule 'logstash' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/logstash.py (found_in_cache=False, class_only=True)
 21608 1508943450.27397: assigned :doc
 21608 1508943450.27430: Loaded config def from plugin (callback/logstash)
 21608 1508943450.27539: Loading CallbackModule 'mail' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/mail.py (found_in_cache=False, class_only=True)
 21608 1508943450.27923: assigned :doc
 21608 1508943450.27941: Loaded config def from plugin (callback/mail)
 21608 1508943450.27949: Loading CallbackModule 'minimal' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/minimal.py (found_in_cache=False, class_only=True)
 21608 1508943450.28111: assigned :doc
 21608 1508943450.28139: Loading CallbackModule 'oneline' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/oneline.py (found_in_cache=False, class_only=True)
 21608 1508943450.28312: assigned :doc
 21608 1508943450.28341: Loading CallbackModule 'osx_say' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/osx_say.py (found_in_cache=False, class_only=True)
 21608 1508943450.28611: assigned :doc
 21608 1508943450.28649: Loading CallbackModule 'profile_roles' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/profile_roles.py (found_in_cache=False, class_only=True)
 21608 1508943450.28910: assigned :doc
 21608 1508943450.28967: Loading CallbackModule 'profile_tasks' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/profile_tasks.py (found_in_cache=False, class_only=True)
 21608 1508943450.29742: assigned :doc
 21608 1508943450.29749: assigned :plainexamples
 21608 1508943450.29763: Loaded config def from plugin (callback/profile_tasks)
 21608 1508943450.29794: Loading CallbackModule 'selective' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/selective.py (found_in_cache=False, class_only=True)
 21608 1508943450.30340: assigned :doc
 21608 1508943450.30347: assigned :plainexamples
 21608 1508943450.30366: Loaded config def from plugin (callback/selective)
 21608 1508943450.30399: Loading CallbackModule 'skippy' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/skippy.py (found_in_cache=False, class_only=True)
 21608 1508943450.30598: assigned :doc
 21608 1508943450.30647: Loading CallbackModule 'slack' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/slack.py (found_in_cache=False, class_only=True)
 21608 1508943450.31305: assigned :doc
 21608 1508943450.31321: Loaded config def from plugin (callback/slack)
 21608 1508943450.31351: Loading CallbackModule 'stderr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/stderr.py (found_in_cache=False, class_only=True)
 21608 1508943450.31602: assigned :doc
 21608 1508943450.31696: Loading CallbackModule 'syslog_json' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/syslog_json.py (found_in_cache=False, class_only=True)
 21608 1508943450.32285: assigned :doc
 21608 1508943450.32295: Loaded config def from plugin (callback/syslog_json)
 21608 1508943450.32326: Loading CallbackModule 'timer' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/timer.py (found_in_cache=False, class_only=True)
 21608 1508943450.32478: assigned :doc
 21608 1508943450.32512: Loading CallbackModule 'tree' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/tree.py (found_in_cache=False, class_only=True)
 21608 1508943450.32709: assigned :doc
 21608 1508943450.32748: Loading CallbackModule 'unixy' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/callback/unixy.py (found_in_cache=False, class_only=True)
 21608 1508943450.33054: assigned :doc
 21608 1508943450.33074: in VariableManager get_vars()
 21608 1508943450.33167: Loading FilterModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/core.py (found_in_cache=True, class_only=False)
 21608 1508943450.33174: Loading FilterModule 'ipaddr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/ipaddr.py (found_in_cache=True, class_only=False)
 21608 1508943450.33180: Loading FilterModule 'json_query' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/json_query.py (found_in_cache=True, class_only=False)
 21608 1508943450.33186: Loading FilterModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/mathstuff.py (found_in_cache=True, class_only=False)
 21608 1508943450.33193: Loading FilterModule 'network' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/network.py (found_in_cache=True, class_only=False)
 21608 1508943450.33200: Loading FilterModule 'urlsplit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/urlsplit.py (found_in_cache=True, class_only=False)
 21608 1508943450.33223: Loading TestModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/core.py (found_in_cache=True, class_only=False)
 21608 1508943450.33229: Loading TestModule 'files' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/files.py (found_in_cache=True, class_only=False)
 21608 1508943450.33234: Loading TestModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/mathstuff.py (found_in_cache=True, class_only=False)
 21608 1508943450.33292: done with get_vars()
 21608 1508943450.33920: Loading StrategyModule 'linear' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/strategy/linear.py
 21608 1508943450.34060: getting the remaining hosts for this loop
 21608 1508943450.34071: done getting the remaining hosts for this loop
 21608 1508943450.34077: building list of next tasks for hosts
 21608 1508943450.34083: getting the next task for host host5
 21608 1508943450.34089: done getting next task for host host5
 21608 1508943450.34096:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.34101:  ^ state is: HOST STATE: block=1, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.34106: done building task lists
 21608 1508943450.34110: counting tasks in each state of execution
 21608 1508943450.34115: done counting tasks in each state of execution:
	num_setups: 0
	num_tasks: 1
	num_rescue: 0
	num_always: 0
 21608 1508943450.34119: advancing hosts in ITERATING_TASKS
 21608 1508943450.34123: starting to advance hosts
 21608 1508943450.34127: getting the next task for host host5
 21608 1508943450.34132: done getting next task for host host5
 21608 1508943450.34136:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.35267:  ^ state is: HOST STATE: block=1, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.35275: done advancing hosts to next task
 21608 1508943450.35287: done queuing things up, now waiting for results queue to drain
 21608 1508943450.35295: results queue empty
 21608 1508943450.35299: checking for any_errors_fatal
 21608 1508943450.35305: done checking for any_errors_fatal
 21608 1508943450.35309: checking for max_fail_percentage
 21608 1508943450.35313: done checking for max_fail_percentage
 21608 1508943450.35317: checking to see if all hosts have failed and the running result is not ok
 21608 1508943450.35320: done checking to see if all hosts have failed
 21608 1508943450.35324: getting the remaining hosts for this loop
 21608 1508943450.35329: done getting the remaining hosts for this loop
 21608 1508943450.35334: building list of next tasks for hosts
 21608 1508943450.35338: getting the next task for host host5
 21608 1508943450.35345: done getting next task for host host5
 21608 1508943450.35351:  ^ task is: TASK: debug
 21608 1508943450.35356:  ^ state is: HOST STATE: block=2, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.35360: done building task lists
 21608 1508943450.35364: counting tasks in each state of execution
 21608 1508943450.35369: done counting tasks in each state of execution:
	num_setups: 0
	num_tasks: 1
	num_rescue: 0
	num_always: 0
 21608 1508943450.35374: advancing hosts in ITERATING_TASKS
 21608 1508943450.35378: starting to advance hosts
 21608 1508943450.35382: getting the next task for host host5
 21608 1508943450.35388: done getting next task for host host5
 21608 1508943450.35396:  ^ task is: TASK: debug
 21608 1508943450.35409:  ^ state is: HOST STATE: block=2, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.35423: done advancing hosts to next task
 21608 1508943450.35462: Loading ActionModule 'debug' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/action/debug.py (found_in_cache=False, class_only=True)
 21608 1508943450.35471: getting variables
 21608 1508943450.35476: in VariableManager get_vars()
 21608 1508943450.35508: Loading FilterModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/core.py (found_in_cache=True, class_only=False)
 21608 1508943450.35516: Loading FilterModule 'ipaddr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/ipaddr.py (found_in_cache=True, class_only=False)
 21608 1508943450.35522: Loading FilterModule 'json_query' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/json_query.py (found_in_cache=True, class_only=False)
 21608 1508943450.35528: Loading FilterModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/mathstuff.py (found_in_cache=True, class_only=False)
 21608 1508943450.35543: Loading FilterModule 'network' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/network.py (found_in_cache=True, class_only=False)
 21608 1508943450.35552: Loading FilterModule 'urlsplit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/urlsplit.py (found_in_cache=True, class_only=False)
 21608 1508943450.35579: Loading TestModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/core.py (found_in_cache=True, class_only=False)
 21608 1508943450.35589: Loading TestModule 'files' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/files.py (found_in_cache=True, class_only=False)
 21608 1508943450.35597: Loading TestModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/mathstuff.py (found_in_cache=True, class_only=False)
 21608 1508943450.35712: Calling all_inventory to load vars for host5
 21608 1508943450.35723: Calling groups_inventory to load vars for host5
 21608 1508943450.35733: Calling all_plugins_inventory to load vars for host5
 21608 1508943450.35823: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py
 21608 1508943450.35849: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.35864: Calling all_plugins_play to load vars for host5
 21608 1508943450.35879: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.35894: Calling groups_plugins_inventory to load vars for host5
 21608 1508943450.35910: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.35933: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.35947: Calling groups_plugins_play to load vars for host5
 21608 1508943450.35965: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.35994: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.36017: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.36040: Loading VarsModule 'host_group_vars' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/vars/host_group_vars.py (found_in_cache=True, class_only=False)
 21608 1508943450.36065: done with get_vars()
 21608 1508943450.36077: done getting variables
 21608 1508943450.36085: sending task start callback, copying the task so we can template it temporarily
 21608 1508943450.36090: done copying, going to template now
 21608 1508943450.36095: done templating
 21608 1508943450.36100: here goes the callback...
 21608 1508943450.36105: sending task start callback
 21608 1508943450.36110: entering _queue_task() for host5/debug
 21608 1508943450.36115: Creating lock for debug
 21608 1508943450.36250: worker is 1 (out of 1 available)
 21608 1508943450.36300: exiting _queue_task() for host5/debug
 21608 1508943450.36322: done queuing things up, now waiting for results queue to drain
 21608 1508943450.36329: waiting for pending results...
 21613 1508943450.36708: running TaskExecutor() for host5/TASK: debug
 21613 1508943450.36781: in run() - task a0999b15-adf7-1b07-0c60-00000000000d
 21613 1508943450.38905: calling self._execute()
 21613 1508943450.39685: Loading Connection 'ssh' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/connection/ssh.py
 21613 1508943450.39763: Loading ShellModule 'csh' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/shell/csh.py
 21613 1508943450.39835: Loading ShellModule 'fish' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/shell/fish.py
 21613 1508943450.39846: Loading ShellModule 'powershell' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/shell/powershell.py
 21613 1508943450.39854: Loading ShellModule 'sh' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/shell/sh.py
 21613 1508943450.39880: Loading ShellModule 'sh' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/shell/sh.py (found_in_cache=True, class_only=False)
 21613 1508943450.44040: assigned :doc
 21613 1508943450.44122: Loaded config def from plugin (connection/ssh)
 21613 1508943450.44139: Loading ActionModule 'debug' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/action/debug.py (found_in_cache=True, class_only=False)
 21613 1508943450.44152: starting attempt loop
 21613 1508943450.44158: running the handler
 21613 1508943450.44228: Loading FilterModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/core.py (found_in_cache=True, class_only=False)
 21613 1508943450.44236: Loading FilterModule 'ipaddr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/ipaddr.py (found_in_cache=True, class_only=False)
 21613 1508943450.44244: Loading FilterModule 'json_query' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/json_query.py (found_in_cache=True, class_only=False)
 21613 1508943450.44254: Loading FilterModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/mathstuff.py (found_in_cache=True, class_only=False)
 21613 1508943450.44262: Loading FilterModule 'network' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/network.py (found_in_cache=True, class_only=False)
 21613 1508943450.44269: Loading FilterModule 'urlsplit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/urlsplit.py (found_in_cache=True, class_only=False)
 21613 1508943450.44299: Loading TestModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/core.py (found_in_cache=True, class_only=False)
 21613 1508943450.44306: Loading TestModule 'files' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/files.py (found_in_cache=True, class_only=False)
 21613 1508943450.44313: Loading TestModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/mathstuff.py (found_in_cache=True, class_only=False)
 21613 1508943450.44485: Loading FilterModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/core.py (found_in_cache=True, class_only=False)
 21613 1508943450.44493: Loading FilterModule 'ipaddr' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/ipaddr.py (found_in_cache=True, class_only=False)
 21613 1508943450.44500: Loading FilterModule 'json_query' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/json_query.py (found_in_cache=True, class_only=False)
 21613 1508943450.44506: Loading FilterModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/mathstuff.py (found_in_cache=True, class_only=False)
 21613 1508943450.44513: Loading FilterModule 'network' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/network.py (found_in_cache=True, class_only=False)
 21613 1508943450.44520: Loading FilterModule 'urlsplit' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/filter/urlsplit.py (found_in_cache=True, class_only=False)
 21613 1508943450.44538: Loading TestModule 'core' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/core.py (found_in_cache=True, class_only=False)
 21613 1508943450.44545: Loading TestModule 'files' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/files.py (found_in_cache=True, class_only=False)
 21613 1508943450.44551: Loading TestModule 'mathstuff' from /Users/lynchg/git/github.com/ansible/ansible/lib/ansible/plugins/test/mathstuff.py (found_in_cache=True, class_only=False)
 21613 1508943450.44592: handler run complete
 21613 1508943450.44604: attempt loop complete, returning result
 21613 1508943450.44609: _execute() done
 21613 1508943450.44615: dumping result to json
 21613 1508943450.44625: done dumping result, returning
 21613 1508943450.44633: done running TaskExecutor() for host5/TASK: debug [a0999b15-adf7-1b07-0c60-00000000000d]
 21613 1508943450.44651: sending task result for task a0999b15-adf7-1b07-0c60-00000000000d
 21613 1508943450.44689: done sending task result for task a0999b15-adf7-1b07-0c60-00000000000d
 21613 1508943450.44697: WORKER PROCESS EXITING
host5 | SUCCESS => {
    "changed": false,
    "groups": {
        "all": [
            "host1",
            "host2",
            "host3",
            "host4",
            "host5"
        ],
        "foo_bar": [
            "host2"
        ],
        "foo_foo": [
            "host5",
            "host3"
        ],
        "foo_none": [
            "host4",
            "host1"
        ],
        "ungrouped": [
            "host1",
            "host2",
            "host3",
            "host4",
            "host5"
        ]
    }
}
 21608 1508943450.45060: no more pending results, returning what we have
 21608 1508943450.45068: results queue empty
 21608 1508943450.45073: checking for any_errors_fatal
 21608 1508943450.45077: done checking for any_errors_fatal
 21608 1508943450.45082: checking for max_fail_percentage
 21608 1508943450.45087: done checking for max_fail_percentage
 21608 1508943450.45091: checking to see if all hosts have failed and the running result is not ok
 21608 1508943450.45097: done checking to see if all hosts have failed
 21608 1508943450.45101: getting the remaining hosts for this loop
 21608 1508943450.45110: done getting the remaining hosts for this loop
 21608 1508943450.45121: building list of next tasks for hosts
 21608 1508943450.45128: getting the next task for host host5
 21608 1508943450.45138: done getting next task for host host5
 21608 1508943450.45145:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.45153:  ^ state is: HOST STATE: block=3, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45160: done building task lists
 21608 1508943450.45164: counting tasks in each state of execution
 21608 1508943450.45169: done counting tasks in each state of execution:
	num_setups: 0
	num_tasks: 1
	num_rescue: 0
	num_always: 0
 21608 1508943450.45175: advancing hosts in ITERATING_TASKS
 21608 1508943450.45180: starting to advance hosts
 21608 1508943450.45186: getting the next task for host host5
 21608 1508943450.45193: done getting next task for host host5
 21608 1508943450.45197:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.45202:  ^ state is: HOST STATE: block=3, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45209: done advancing hosts to next task
 21608 1508943450.45235: done queuing things up, now waiting for results queue to drain
 21608 1508943450.45241: results queue empty
 21608 1508943450.45245: checking for any_errors_fatal
 21608 1508943450.45250: done checking for any_errors_fatal
 21608 1508943450.45254: checking for max_fail_percentage
 21608 1508943450.45257: done checking for max_fail_percentage
 21608 1508943450.45261: checking to see if all hosts have failed and the running result is not ok
 21608 1508943450.45265: done checking to see if all hosts have failed
 21608 1508943450.45269: getting the remaining hosts for this loop
 21608 1508943450.45273: done getting the remaining hosts for this loop
 21608 1508943450.45278: building list of next tasks for hosts
 21608 1508943450.45282: getting the next task for host host5
 21608 1508943450.45287: done getting next task for host host5
 21608 1508943450.45292:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.45297:  ^ state is: HOST STATE: block=4, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45301: done building task lists
 21608 1508943450.45305: counting tasks in each state of execution
 21608 1508943450.45309: done counting tasks in each state of execution:
	num_setups: 0
	num_tasks: 1
	num_rescue: 0
	num_always: 0
 21608 1508943450.45314: advancing hosts in ITERATING_TASKS
 21608 1508943450.45319: starting to advance hosts
 21608 1508943450.45323: getting the next task for host host5
 21608 1508943450.45329: done getting next task for host host5
 21608 1508943450.45334:  ^ task is: TASK: meta (flush_handlers)
 21608 1508943450.45339:  ^ state is: HOST STATE: block=4, task=1, rescue=0, always=0, run_state=ITERATING_TASKS, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45344: done advancing hosts to next task
 21608 1508943450.45353: done queuing things up, now waiting for results queue to drain
 21608 1508943450.45361: results queue empty
 21608 1508943450.45365: checking for any_errors_fatal
 21608 1508943450.45370: done checking for any_errors_fatal
 21608 1508943450.45375: checking for max_fail_percentage
 21608 1508943450.45380: done checking for max_fail_percentage
 21608 1508943450.45384: checking to see if all hosts have failed and the running result is not ok
 21608 1508943450.45387: done checking to see if all hosts have failed
 21608 1508943450.45391: getting the remaining hosts for this loop
 21608 1508943450.45397: done getting the remaining hosts for this loop
 21608 1508943450.45402: building list of next tasks for hosts
 21608 1508943450.45406: getting the next task for host host5
 21608 1508943450.45412: done getting next task for host host5
 21608 1508943450.45416:  ^ task is: None
 21608 1508943450.45421:  ^ state is: HOST STATE: block=5, task=0, rescue=0, always=0, run_state=ITERATING_COMPLETE, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45425: done building task lists
 21608 1508943450.45429: counting tasks in each state of execution
 21608 1508943450.45433: done counting tasks in each state of execution:
	num_setups: 0
	num_tasks: 0
	num_rescue: 0
	num_always: 0
 21608 1508943450.45438: all hosts are done, so returning None's for all hosts
 21608 1508943450.45442: done queuing things up, now waiting for results queue to drain
 21608 1508943450.45446: results queue empty
 21608 1508943450.45450: checking for any_errors_fatal
 21608 1508943450.45454: done checking for any_errors_fatal
 21608 1508943450.45458: checking for max_fail_percentage
 21608 1508943450.45461: done checking for max_fail_percentage
 21608 1508943450.45465: checking to see if all hosts have failed and the running result is not ok
 21608 1508943450.45469: done checking to see if all hosts have failed
 21608 1508943450.45473: getting the next task for host host5
 21608 1508943450.45479: done getting next task for host host5
 21608 1508943450.45483:  ^ task is: None
 21608 1508943450.45487:  ^ state is: HOST STATE: block=5, task=0, rescue=0, always=0, run_state=ITERATING_COMPLETE, fail_state=FAILED_NONE, pending_setup=False, tasks child state? (None), rescue child state? (None), always child state? (None), did rescue? False, did start at task? False
 21608 1508943450.45492: running handlers
 21608 1508943450.45565: RUNNING CLEANUP
```
not an issue with reconcile, but constructed not adding the hosts correctly to group
It works if I change https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/data.py#L124
from
```
                if set(mygroups).difference(set([self.groups['all'], self.groups['ungrouped']])):
```
to
```
                if set(mygroups).difference([self.groups['all'], self.groups['ungrouped']]):
```
No, ignore me... it works in pdb, but not in the actual end result.

Resolving patch:
diff --git a/lib/ansible/inventory/data.py b/lib/ansible/inventory/data.py
--- a/lib/ansible/inventory/data.py
+++ b/lib/ansible/inventory/data.py
@@ -128,7 +128,7 @@ def reconcile_inventory(self):
             if self.groups['ungrouped'] in mygroups:
                 # clear ungrouped of any incorrectly stored by parser
                 if set(mygroups).difference(set([self.groups['all'], self.groups['ungrouped']])):
-                    host.remove_group(self.groups['ungrouped'])
+                    self.groups['ungrouped'].remove_host(host)
 
             elif not host.implicit:
                 # add ungrouped hosts to ungrouped, except implicit


Test patch:
diff --git a/test/units/plugins/inventory/test_inventory.py b/test/units/plugins/inventory/test_inventory.py
--- a/test/units/plugins/inventory/test_inventory.py
+++ b/test/units/plugins/inventory/test_inventory.py
@@ -198,6 +198,6 @@ def _test_default_groups(self, inventory_content):
         all_hosts = set(host.name for host in inventory.groups['all'].get_hosts())
         self.assertEqual(set(['host1', 'host2', 'host3', 'host4', 'host5']), all_hosts)
         ungrouped_hosts = set(host.name for host in inventory.groups['ungrouped'].get_hosts())
-        self.assertEqual(set(['host1', 'host2', 'host3']), ungrouped_hosts)
+        self.assertEqual(set(['host1', 'host2']), ungrouped_hosts)
         servers_hosts = set(host.name for host in inventory.groups['servers'].get_hosts())
         self.assertEqual(set(['host3', 'host4', 'host5']), servers_hosts)