Repository: ansible/ansible

Issue:
Cobbler inventory script should ignore hosts with `dns_name is None`, not just `dns_name == ''`
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
 - Bug Report

##### COMPONENT NAME
* [Cobbler Inventory Script](https://github.com/ansible/ansible/blob/devel/contrib/inventory/cobbler.py)

##### ANSIBLE VERSION
<!--- Paste verbatim output from “ansible --version” between quotes below -->
```
ansible 2.3.0.0
  config file = /etc/ansible/ansible.cfg
  configured module search path = Default w/o overrides
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
```

##### CONFIGURATION
No changes to `ansible.cfg`

##### OS / ENVIRONMENT
N/A

##### SUMMARY
The Cobbler inventory script discards hosts that have the empty string for a DNS name, but not those that fail to set the `dns_name` variable at all (ie. leave it as `None`).

##### 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.
-->
Create a system in cobbler with a single static interface and no DNS name.

```bash
sudo cobbler system add --name=test --profile=centos7-x86_64 --interface=eth0 --static=1
```

Then run cobbler.py
```
python cobbler.py
```

##### EXPECTED RESULTS
<!--- What did you expect to happen when running the steps above? -->
The host with no DNS name would also be ignored, [as claimed at the top of cobbler.py](https://github.com/ansible/ansible/blob/d3249e7875533d5d05351a19543d5fbc1c957cc9/contrib/inventory/cobbler.py#L23).

##### ACTUAL RESULTS
<!--- What actually happened? If possible run with extra verbosity (-vvvv) -->

When called implicitly as part of any ansible command, cobbler.py returns a JSON object with a `null` hostname

```
  "production": [
    "10.235.37.103", 
    null, 
    "10.235.36.109"
  ]
```

Which causes Ansible to fail when it tries to load the inventory:

```
Traceback (most recent call last):
  File "env/bin/ansible-playbook", line 109, in <module>
    exit_code = cli.run()
  File "env/lib/python2.7/site-packages/ansible/cli/playbook.py", line 128, in run
    inventory = Inventory(loader=loader, variable_manager=variable_manager, host_list=self.options.inventory)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 98, in __init__
    self.parse_inventory(host_list)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 175, in parse_inventory
    for host in self.get_hosts(ignore_limits=True, ignore_restrictions=True):
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 247, in get_hosts
    hosts = self._evaluate_patterns(patterns)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 345, in _evaluate_patterns
    that = self._match_one_pattern(p)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 398, in _match_one_pattern
    hosts = self._enumerate_matches(expr)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 489, in _enumerate_matches
    matching_hosts = self._match_list(group.get_hosts(), 'name', pattern)
  File "env/lib/python2.7/site-packages/ansible/inventory/__init__.py", line 220, in _match_list
    if pattern.match(getattr(item, item_attr)):
TypeError: expected string or buffer
```
There's [a check for `dns_name == ''`](https://github.com/ansible/ansible/blob/d3249e7875533d5d05351a19543d5fbc1c957cc9/contrib/inventory/cobbler.py#L193), but there should also be a check for `dns_name is None`



Discussion:

Resolving patch:
diff --git a/contrib/inventory/cobbler.py b/contrib/inventory/cobbler.py
--- a/contrib/inventory/cobbler.py
+++ b/contrib/inventory/cobbler.py
@@ -190,7 +190,7 @@ def update_cache(self):
                         if this_dns_name is not None and this_dns_name is not "":
                             dns_name = this_dns_name
 
-            if dns_name == '':
+            if dns_name == '' or dns_name is None:
                 continue
 
             status = host['status']


Test patch: