diff --git a/changelogs/fragments/8897-nmcli-add-reload-and-up-down.yml b/changelogs/fragments/8897-nmcli-add-reload-and-up-down.yml new file mode 100644 index 0000000000..68f481452c --- /dev/null +++ b/changelogs/fragments/8897-nmcli-add-reload-and-up-down.yml @@ -0,0 +1,3 @@ +minor_changes: + - nmcli - add ``conn_enable`` param to reload connection (https://github.com/ansible-collections/community.general/issues/3752, https://github.com/ansible-collections/community.general/issues/8704, https://github.com/ansible-collections/community.general/pull/8897). + - nmcli - add ``state=up`` and ``state=down`` to enable/disable connections (https://github.com/ansible-collections/community.general/issues/3752, https://github.com/ansible-collections/community.general/issues/8704, https://github.com/ansible-collections/community.general/issues/7152, https://github.com/ansible-collections/community.general/pull/8897). diff --git a/plugins/modules/nmcli.py b/plugins/modules/nmcli.py index e48183d049..e2803432a9 100644 --- a/plugins/modules/nmcli.py +++ b/plugins/modules/nmcli.py @@ -34,9 +34,11 @@ options: state: description: - Whether the device should exist or not, taking action if the state is different from what is stated. + - Using O(state=present) to create connection will automatically bring connection up. + - Using O(state=up) and O(state=down) will not modify connection with other parameters. These states have been added in community.general 9.5.0. type: str required: true - choices: [ absent, present ] + choices: [ absent, present, up, down ] autoconnect: description: - Whether the connection should start on boot. @@ -48,6 +50,13 @@ options: - The name used to call the connection. Pattern is [-][-]. type: str required: true + conn_reload: + description: + - Whether the connection should be reloaded if it was modified. + type: bool + required: false + default: false + version_added: 9.5.0 ifname: description: - The interface to bind the connection to. @@ -1309,6 +1318,25 @@ EXAMPLES = r''' type: ethernet state: present + - name: Change the property of a setting e.g. MTU and reload connection + community.general.nmcli: + conn_name: my-eth1 + mtu: 1500 + type: ethernet + state: present + conn_reload: true + + - name: Disable connection + community.general.nmcli: + conn_name: my-eth1 + state: down + + - name: Reload and enable connection + community.general.nmcli: + conn_name: my-eth1 + state: up + reload: true + - name: Add second ip4 address community.general.nmcli: conn_name: my-eth1 @@ -1581,6 +1609,7 @@ class Nmcli(object): self.ignore_unsupported_suboptions = module.params['ignore_unsupported_suboptions'] self.autoconnect = module.params['autoconnect'] self.conn_name = module.params['conn_name'] + self.conn_reload = module.params['conn_reload'] self.slave_type = module.params['slave_type'] self.master = module.params['master'] self.ifname = module.params['ifname'] @@ -2165,6 +2194,10 @@ class Nmcli(object): cmd = [self.nmcli_bin, 'con', 'up', self.conn_name] return self.execute_command(cmd) + def reload_connection(self): + cmd = [self.nmcli_bin, 'con', 'reload'] + return self.execute_command(cmd) + def connection_update(self, nmcli_command): if nmcli_command == 'create': cmd = [self.nmcli_bin, 'con', 'add', 'type'] @@ -2431,8 +2464,9 @@ def main(): argument_spec=dict( ignore_unsupported_suboptions=dict(type='bool', default=False), autoconnect=dict(type='bool', default=True), - state=dict(type='str', required=True, choices=['absent', 'present']), + state=dict(type='str', required=True, choices=['absent', 'present', 'up', 'down']), conn_name=dict(type='str', required=True), + conn_reload=dict(type='bool', default=False), master=dict(type='str'), slave_type=dict(type='str', choices=['bond', 'bridge', 'team', 'ovs-port']), ifname=dict(type='str'), @@ -2639,6 +2673,8 @@ def main(): if module.check_mode: module.exit_json(changed=True, **result) (rc, out, err) = nmcli.modify_connection() + if nmcli.conn_reload: + (rc, out, err) = nmcli.reload_connection() else: result['Exists'] = 'Connections already exist and no changes made' if module.check_mode: @@ -2650,6 +2686,27 @@ def main(): (rc, out, err) = nmcli.create_connection() if rc is not None and rc != 0: module.fail_json(name=nmcli.conn_name, msg=err, rc=rc) + + elif nmcli.state == 'up': + if nmcli.connection_exists(): + if module.check_mode: + module.exit_json(changed=True) + if nmcli.conn_reload: + (rc, out, err) = nmcli.reload_connection() + (rc, out, err) = nmcli.up_connection() + if rc != 0: + module.fail_json(name=('No Connection named %s exists' % nmcli.conn_name), msg=err, rc=rc) + + elif nmcli.state == 'down': + if nmcli.connection_exists(): + if module.check_mode: + module.exit_json(changed=True) + if nmcli.conn_reload: + (rc, out, err) = nmcli.reload_connection() + (rc, out, err) = nmcli.down_connection() + if rc != 0: + module.fail_json(name=('No Connection named %s exists' % nmcli.conn_name), msg=err, rc=rc) + except NmcliModuleError as e: module.fail_json(name=nmcli.conn_name, msg=str(e)) diff --git a/tests/unit/plugins/modules/test_nmcli.py b/tests/unit/plugins/modules/test_nmcli.py index 8c9c007ace..570b04d56f 100644 --- a/tests/unit/plugins/modules/test_nmcli.py +++ b/tests/unit/plugins/modules/test_nmcli.py @@ -4251,6 +4251,7 @@ def test_bond_connection_unchanged(mocked_generic_connection_diff_check, capfd): autoconnect=dict(type='bool', default=True), state=dict(type='str', required=True, choices=['absent', 'present']), conn_name=dict(type='str', required=True), + conn_reload=dict(type='bool', required=False, default=False), master=dict(type='str'), slave_type=dict(type=str, choices=['bond', 'bridge', 'team']), ifname=dict(type='str'),