feat: Support ipv4_ignore_auto_dns and ipv6_ignore_auto_dns settings

reason: The user wants to ignore automatically configured name servers and
search domains (e.g. dns record from DHCP), and only use the name
servers and search domains specified in the `dns` and `dns_search`
properties.

result: The user is able to ignore automatically configured name servers
and search domains.

Notice that there are two settings here distinguished by the address
families, which aims to be compatible with NetworkManager
(`ipv4.ignore-auto-dns` and `ipv6.ignore-auto-dns`)and Nmstate (setting
`auto-dns` on `ipv4` or `ipv6` section). Also, the users can get auto
DNS from DHCPv4, DHCPv6, modem etc, and they may want to ignore auto
DNS on Ipv4 but not on IPv6, in this case, it is better to have two
settings distinguished by the address families.

Signed-off-by: Wen Liang <liangwen12year@gmail.com>
This commit is contained in:
Wen Liang 2023-04-23 17:06:09 -04:00 committed by Fernando Fernández Mancera
parent 2ce6f3afa7
commit ffe01a5f8b
8 changed files with 258 additions and 0 deletions

View file

@ -540,6 +540,17 @@ The IP configuration supports the following options:
The default gateway for IPv4 (`gateway4`) or IPv6 (`gateway6`) packets.
- `ipv4_ignore_auto_dns` and `ipv6_ignore_auto_dns`
If enabled, the automatically configured name servers and search domains (via
DHCPv4, DHCPv6, modem etc) for IPv4 or IPv6 are ignored, only the name servers and
search domains specified in `dns` and `dns_search` properties are used. The
settings are distinguished by the address families. The variables are not supported
by initscripts provider.
If the variables are not specified, the role will use the default behavior of nm
provider.
- `route_metric4` and `route_metric6`
For `NetworkManager`, `route_metric4` and `route_metric6` corresponds to the

View file

@ -0,0 +1,24 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- name: Test ipv4_ignore_auto_dns and ipv6_ignore_auto_dns settings
hosts: all
tasks:
- name: Test configuring ipv4_ignore_auto_dns and ipv6_ignore_auto_dns
settings for an interface
block:
- name: Configure an interface with ipv4_ignore_auto_dns disabled and
ipv6_ignore_auto_dns enabled
import_role:
name: linux-system-roles.network
vars:
network_connections:
- name: eth0
state: up
type: ethernet
autoconnect: false
ip:
ipv4_ignore_auto_dns: false
ipv6_ignore_auto_dns: true
auto6: true
address:
- 198.51.100.3/24

View file

@ -1173,6 +1173,13 @@ class NMUtil:
s_ip6.set_property(NM.SETTING_IP_CONFIG_NEVER_DEFAULT, True)
s_ip4.set_property(NM.SETTING_IP_CONFIG_NEVER_DEFAULT, True)
s_ip4.set_property(
NM.SETTING_IP_CONFIG_IGNORE_AUTO_DNS, bool(ip["ipv4_ignore_auto_dns"])
)
s_ip6.set_property(
NM.SETTING_IP_CONFIG_IGNORE_AUTO_DNS, bool(ip["ipv6_ignore_auto_dns"])
)
for nameserver in ip["dns"]:
if nameserver["family"] == socket.AF_INET6:
s_ip6.add_dns(nameserver["address"])

View file

@ -867,6 +867,8 @@ class ArgValidator_DictIP(ArgValidatorDict):
"route_metric4", val_min=-1, val_max=UINT32_MAX, default_value=None
),
ArgValidatorBool("auto6", default_value=None),
ArgValidatorBool("ipv4_ignore_auto_dns", default_value=None),
ArgValidatorBool("ipv6_ignore_auto_dns", default_value=None),
ArgValidatorBool("ipv6_disabled", default_value=None),
ArgValidatorIP("gateway6", family=socket.AF_INET6),
ArgValidatorNum(
@ -918,6 +920,8 @@ class ArgValidator_DictIP(ArgValidatorDict):
"gateway4": None,
"route_metric4": None,
"auto6": True,
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"ipv6_disabled": False,
"gateway6": None,
"route_metric6": None,
@ -2461,6 +2465,19 @@ class ArgValidator_ListConnections(ArgValidatorList):
"if you need to use initscripts.",
)
# initscripts does not support ip.ipv4_ignore_auto_dns or
# ip.ipv6_ignore_auto_dns, so raise errors when network
# provider is initscripts
if (
connection["ip"]["ipv4_ignore_auto_dns"] is not None
or connection["ip"]["ipv6_ignore_auto_dns"] is not None
):
if mode == self.VALIDATE_ONE_MODE_INITSCRIPTS:
raise ValidationError.from_connection(
idx,
"ip.ipv4_ignore_auto_dns or ip.ipv6_ignore_auto_dns is not "
"supported by initscripts.",
)
# initscripts does not support ip.dns_options, so raise errors when network
# provider is initscripts
if connection["ip"]["dns_options"]:

View file

@ -76,6 +76,7 @@ ibution_major_version | int < 9",
EXTRA_RUN_CONDITION: "ansible_distribution != 'RedHat' or\n ansible_distr\
ibution_major_version | int < 9",
},
"playbooks/tests_ignore_auto_dns.yml": {},
"playbooks/tests_bond_options.yml": {},
"playbooks/tests_eth_dns_support.yml": {},
"playbooks/tests_dummy.yml": {}, # wokeignore:rule=dummy

View file

@ -0,0 +1,82 @@
# SPDX-License-Identifier: BSD-3-Clause
---
- name: Test ipv4_ignore_auto_dns and ipv6_ignore_auto_dns settings
hosts: all
vars:
type: veth
interface: ethtest0
tasks:
- name: Include the task 'show_interfaces.yml'
include_tasks: tasks/show_interfaces.yml
- name: Include the task 'manage_test_interface.yml'
include_tasks: tasks/manage_test_interface.yml
vars:
state: present
- name: Include the task 'assert_device_present.yml'
include_tasks: tasks/assert_device_present.yml
- name: Test configuring ipv4_ignore_auto_dns and ipv6_ignore_auto_dns
settings for an interface
block:
- name: Configure an interface with ipv4_ignore_auto_dns disabled and
ipv6_ignore_auto_dns enabled
import_role:
name: linux-system-roles.network
vars:
network_connections:
- name: "{{ interface }}"
interface_name: "{{ interface }}"
state: up
type: ethernet
autoconnect: false
ip:
ipv4_ignore_auto_dns: false
ipv6_ignore_auto_dns: true
auto6: true
address:
- 198.51.100.3/24
- name: Get the nmcli ipv4.ignore-auto-dns setting
command: nmcli -f ipv4.ignore-auto-dns c show {{ interface }}
register: ipv4_ignore_auto_dns
changed_when: false
- name: Get the nmcli ipv6.ignore-auto-dns setting
command: nmcli -f ipv6.ignore-auto-dns c show {{ interface }}
register: ipv6_ignore_auto_dns
changed_when: false
- name: Assert that the setting ipv4.ignore-auto-dns is 'no'
assert:
that:
- "'no' in ipv4_ignore_auto_dns.stdout"
msg: "the setting ipv4.ignore-auto-dns is 'yes'"
- name: Assert that the setting ipv6.ignore-auto-dns is 'yes'
assert:
that:
- "'yes' in ipv6_ignore_auto_dns.stdout"
msg: "the setting ipv6.ignore-auto-dns is 'no'"
always:
- name: Remove test configuration
tags:
- "tests::cleanup"
block:
- name: Bring down test devices and profiles
include_role:
name: linux-system-roles.network
vars:
network_connections:
- name: "{{ interface }}"
persistent_state: absent
state: down
- name: Delete interface - '{{ interface }}'
include_tasks: tasks/delete_interface.yml
- name: Include the task 'assert_device_absent.yml'
include_tasks: tasks/assert_device_absent.yml
- name: Include the task 'assert_profile_absent.yml'
include_tasks: tasks/assert_profile_absent.yml
vars:
profile: "{{ interface }}"
...

View file

