mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
Fixing ip address without mask bug (#3784)
* change ip6 type to list of str and fix problem with setting addresses without netmask * change ip6 type to list of str and fix problem with setting addresses without netmask * Add changelog fragment * add suggestions * fix no mask using bug * Make change independed from feature branch
This commit is contained in:
parent
887b3882dc
commit
aae3ae1a8e
3 changed files with 99 additions and 10 deletions
|
@ -0,0 +1,4 @@
|
||||||
|
---
|
||||||
|
bugfixes:
|
||||||
|
- nmcli - fix returning "changed" when no mask set for IPv4 or IPv6 addresses on task rerun
|
||||||
|
(https://github.com/ansible-collections/community.general/issues/3768).
|
|
@ -70,7 +70,7 @@ options:
|
||||||
ip4:
|
ip4:
|
||||||
description:
|
description:
|
||||||
- List of IPv4 addresses to this interface.
|
- List of IPv4 addresses to this interface.
|
||||||
- Use the format C(192.0.2.24/24).
|
- Use the format C(192.0.2.24/24) or C(192.0.2.24).
|
||||||
- If defined and I(method4) is not specified, automatically set C(ipv4.method) to C(manual).
|
- If defined and I(method4) is not specified, automatically set C(ipv4.method) to C(manual).
|
||||||
type: list
|
type: list
|
||||||
elements: str
|
elements: str
|
||||||
|
@ -144,7 +144,7 @@ options:
|
||||||
ip6:
|
ip6:
|
||||||
description:
|
description:
|
||||||
- The IPv6 address to this interface.
|
- The IPv6 address to this interface.
|
||||||
- Use the format C(abbe::cafe).
|
- Use the format C(abbe::cafe/128 or abbe::cafe).
|
||||||
- If defined and I(method6) is not specified, automatically set C(ipv6.method) to C(manual).
|
- If defined and I(method6) is not specified, automatically set C(ipv6.method) to C(manual).
|
||||||
type: str
|
type: str
|
||||||
gw6:
|
gw6:
|
||||||
|
@ -1011,6 +1011,16 @@ EXAMPLES = r'''
|
||||||
- 192.0.3.100/24
|
- 192.0.3.100/24
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Add second ip6 address
|
||||||
|
community.general.nmcli:
|
||||||
|
conn_name: my-eth1
|
||||||
|
ifname: eth1
|
||||||
|
type: ethernet
|
||||||
|
ip6:
|
||||||
|
- 2001:db8::cafe
|
||||||
|
- 2002:db8::cafe
|
||||||
|
state: present
|
||||||
|
|
||||||
- name: Add VxLan
|
- name: Add VxLan
|
||||||
community.general.nmcli:
|
community.general.nmcli:
|
||||||
type: vxlan
|
type: vxlan
|
||||||
|
@ -1255,7 +1265,7 @@ class Nmcli(object):
|
||||||
# IP address options.
|
# IP address options.
|
||||||
if self.ip_conn_type and not self.master:
|
if self.ip_conn_type and not self.master:
|
||||||
options.update({
|
options.update({
|
||||||
'ipv4.addresses': self.ip4,
|
'ipv4.addresses': self.enforce_ipv4_cidr_notation(self.ip4),
|
||||||
'ipv4.dhcp-client-id': self.dhcp_client_id,
|
'ipv4.dhcp-client-id': self.dhcp_client_id,
|
||||||
'ipv4.dns': self.dns4,
|
'ipv4.dns': self.dns4,
|
||||||
'ipv4.dns-search': self.dns4_search,
|
'ipv4.dns-search': self.dns4_search,
|
||||||
|
@ -1268,7 +1278,7 @@ class Nmcli(object):
|
||||||
'ipv4.never-default': self.never_default4,
|
'ipv4.never-default': self.never_default4,
|
||||||
'ipv4.method': self.ipv4_method,
|
'ipv4.method': self.ipv4_method,
|
||||||
'ipv4.may-fail': self.may_fail4,
|
'ipv4.may-fail': self.may_fail4,
|
||||||
'ipv6.addresses': self.ip6,
|
'ipv6.addresses': self.enforce_ipv6_cidr_notation(self.ip6),
|
||||||
'ipv6.dns': self.dns6,
|
'ipv6.dns': self.dns6,
|
||||||
'ipv6.dns-search': self.dns6_search,
|
'ipv6.dns-search': self.dns6_search,
|
||||||
'ipv6.ignore-auto-dns': self.dns6_ignore_auto,
|
'ipv6.ignore-auto-dns': self.dns6_ignore_auto,
|
||||||
|
@ -1458,6 +1468,21 @@ class Nmcli(object):
|
||||||
'sit',
|
'sit',
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def enforce_ipv4_cidr_notation(ip4_addresses):
|
||||||
|
if ip4_addresses is None:
|
||||||
|
return None
|
||||||
|
return [address if '/' in address else address + '/32' for address in ip4_addresses]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def enforce_ipv6_cidr_notation(ip6_address):
|
||||||
|
if ip6_address is None:
|
||||||
|
return None
|
||||||
|
elif '/' in ip6_address:
|
||||||
|
return ip6_address
|
||||||
|
else:
|
||||||
|
return ip6_address + '/128'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def bool_to_string(boolean):
|
def bool_to_string(boolean):
|
||||||
if boolean:
|
if boolean:
|
||||||
|
|
|
@ -568,7 +568,17 @@ TESTCASE_ETHERNET_STATIC_MULTIPLE_IP4_ADDRESSES = [
|
||||||
'type': 'ethernet',
|
'type': 'ethernet',
|
||||||
'conn_name': 'non_existent_nw_device',
|
'conn_name': 'non_existent_nw_device',
|
||||||
'ifname': 'ethernet_non_existant',
|
'ifname': 'ethernet_non_existant',
|
||||||
'ip4': ['10.10.10.10/24', '10.10.20.10/24'],
|
'ip4': ['10.10.10.10/32', '10.10.20.10/32'],
|
||||||
|
'gw4': '10.10.10.1',
|
||||||
|
'dns4': ['1.1.1.1', '8.8.8.8'],
|
||||||
|
'state': 'present',
|
||||||
|
'_ansible_check_mode': False,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'type': 'ethernet',
|
||||||
|
'conn_name': 'non_existent_nw_device',
|
||||||
|
'ifname': 'ethernet_non_existant',
|
||||||
|
'ip4': ['10.10.10.10', '10.10.20.10'],
|
||||||
'gw4': '10.10.10.1',
|
'gw4': '10.10.10.1',
|
||||||
'dns4': ['1.1.1.1', '8.8.8.8'],
|
'dns4': ['1.1.1.1', '8.8.8.8'],
|
||||||
'state': 'present',
|
'state': 'present',
|
||||||
|
@ -582,7 +592,7 @@ connection.interface-name: ethernet_non_existant
|
||||||
connection.autoconnect: yes
|
connection.autoconnect: yes
|
||||||
802-3-ethernet.mtu: auto
|
802-3-ethernet.mtu: auto
|
||||||
ipv4.method: manual
|
ipv4.method: manual
|
||||||
ipv4.addresses: 10.10.10.10/24,10.10.20.10/24
|
ipv4.addresses: 10.10.10.10/32, 10.10.20.10/32
|
||||||
ipv4.gateway: 10.10.10.1
|
ipv4.gateway: 10.10.10.1
|
||||||
ipv4.ignore-auto-dns: no
|
ipv4.ignore-auto-dns: no
|
||||||
ipv4.ignore-auto-routes: no
|
ipv4.ignore-auto-routes: no
|
||||||
|
@ -594,6 +604,47 @@ ipv6.ignore-auto-dns: no
|
||||||
ipv6.ignore-auto-routes: no
|
ipv6.ignore-auto-routes: no
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
TESTCASE_ETHERNET_STATIC_IP6_ADDRESS_SHOW_OUTPUT = """\
|
||||||
|
connection.id: non_existent_nw_device
|
||||||
|
connection.interface-name: ethernet_non_existant
|
||||||
|
connection.autoconnect: yes
|
||||||
|
802-3-ethernet.mtu: auto
|
||||||
|
ipv6.method: manual
|
||||||
|
ipv6.addresses: 2001:db8::cafe/128
|
||||||
|
ipv6.gateway: 2001:db8::cafa
|
||||||
|
ipv6.ignore-auto-dns: no
|
||||||
|
ipv6.ignore-auto-routes: no
|
||||||
|
ipv6.never-default: no
|
||||||
|
ipv6.may-fail: yes
|
||||||
|
ipv6.dns: 2001:4860:4860::8888,2001:4860:4860::8844
|
||||||
|
ipv4.method: disabled
|
||||||
|
ipv4.ignore-auto-dns: no
|
||||||
|
ipv4.ignore-auto-routes: no
|
||||||
|
ipv4.never-default: no
|
||||||
|
ipv4.may-fail: yes
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
TESTCASE_ETHERNET_STATIC_MULTIPLE_IP6_ADDRESSES_SHOW_OUTPUT = """\
|
||||||
|
connection.id: non_existent_nw_device
|
||||||
|
connection.interface-name: ethernet_non_existant
|
||||||
|
connection.autoconnect: yes
|
||||||
|
802-3-ethernet.mtu: auto
|
||||||
|
ipv6.method: manual
|
||||||
|
ipv6.addresses: 2001:db8::cafe/128, 2002:db8::cafe/128
|
||||||
|
ipv6.gateway: 2001:db8::cafa
|
||||||
|
ipv6.ignore-auto-dns: no
|
||||||
|
ipv6.ignore-auto-routes: no
|
||||||
|
ipv6.never-default: no
|
||||||
|
ipv6.may-fail: yes
|
||||||
|
ipv6.dns: 2001:4860:4860::8888,2001:4860:4860::8844
|
||||||
|
ipv4.method: disabled
|
||||||
|
ipv4.ignore-auto-dns: no
|
||||||
|
ipv4.ignore-auto-routes: no
|
||||||
|
ipv4.never-default: no
|
||||||
|
ipv4.may-fail: yes
|
||||||
|
"""
|
||||||
|
|
||||||
TESTCASE_WIRELESS = [
|
TESTCASE_WIRELESS = [
|
||||||
{
|
{
|
||||||
'type': 'wifi',
|
'type': 'wifi',
|
||||||
|
@ -699,7 +750,6 @@ ipv4.ignore-auto-routes: no
|
||||||
ipv4.never-default: no
|
ipv4.never-default: no
|
||||||
ipv4.may-fail: yes
|
ipv4.may-fail: yes
|
||||||
ipv4.dns: 1.1.1.1,8.8.8.8
|
ipv4.dns: 1.1.1.1,8.8.8.8
|
||||||
ipv6.method: auto
|
|
||||||
ipv6.ignore-auto-dns: no
|
ipv6.ignore-auto-dns: no
|
||||||
ipv6.ignore-auto-routes: no
|
ipv6.ignore-auto-routes: no
|
||||||
ipv6.method: manual
|
ipv6.method: manual
|
||||||
|
@ -718,7 +768,6 @@ ipv4.ignore-auto-routes: no
|
||||||
ipv4.never-default: no
|
ipv4.never-default: no
|
||||||
ipv4.may-fail: yes
|
ipv4.may-fail: yes
|
||||||
ipv4.dns: 1.1.1.1,8.8.8.8
|
ipv4.dns: 1.1.1.1,8.8.8.8
|
||||||
ipv6.method: auto
|
|
||||||
ipv6.ignore-auto-dns: no
|
ipv6.ignore-auto-dns: no
|
||||||
ipv6.ignore-auto-routes: no
|
ipv6.ignore-auto-routes: no
|
||||||
ipv6.method: manual
|
ipv6.method: manual
|
||||||
|
@ -969,6 +1018,17 @@ def mocked_ethernet_connection_static_modify(mocker):
|
||||||
))
|
))
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def mocked_ethernet_connection_with_ipv6_address_static_modify(mocker):
|
||||||
|
mocker_set(mocker,
|
||||||
|
connection_exists=True,
|
||||||
|
execute_return=None,
|
||||||
|
execute_side_effect=(
|
||||||
|
(0, TESTCASE_ETHERNET_STATIC_IP6_ADDRESS_SHOW_OUTPUT, ""),
|
||||||
|
(0, "", ""),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def mocked_ethernet_connection_dhcp_to_static(mocker):
|
def mocked_ethernet_connection_dhcp_to_static(mocker):
|
||||||
mocker_set(mocker,
|
mocker_set(mocker,
|
||||||
|
@ -2530,7 +2590,7 @@ def test_create_ethernet_with_mulitple_ip4_addresses_static(mocked_generic_conne
|
||||||
|
|
||||||
add_args_text = list(map(to_text, add_args[0]))
|
add_args_text = list(map(to_text, add_args[0]))
|
||||||
for param in ['connection.interface-name', 'ethernet_non_existant',
|
for param in ['connection.interface-name', 'ethernet_non_existant',
|
||||||
'ipv4.addresses', '10.10.10.10/24,10.10.20.10/24',
|
'ipv4.addresses', '10.10.10.10/32,10.10.20.10/32',
|
||||||
'ipv4.gateway', '10.10.10.1',
|
'ipv4.gateway', '10.10.10.1',
|
||||||
'ipv4.dns', '1.1.1.1,8.8.8.8']:
|
'ipv4.dns', '1.1.1.1,8.8.8.8']:
|
||||||
assert param in add_args_text
|
assert param in add_args_text
|
||||||
|
@ -2578,7 +2638,7 @@ def test_add_second_ip4_address_to_ethernet_connection(mocked_ethernet_connectio
|
||||||
assert args[0][2] == 'modify'
|
assert args[0][2] == 'modify'
|
||||||
assert args[0][3] == 'non_existent_nw_device'
|
assert args[0][3] == 'non_existent_nw_device'
|
||||||
|
|
||||||
for param in ['ipv4.addresses', '10.10.10.10/24,10.10.20.10/24']:
|
for param in ['ipv4.addresses', '10.10.10.10/32,10.10.20.10/32']:
|
||||||
assert param in args[0]
|
assert param in args[0]
|
||||||
|
|
||||||
out, err = capfd.readouterr()
|
out, err = capfd.readouterr()
|
||||||
|
|
Loading…
Reference in a new issue