Repository: ansible-collections/community.general

Issue:
nmcli: Unable to create bridge slave
### Summary

Trying to create a bridge-slave (see playbook below) results in error message:
```
Error: invalid or not allowed setting 'bridge-port': 'bridge-port' not among [connection, 802-3-ethernet (ethernet), 802-1x, dcb, sriov, ethtool, match, ipv4, ipv6, hostname, tc, proxy].
```

This seems to be due to an invalid `nmcli` command. The command executed at the end of

https://github.com/ansible-collections/community.general/blob/4e90ee752ed8d9586bb0df69511b0d040a0946ff/plugins/modules/net_tools/nmcli.py#L931

is 
```
/usr/bin/nmcli con modify ens3 \
connection.interface-name ens3 \
connection.autoconnect yes \
connection.master br0 \
bridge-port.path-cost 100 \
bridge-port.hairpin-mode yes \
bridge-port.priority 32
```

which doesn't seem to be valid. Adding `slave-type bridge` does work though:

<pre><code>
/usr/bin/nmcli con modify ens3 \
connection.interface-name ens3 \
connection.autoconnect yes \
connection.master br0 \
<strong>slave-type bridge</strong> \
bridge-port.path-cost 100 \
bridge-port.hairpin-mode yes \
bridge-port.priority 32
</code></pre>

### Issue Type

Bug Report

### Component Name

nmcli

### Ansible Version

```console (paste below)
$ ansible --version
ansible 2.10.8
  config file = /home/spike/ansible/ansible.cfg
  configured module search path = ['/home/spike/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/spike/.local/lib/python3.9/site-packages/ansible
  executable location = /home/spike/.local/bin/ansible
  python version = 3.9.4 (default, Apr  6 2021, 00:00:00) [GCC 11.0.1 20210324 (Red Hat 11.0.1-0)]
```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed
ANSIBLE_PIPELINING(/home/spike/ansible/ansible.cfg) = True
DEFAULT_FORKS(/home/spike/ansible/ansible.cfg) = 4
DEFAULT_HOST_LIST(/home/spike/ansible/ansible.cfg) = ['/home/spike/ansible/inventory']
DEFAULT_REMOTE_USER(/home/spike/ansible/ansible.cfg) = root
INTERPRETER_PYTHON(/home/spike/ansible/ansible.cfg) = auto
RETRY_FILES_ENABLED(/home/spike/ansible/ansible.cfg) = False
```


### OS / Environment

Fedora 34 x86_64

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: Test creating a bridge and attaching a slave interface
  hosts: bridge_test
  gather_facts: False
  tasks:
    - name: Create bridge
      community.general.nmcli:
        type: bridge
        conn_name: br0
        ifname: br0
        state: present

    - name: Make ens3 a bridge-slave
      community.general.nmcli:
        type: bridge-slave
        master: br0
        conn_name: ens3
        ifname: ens3
        state: present
```


### Expected Results

ens3 becoming a bridge-slave of br0

### Actual Results

```console (paste below)
PLAY [Test creating a bridge and attaching a slave interface] ***************************************************************************************************************************

TASK [Create bridge] ********************************************************************************************************************************************************************
ok: [bridge_test]

TASK [Make ens3 a bridge-slave] *********************************************************************************************************************************************************
fatal: [bridge_test]: FAILED! => {"changed": false, "msg": "Error: invalid or not allowed setting 'bridge-port': 'bridge-port' not among [connection, 802-3-ethernet (ethernet), 802-1x, dcb, sriov, ethtool, match, ipv4, ipv6, hostname, tc, proxy].\n", "name": "ens3", "rc": 2}

PLAY RECAP ******************************************************************************************************************************************************************************
bridge_test                : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0
```


### Code of Conduct

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


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

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 --->
cc @alcamie101 @nerzhul
[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: notify --->

Resolving patch:
diff --git a/plugins/modules/net_tools/nmcli.py b/plugins/modules/net_tools/nmcli.py
--- a/plugins/modules/net_tools/nmcli.py
+++ b/plugins/modules/net_tools/nmcli.py
@@ -752,6 +752,7 @@ def connection_options(self, detect_change=False):
             })
         elif self.type == 'bridge-slave':
             options.update({
+                'connection.slave-type': 'bridge',
                 'bridge-port.path-cost': self.path_cost,
                 'bridge-port.hairpin-mode': self.hairpin,
                 'bridge-port.priority': self.slavepriority,


Test patch:
diff --git a/tests/unit/plugins/modules/net_tools/test_nmcli.py b/tests/unit/plugins/modules/net_tools/test_nmcli.py
--- a/tests/unit/plugins/modules/net_tools/test_nmcli.py
+++ b/tests/unit/plugins/modules/net_tools/test_nmcli.py
@@ -223,6 +223,7 @@
 connection.id:                          non_existent_nw_device
 connection.interface-name:              br0_non_existant
 connection.autoconnect:                 yes
+connection.slave-type:                  bridge
 ipv4.never-default:                     no
 bridge-port.path-cost:                  100
 bridge-port.hairpin-mode:               yes