@ -0,0 +1,23 @@
# SPDX-License-Identifier: BSD-3-Clause
# This file was generated by ensure_provider_tests.py
---
# set network provider and gather facts
- hosts: all
# yamllint disable rule:line-length
name: Run playbook 'playbooks/tests_ignore_auto_dns.yml' with nm as provider
tasks:
- name: Include the task 'el_repo_setup.yml'
include_tasks: tasks/el_repo_setup.yml
- name: Set network provider to 'nm'
set_fact:
network_provider: nm
tags:
- always
# The test requires or should run with NetworkManager, therefore it cannot run
# on RHEL/CentOS 6
- name: Import the playbook 'playbooks/tests_ignore_auto_dns.yml'
import_playbook: playbooks/tests_ignore_auto_dns.yml
when:
- ansible_distribution_major_version != '6'

View file

@ -189,6 +189,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -586,6 +588,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -645,6 +649,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -698,6 +704,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -801,6 +809,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.174.5",
}
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -870,6 +880,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.174.5",
}
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -942,6 +954,8 @@ class TestValidator(Python26CompatTestCase):
"prefix": 32,
},
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1040,6 +1054,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.177.5",
},
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1105,6 +1121,8 @@ class TestValidator(Python26CompatTestCase):
"address": "a:b:c::6",
},
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1193,6 +1211,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dns": [],
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": True,
"route_append_only": False,
"rule_append_only": False,
@ -1272,6 +1292,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dns": [],
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": False,
"route_append_only": False,
"rule_append_only": False,
@ -1371,6 +1393,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.177.5",
},
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1437,6 +1461,8 @@ class TestValidator(Python26CompatTestCase):
"address": "a:b:c::6",
},
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1522,6 +1548,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.122.3",
}
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1582,6 +1610,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.244.1",
}
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1642,6 +1672,8 @@ class TestValidator(Python26CompatTestCase):
"address": "192.168.245.7",
}
],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1733,6 +1765,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": "bridge2",
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": False,
"dhcp4": False,
@ -1778,6 +1812,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": "eth1",
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4": True,
@ -1886,6 +1922,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dns": [],
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -1967,6 +2005,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dns": [],
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -2019,6 +2059,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": None,
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -2077,6 +2119,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -2151,6 +2195,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": "6643-controller",
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"ipv6_disabled": False,
@ -2196,6 +2242,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": "6643",
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4_send_hostname": None,
@ -2257,6 +2305,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": None,
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4": True,
@ -2335,6 +2385,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": None,
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4": True,
@ -2419,6 +2471,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": "ib0",
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4": True,
@ -2463,6 +2517,8 @@ class TestValidator(Python26CompatTestCase):
"interface_name": None,
"ip": {
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"auto6": True,
"dhcp4": True,
@ -2578,6 +2634,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -2680,6 +2738,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": True,
"rule_append_only": False,
@ -2831,6 +2891,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": True,
"rule_append_only": False,
@ -2983,6 +3045,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -3065,6 +3129,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -3147,6 +3213,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -3227,6 +3295,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -3297,6 +3367,8 @@ class TestValidator(Python26CompatTestCase):
"ipv6_disabled": False,
"dhcp4": True,
"address": [],
"ipv4_ignore_auto_dns": None,
"ipv6_ignore_auto_dns": None,
"auto_gateway": None,
"route_append_only": False,
"rule_append_only": False,
@ -4445,6 +4517,27 @@ class TestValidator(Python26CompatTestCase):
# wokeignore:rule=slave
self.assertTrue("slave_type" not in connection)
def test_validate_ignore_auto_dns(self):
"""
Test and validate a connection profile with ipv4_ignore_auto_dns and
ipv6_ignore_auto_dns enabled.
"""
validator = network_lsr.argument_validator.ArgValidator_ListConnections()
test_ignore_auto_dns = [
{
"name": "ignore_auto_dns",
"type": "ethernet",
"ip": {
"auto6": True,
"dhcp4": True,
"ipv4_ignore_auto_dns": True,
"ipv6_ignore_auto_dns": True,
},
}
]
validator.validate(test_ignore_auto_dns)
@my_test_skipIf(nmutil is None, "no support for NM (libnm via pygobject)")
class TestNM(unittest.TestCase):