Repository: ansible-collections/community.general

Issue:
nmap inventory plugin error: local variable 'results' referenced before assignment
### Summary

Using the nmap inventory plugin from collection version 3.x and 2.x I am getting the following error when attempting to do the inventory sync in Ansible:

```
[WARNING]:  * Failed to parse /tmp/awx_320_6c0cpe4z/project/hosts/nmap/nmap.yml
with ansible_collections.community.general.plugins.inventory.nmap plugin: local
variable 'results' referenced before assignment
```

I'm assuming the python code references the `results` variable before assignment. 

This error did not exist in the previous version of the collection (version 1.x).


### Issue Type

Bug Report

### Component Name

nmap inventory plugin

### Ansible Version

From Ansible Tower job output:

```console (paste below)
ansible-inventory 2.9.17
  config file = /tmp/awx_320_6c0cpe4z/project/ansible.cfg
  configured module search path = ['/var/lib/awx/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.6/site-packages/ansible
  executable location = /usr/bin/ansible-inventory
  python version = 3.6.8 (default, Aug 18 2020, 08:33:21) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
Using /tmp/awx_320_6c0cpe4z/project/ansible.cfg as config file
[WARNING]:  * Failed to parse /tmp/awx_320_6c0cpe4z/project/hosts/nmap/nmap.yml
with ansible_collections.community.general.plugins.inventory.nmap plugin: local
variable 'results' referenced before assignment
  File "/usr/lib/python3.6/site-packages/ansible/inventory/manager.py", line 280, in parse_source
    plugin.parse(self._inventory, self._loader, source, cache=cache)
  File "/tmp/awx_320_6c0cpe4z/requirements_collections/ansible_collections/community/general/plugins/inventory/nmap.py", line 212, in parse
    self._populate(results)
[WARNING]: Unable to parse /tmp/awx_320_6c0cpe4z/project/hosts/nmap/nmap.yml as
an inventory source
[WARNING]: Unable to parse /tmp/awx_320_6c0cpe4z/project/hosts/nmap as an
inventory source
ERROR! No inventory was parsed, please check your configuration and options.
```


### Configuration

The `nmap.yml` inventory plugin configuration.

```console (paste below)
# Inventory plugin type
plugin: community.general.nmap
# Invalid entries do not cause a fatal error and will be skipped
strict: False
# Network IP or range of IPs to scan, you can use a simple range (10.2.2.15-25) or CIDR notation.
address: 192.168.1.0/24
# list of addresses to exclude
exclude:
    - '192.168.1.0'
# Enable/disable scanning for open ports; poor performance when scanning all ports
ports: False

# At least one of ipv4 or ipv6 is required to be True, both can be True, but they cannot both be False.
# Use IPv4 type addresses
ipv4: True
# Use IPv6 type addresses
ipv6: False

# # Create vars from jinja2 expressions. (dictionary)
# compose:
#     open_ports_exist: "{{ ports | count }}"
# # Add hosts to group based on Jinja2 conditionals (dictionary)
# groups:
#     'ports_open': "{{ ports is defined }}"
# # Add hosts to group based on the values of a variable. (list)
# keyed_groups:
# - key: ports | default("none")
#   parent_group: ports
```


### OS / Environment

RHEL8 server with Ansible Tower 3.8.x and Ansible Engine 2.9.x

### Steps to Reproduce

- Create `nmap.yml` inventory plugin yaml file
- Install `nmap` locally
- Run `ansible-inventory` to test nmap inventory plugin using collection


### Expected Results

Inventory sync succeeds.

### Actual Results

Error happens (as listed above)

### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:
Files identified in the description:
* [`lib/ansible/plugins/inventory`](https://github.com/ansible-collections/community.general/blob/master/lib/ansible/plugins/inventory)

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 --->
It appears the problem started with collection v2.5.2 where there's a couple lines of code added to the end of the `nmap.py` that references the `results`. I tested with v2.5.1 and it works fine for me, but starting with v2.5.2 it's broken.
That has probably been caused by #2282.

CC @denngie

Resolving patch:
diff --git a/plugins/inventory/nmap.py b/plugins/inventory/nmap.py
--- a/plugins/inventory/nmap.py
+++ b/plugins/inventory/nmap.py
@@ -130,7 +130,7 @@ def parse(self, inventory, loader, path, cache=True):
                 # This occurs if the cache_key is not in the cache or if the cache_key expired, so the cache needs to be updated
                 cache_needs_update = True
 
-        if cache_needs_update:
+        if not user_cache_setting or cache_needs_update:
             # setup command
             cmd = [self._nmap]
             if not self._options['ports']:
@@ -207,6 +207,7 @@ def parse(self, inventory, loader, path, cache=True):
             except Exception as e:
                 raise AnsibleParserError("failed to parse %s: %s " % (to_native(path), to_native(e)))
 
+        if cache_needs_update:
             self._cache[cache_key] = results
 
         self._populate(results)


Test patch: