mirror of
https://github.com/linux-system-roles/network.git
synced 2026-01-23 02:15:17 +00:00
Merge e8a3ff4881 into 4e0379ec6e
This commit is contained in:
commit
b68dffc8f7
64 changed files with 2296 additions and 1315 deletions
|
|
@ -8,8 +8,6 @@ on: # yamllint disable-line rule:truthy
|
|||
types:
|
||||
- checks_requested
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
|
|
@ -35,13 +33,6 @@ jobs:
|
|||
# container
|
||||
- { image: "centos-9", env: "container-ansible-core-2.16" }
|
||||
- { image: "centos-9-bootc", env: "container-ansible-core-2.16" }
|
||||
# broken on non-running dbus
|
||||
# - { image: "centos-10", env: "container-ansible-core-2.17" }
|
||||
- { image: "centos-10-bootc", env: "container-ansible-core-2.17" }
|
||||
- { image: "fedora-41", env: "container-ansible-core-2.17" }
|
||||
- { image: "fedora-42", env: "container-ansible-core-2.17" }
|
||||
- { image: "fedora-41-bootc", env: "container-ansible-core-2.17" }
|
||||
- { image: "fedora-42-bootc", env: "container-ansible-core-2.17" }
|
||||
|
||||
env:
|
||||
TOX_ARGS: "--skip-tags tests::infiniband,tests::nvme,tests::scsi"
|
||||
|
|
|
|||
|
|
@ -31,8 +31,10 @@ network_provider_os_default: "{{
|
|||
ansible_distribution_major_version is version('7', '<')
|
||||
else 'nm' }}"
|
||||
# If NetworkManager.service is running, assume that 'nm' is currently in-use,
|
||||
# otherwise initscripts
|
||||
# otherwise initscripts. However, in non-booted environments we don't have
|
||||
# ansible_facts.services, so use the above OS default.
|
||||
__network_provider_current: "{{
|
||||
network_provider_os_default if ansible_facts.services is not defined else
|
||||
'nm' if 'NetworkManager.service' in ansible_facts.services and
|
||||
ansible_facts.services['NetworkManager.service']['state'] == 'running'
|
||||
else 'initscripts' }}"
|
||||
|
|
@ -136,6 +138,9 @@ __network_provider_setup:
|
|||
nm:
|
||||
service_name: "{{ __network_service_name_default_nm }}"
|
||||
packages: "{{ __network_packages_default_nm }}"
|
||||
nm_offline:
|
||||
service_name: "{{ __network_service_name_default_nm }}"
|
||||
packages: "{{ __network_packages_default_nm }}"
|
||||
initscripts:
|
||||
service_name: "{{ __network_service_name_default_initscripts }}"
|
||||
packages: "{{ __network_packages_default_initscripts }}"
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ import subprocess
|
|||
import time
|
||||
import traceback
|
||||
import logging
|
||||
import stat
|
||||
|
||||
# pylint: disable=import-error, no-name-in-module
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
|
@ -1712,7 +1713,7 @@ class RunEnvironment(object):
|
|||
self._check_mode = None
|
||||
|
||||
@property
|
||||
def ifcfg_header(self):
|
||||
def managed_file_header(self):
|
||||
return None
|
||||
|
||||
def log(
|
||||
|
|
@ -1728,7 +1729,7 @@ class RunEnvironment(object):
|
|||
):
|
||||
raise NotImplementedError()
|
||||
|
||||
def run_command(self, argv, encoding=None):
|
||||
def run_command(self, argv, encoding=None, check_rc=False):
|
||||
raise NotImplementedError()
|
||||
|
||||
def _check_mode_changed(self, old_check_mode, new_check_mode, connections):
|
||||
|
|
@ -1780,11 +1781,11 @@ class RunEnvironmentAnsible(RunEnvironment):
|
|||
self.module = module
|
||||
|
||||
@property
|
||||
def ifcfg_header(self):
|
||||
def managed_file_header(self):
|
||||
return self.module.params["__header"]
|
||||
|
||||
def run_command(self, argv, encoding=None):
|
||||
return self.module.run_command(argv, encoding=encoding)
|
||||
def run_command(self, argv, encoding=None, check_rc=False):
|
||||
return self.module.run_command(argv, encoding=encoding, check_rc=check_rc)
|
||||
|
||||
def _run_results_push(self, n_connections):
|
||||
c = []
|
||||
|
|
@ -1935,8 +1936,8 @@ class Cmd(object):
|
|||
self._is_changed_modified_system = False
|
||||
self._debug_flags = debug_flags
|
||||
|
||||
def run_command(self, argv, encoding=None):
|
||||
return self.run_env.run_command(argv, encoding=encoding)
|
||||
def run_command(self, argv, encoding=None, check_rc=False):
|
||||
return self.run_env.run_command(argv, encoding=encoding, check_rc=check_rc)
|
||||
|
||||
@property
|
||||
def is_changed_modified_system(self):
|
||||
|
|
@ -2030,6 +2031,8 @@ class Cmd(object):
|
|||
def create(provider, **kwargs):
|
||||
if provider == "nm":
|
||||
return Cmd_nm(**kwargs)
|
||||
if provider == "nm_offline":
|
||||
return Cmd_nm_offline(**kwargs)
|
||||
elif provider == "initscripts":
|
||||
return Cmd_initscripts(**kwargs)
|
||||
raise MyError("unsupported provider %s" % (provider))
|
||||
|
|
@ -2639,6 +2642,519 @@ class Cmd_nm(Cmd):
|
|||
###############################################################################
|
||||
|
||||
|
||||
class Cmd_nm_offline(Cmd):
|
||||
def __init__(self, **kwargs):
|
||||
Cmd.__init__(self, **kwargs)
|
||||
self.validate_one_type = ArgValidator_ListConnections.VALIDATE_ONE_MODE_NM
|
||||
self._checkpoint = None
|
||||
|
||||
def profile_path(self, name):
|
||||
return os.path.join(
|
||||
"/etc/NetworkManager/system-connections", name + ".nmconnection"
|
||||
)
|
||||
|
||||
def run_prepare(self):
|
||||
# we can't check any hardware or runtime status, we can just trust the input
|
||||
pass
|
||||
|
||||
# mirror Cmd_nm.connection_create()
|
||||
def connection_create(self, connections, idx):
|
||||
connection = connections[idx]
|
||||
# global/type independent arguments
|
||||
if "nm.uuid" not in connection:
|
||||
connection["nm.uuid"] = Util.create_uuid()
|
||||
if "nm.exists" not in connection:
|
||||
connection["nm.exists"] = True
|
||||
argv = [
|
||||
"nmcli",
|
||||
"--offline",
|
||||
"connection",
|
||||
"add",
|
||||
"ifname",
|
||||
connection["interface_name"],
|
||||
"con-name",
|
||||
connection["name"],
|
||||
"type",
|
||||
connection["type"],
|
||||
"autoconnect",
|
||||
"yes" if connection["autoconnect"] else "no",
|
||||
"connection.autoconnect-retries",
|
||||
str(connection["autoconnect_retries"]),
|
||||
"connection.uuid",
|
||||
connection["nm.uuid"],
|
||||
]
|
||||
|
||||
if connection["cloned_mac"] != "default":
|
||||
argv.extend(["cloned-mac", connection["cloned_mac"]])
|
||||
|
||||
# composite devices
|
||||
if connection["controller"] is not None:
|
||||
if connection["port_type"] is None:
|
||||
self.log_error(
|
||||
idx,
|
||||
"connection.port-type must be specified when connection.controller is set",
|
||||
)
|
||||
# must use uuid instead of name for controller here
|
||||
controller_uuid = ArgUtil.connection_find_controller_uuid(
|
||||
connection["controller"], connections
|
||||
)
|
||||
|
||||
argv.extend(
|
||||
[
|
||||
"connection.controller",
|
||||
controller_uuid,
|
||||
"connection.port-type",
|
||||
connection["port_type"],
|
||||
]
|
||||
)
|
||||
|
||||
# skip IP and other config for composites
|
||||
return argv
|
||||
|
||||
c_ip = connection["ip"]
|
||||
ip4_addrs = []
|
||||
ip6_addrs = []
|
||||
for address in c_ip["address"]:
|
||||
addr = "{0}/{1}".format(address["address"], address["prefix"])
|
||||
if address["family"] == socket.AF_INET:
|
||||
ip4_addrs.append(addr)
|
||||
elif address["family"] == socket.AF_INET6:
|
||||
ip6_addrs.append(addr)
|
||||
else:
|
||||
self.log_error(idx, "unknown address family %s" % (address["family"]))
|
||||
|
||||
argv.extend(
|
||||
[
|
||||
"ipv4.method",
|
||||
"auto" if c_ip["dhcp4"] else "manual" if ip4_addrs else "disabled",
|
||||
"ipv4.addresses",
|
||||
", ".join(ip4_addrs),
|
||||
"ipv6.method",
|
||||
(
|
||||
"disabled"
|
||||
if c_ip["ipv6_disabled"]
|
||||
else (
|
||||
"auto"
|
||||
if c_ip["auto6"]
|
||||
else (
|
||||
"manual"
|
||||
if ip6_addrs
|
||||
else
|
||||
# online backend uses legacy "ignore", DTRT for this new backend
|
||||
"ignore"
|
||||
)
|
||||
)
|
||||
), # "link-local",
|
||||
"ipv6.addresses",
|
||||
", ".join(ip6_addrs),
|
||||
]
|
||||
)
|
||||
|
||||
# gateway
|
||||
if c_ip["gateway4"]:
|
||||
argv.extend(["ipv4.gateway", c_ip["gateway4"]])
|
||||
if c_ip["gateway6"]:
|
||||
argv.extend(["ipv6.gateway", c_ip["gateway6"]])
|
||||
|
||||
# dns*
|
||||
dns4_addrs = []
|
||||
dns6_addrs = []
|
||||
for dns in c_ip["dns"]:
|
||||
if dns["family"] == socket.AF_INET:
|
||||
dns4_addrs.append(dns["address"])
|
||||
elif dns["family"] == socket.AF_INET6:
|
||||
dns6_addrs.append(dns["address"])
|
||||
else:
|
||||
self.log_error(idx, "unknown DNS address family %s" % (dns["family"]))
|
||||
if dns4_addrs:
|
||||
argv.extend(["ipv4.dns", ",".join(dns4_addrs)])
|
||||
if dns6_addrs:
|
||||
argv.extend(["ipv6.dns", ",".join(dns6_addrs)])
|
||||
|
||||
if c_ip["dns_search"]:
|
||||
# NM only allows to configure ipvN.dns-search when IPvN is enabled
|
||||
if c_ip["dhcp4"] or ip4_addrs:
|
||||
argv.extend(["ipv4.dns-search", " ".join(c_ip["dns_search"])])
|
||||
if c_ip["auto6"] or ip6_addrs:
|
||||
argv.extend(["ipv6.dns-search", " ".join(c_ip["dns_search"])])
|
||||
|
||||
if c_ip["dns_options"]:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv4.dns-options",
|
||||
",".join(c_ip["dns_options"]),
|
||||
"ipv6.dns-options",
|
||||
",".join(c_ip["dns_options"]),
|
||||
]
|
||||
)
|
||||
|
||||
if c_ip["dns_priority"] != 0:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv4.dns-priority",
|
||||
str(c_ip["dns_priority"]),
|
||||
"ipv6.dns-priority",
|
||||
str(c_ip["dns_priority"]),
|
||||
]
|
||||
)
|
||||
|
||||
if c_ip["ipv4_ignore_auto_dns"] is not None:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv4.ignore-auto-dns",
|
||||
"yes" if c_ip["ipv4_ignore_auto_dns"] else "no",
|
||||
]
|
||||
)
|
||||
if c_ip["ipv6_ignore_auto_dns"] is not None:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv6.ignore-auto-dns",
|
||||
"yes" if c_ip["ipv6_ignore_auto_dns"] else "no",
|
||||
]
|
||||
)
|
||||
|
||||
# route
|
||||
if c_ip["route_metric4"] is not None:
|
||||
argv.extend(["ipv4.route-metric", str(c_ip["route_metric4"])])
|
||||
if c_ip["route_metric6"] is not None:
|
||||
argv.extend(["ipv6.route-metric", str(c_ip["route_metric6"])])
|
||||
|
||||
# routes
|
||||
if c_ip.get("route"):
|
||||
ipv4_routes = []
|
||||
ipv6_routes = []
|
||||
for route in c_ip["route"]:
|
||||
route_str = route["network"]
|
||||
if route.get("prefix"):
|
||||
route_str += "/" + str(route["prefix"])
|
||||
if route.get("gateway"):
|
||||
route_str += " " + route["gateway"]
|
||||
if route.get("metric"):
|
||||
route_str += " " + str(route["metric"])
|
||||
if route.get("type"):
|
||||
route_str += " type=" + route["type"]
|
||||
if route.get("table"):
|
||||
route_str += " table=" + str(route["table"])
|
||||
if route.get("src"):
|
||||
route_str += " src=" + route["src"]
|
||||
|
||||
if route["family"] == socket.AF_INET:
|
||||
ipv4_routes.append(route_str)
|
||||
elif route["family"] == socket.AF_INET6:
|
||||
ipv6_routes.append(route_str)
|
||||
|
||||
if ipv4_routes:
|
||||
argv.extend(["ipv4.routes", ",".join(ipv4_routes)])
|
||||
if ipv6_routes:
|
||||
argv.extend(["ipv6.routes", ",".join(ipv6_routes)])
|
||||
|
||||
# routing rules
|
||||
if c_ip.get("routing_rule"):
|
||||
ipv4_rules = []
|
||||
ipv6_rules = []
|
||||
for rule in c_ip["routing_rule"]:
|
||||
rule_parts = []
|
||||
if rule.get("priority"):
|
||||
rule_parts.append("priority " + rule["priority"])
|
||||
if rule.get("from"):
|
||||
rule_parts.append("from " + rule["from"])
|
||||
if rule.get("to"):
|
||||
rule_parts.append("to " + rule["to"])
|
||||
if rule.get("table"):
|
||||
rule_parts.append("table " + rule["table"])
|
||||
|
||||
if rule_parts:
|
||||
rule_str = " ".join(rule_parts)
|
||||
if rule["family"] == socket.AF_INET:
|
||||
ipv4_rules.append(rule_str)
|
||||
elif rule["family"] == socket.AF_INET6:
|
||||
ipv6_rules.append(rule_str)
|
||||
|
||||
if ipv4_rules:
|
||||
argv.extend(["ipv4.routing-rules", " ".join(ipv4_rules)])
|
||||
if ipv6_rules:
|
||||
argv.extend(["ipv6.routing-rules", " ".join(ipv6_rules)])
|
||||
|
||||
# DHCP options
|
||||
if c_ip.get("dhcp4_send_hostname") is not None:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv4.dhcp-send-hostname",
|
||||
"yes" if c_ip["dhcp4_send_hostname"] else "no",
|
||||
]
|
||||
)
|
||||
if c_ip.get("dhcp6_send_hostname") is not None:
|
||||
argv.extend(
|
||||
[
|
||||
"ipv6.dhcp-send-hostname",
|
||||
"yes" if c_ip["dhcp6_send_hostname"] else "no",
|
||||
]
|
||||
)
|
||||
|
||||
# zone
|
||||
if connection.get("zone"):
|
||||
argv.extend(["connection.zone", connection["zone"]])
|
||||
|
||||
# mac address
|
||||
if connection.get("mac") and connection["mac"] != "default":
|
||||
if connection["type"] == "wireless":
|
||||
argv.extend(["802-11-wireless.mac-address", connection["mac"]])
|
||||
else:
|
||||
argv.extend(["802-3-ethernet.mac-address", connection["mac"]])
|
||||
|
||||
# mtu
|
||||
if connection.get("mtu"):
|
||||
if connection["type"] == "wireless":
|
||||
argv.extend(["802-11-wireless.mtu", str(connection["mtu"])])
|
||||
else:
|
||||
argv.extend(["802-3-ethernet.mtu", str(connection["mtu"])])
|
||||
|
||||
# ethernet settings
|
||||
if connection.get("ethernet"):
|
||||
eth = connection["ethernet"]
|
||||
if eth.get("autoneg") is not None:
|
||||
argv.extend(
|
||||
["802-3-ethernet.auto-negotiate", "yes" if eth["autoneg"] else "no"]
|
||||
)
|
||||
if eth.get("speed"):
|
||||
argv.extend(["802-3-ethernet.speed", str(eth["speed"])])
|
||||
if eth.get("duplex"):
|
||||
argv.extend(["802-3-ethernet.duplex", eth["duplex"]])
|
||||
|
||||
# type-specific configurations
|
||||
# bond options[mode, miimon, downdelay, updelay, arp_interval, arp_ip_target, arp_validate, balance-slb, primary,
|
||||
# primary_reselect, fail_over_mac, use_carrier, ad_select, xmit_hash_policy, resend_igmp, lacp_rate, active_slave, ad_actor_sys_prio,
|
||||
# ad_actor_system, ad_user_port_key, all_slaves_active, arp_all_targets, min_links, num_grat_arp, num_unsol_na, packets_per_slave,
|
||||
# tlb_dynamic_lb, lp_interval, peer_notif_delay, arp_missed_max, lacp_active, ns_ip6_target].,
|
||||
if connection["type"] == "bond":
|
||||
opts = []
|
||||
for key, value in connection["bond"].items():
|
||||
if value is not None:
|
||||
if key in ["all_ports_active", "use_carrier", "tlb_dynamic_lb"]:
|
||||
value = int(value)
|
||||
if key in ["all_ports_active", "packets_per_port"]:
|
||||
# wokeignore:rule=slave
|
||||
key = key.replace("port", "slave")
|
||||
opts.append("{0}={1}".format(key, str(value)))
|
||||
if opts:
|
||||
argv.extend(["bond.options", ",".join(opts)])
|
||||
|
||||
elif connection["type"] == "bridge":
|
||||
if connection.get("bridge"):
|
||||
bridge = connection["bridge"]
|
||||
if bridge.get("stp") is not None:
|
||||
argv.extend(["bridge.stp", "yes" if bridge["stp"] else "no"])
|
||||
if bridge.get("priority") is not None:
|
||||
argv.extend(["bridge.priority", str(bridge["priority"])])
|
||||
if bridge.get("forward_delay") is not None:
|
||||
argv.extend(["bridge.forward-delay", str(bridge["forward_delay"])])
|
||||
if bridge.get("hello_time") is not None:
|
||||
argv.extend(["bridge.hello-time", str(bridge["hello_time"])])
|
||||
if bridge.get("max_age") is not None:
|
||||
argv.extend(["bridge.max-age", str(bridge["max_age"])])
|
||||
if bridge.get("ageing_time") is not None:
|
||||
argv.extend(["bridge.ageing-time", str(bridge["ageing_time"])])
|
||||
|
||||
elif connection["type"] == "vlan":
|
||||
if connection.get("vlan") and connection["vlan"].get("id") is not None:
|
||||
argv.extend(["vlan.id", str(connection["vlan"]["id"])])
|
||||
if connection.get("parent"):
|
||||
argv.extend(["vlan.parent", connection["parent"]])
|
||||
|
||||
elif connection["type"] == "macvlan":
|
||||
if connection.get("macvlan"):
|
||||
macvlan = connection["macvlan"]
|
||||
if macvlan.get("mode"):
|
||||
argv.extend(["macvlan.mode", macvlan["mode"]])
|
||||
if macvlan.get("promiscuous") is not None:
|
||||
argv.extend(
|
||||
[
|
||||
"macvlan.promiscuous",
|
||||
"yes" if macvlan["promiscuous"] else "no",
|
||||
]
|
||||
)
|
||||
if macvlan.get("tap") is not None:
|
||||
argv.extend(["macvlan.tap", "yes" if macvlan["tap"] else "no"])
|
||||
if connection.get("parent"):
|
||||
argv.extend(["macvlan.parent", connection["parent"]])
|
||||
|
||||
elif connection["type"] == "infiniband":
|
||||
if connection.get("infiniband"):
|
||||
ib = connection["infiniband"]
|
||||
if ib.get("transport_mode"):
|
||||
argv.extend(["infiniband.transport-mode", ib["transport_mode"]])
|
||||
if ib.get("p_key") is not None:
|
||||
argv.extend(["infiniband.p-key", str(ib["p_key"])])
|
||||
if connection.get("parent"):
|
||||
argv.extend(["infiniband.parent", connection["parent"]])
|
||||
|
||||
elif connection["type"] == "wireless":
|
||||
if connection.get("wireless"):
|
||||
wifi = connection["wireless"]
|
||||
if wifi.get("ssid"):
|
||||
argv.extend(["802-11-wireless.ssid", wifi["ssid"]])
|
||||
if wifi.get("key_mgmt"):
|
||||
argv.extend(["802-11-wireless-security.key-mgmt", wifi["key_mgmt"]])
|
||||
if wifi.get("password") and wifi["key_mgmt"] in ["wpa-psk", "sae"]:
|
||||
argv.extend(["802-11-wireless-security.psk", wifi["password"]])
|
||||
|
||||
elif connection["type"] == "team":
|
||||
if connection.get("team") and connection["team"].get("config"):
|
||||
# Team config is typically JSON, pass as-is
|
||||
argv.extend(["team.config", connection["team"]["config"]])
|
||||
|
||||
# ethtool settings
|
||||
if connection.get("ethtool"):
|
||||
ethtool = connection["ethtool"]
|
||||
|
||||
# ethtool features
|
||||
if ethtool.get("features"):
|
||||
for feature, value in ethtool["features"].items():
|
||||
if value is not None:
|
||||
feature_name = feature.replace("_", "-")
|
||||
if value:
|
||||
value = "on"
|
||||
else:
|
||||
value = "off"
|
||||
argv.extend(["ethtool.feature-" + feature_name, value])
|
||||
|
||||
# ethtool coalesce settings
|
||||
if ethtool.get("coalesce"):
|
||||
for param, value in ethtool["coalesce"].items():
|
||||
if value is not None:
|
||||
param_name = param.replace("_", "-")
|
||||
argv.extend(["ethtool.coalesce-" + param_name, str(value)])
|
||||
|
||||
# ethtool ring settings
|
||||
if ethtool.get("ring"):
|
||||
for param, value in ethtool["ring"].items():
|
||||
if value is not None:
|
||||
param_name = param.replace("_", "-")
|
||||
argv.extend(["ethtool.ring-" + param_name, str(value)])
|
||||
|
||||
# ieee802_1x settings
|
||||
if connection.get("ieee802_1x"):
|
||||
ieee = connection["ieee802_1x"]
|
||||
if ieee.get("eap"):
|
||||
argv.extend(
|
||||
[
|
||||
"802-1x.eap",
|
||||
(
|
||||
",".join(ieee["eap"])
|
||||
if isinstance(ieee["eap"], list)
|
||||
else ieee["eap"]
|
||||
),
|
||||
]
|
||||
)
|
||||
if ieee.get("identity"):
|
||||
argv.extend(["802-1x.identity", ieee["identity"]])
|
||||
if ieee.get("password"):
|
||||
argv.extend(["802-1x.password", ieee["password"]])
|
||||
if ieee.get("ca_cert"):
|
||||
argv.extend(["802-1x.ca-cert", ieee["ca_cert"]])
|
||||
if ieee.get("client_cert"):
|
||||
argv.extend(["802-1x.client-cert", ieee["client_cert"]])
|
||||
if ieee.get("private_key"):
|
||||
argv.extend(["802-1x.private-key", ieee["private_key"]])
|
||||
if ieee.get("private_key_password"):
|
||||
argv.extend(
|
||||
["802-1x.private-key-password", ieee["private_key_password"]]
|
||||
)
|
||||
|
||||
# match settings
|
||||
if connection.get("match"):
|
||||
match = connection["match"]
|
||||
if match.get("path"):
|
||||
match_paths = (
|
||||
match["path"]
|
||||
if isinstance(match["path"], list)
|
||||
else [match["path"]]
|
||||
)
|
||||
argv.extend(["match.path", ",".join(match_paths)])
|
||||
if match.get("driver"):
|
||||
match_drivers = (
|
||||
match["driver"]
|
||||
if isinstance(match["driver"], list)
|
||||
else [match["driver"]]
|
||||
)
|
||||
argv.extend(["match.driver", ",".join(match_drivers)])
|
||||
if match.get("interface_name"):
|
||||
match_names = (
|
||||
match["interface_name"]
|
||||
if isinstance(match["interface_name"], list)
|
||||
else [match["interface_name"]]
|
||||
)
|
||||
argv.extend(["match.interface-name", ",".join(match_names)])
|
||||
|
||||
return argv
|
||||
|
||||
def run_action_present(self, idx):
|
||||
connection = self.connections[idx]
|
||||
|
||||
if not connection.get("type"):
|
||||
# this is mostly test teardown, nobody uses that in container builds
|
||||
if connection["state"] == "down":
|
||||
self.log_info(idx, "nm_offline ignoring 'state: down'")
|
||||
return
|
||||
|
||||
self.log_error(idx, "Connection 'type' not specified")
|
||||
return
|
||||
|
||||
# DEBUG, drop for final commit
|
||||
self.log_info(
|
||||
idx, "XXX nm_offline provider action_present connection: %r" % connection
|
||||
)
|
||||
|
||||
# create the profile
|
||||
(rc, out, err) = self.run_command(
|
||||
self.connection_create(self.connections, idx), check_rc=True
|
||||
)
|
||||
# Should Not Happen™, but make sure
|
||||
if not out.strip():
|
||||
self.log_error(
|
||||
idx, "nmcli --offline returned no output (rc %d); err: %s" % (rc, err)
|
||||
)
|
||||
return
|
||||
|
||||
path = self.profile_path(connection["name"])
|
||||
if self.check_mode == CheckMode.REAL_RUN:
|
||||
with open(path, "w") as f:
|
||||
f.write(self.run_env.managed_file_header)
|
||||
f.write(out.decode("UTF-8"))
|
||||
os.chmod(path, stat.S_IRUSR | stat.S_IWUSR)
|
||||
os.chown(path, 0, 0)
|
||||
|
||||
# nmcli always generates a new UUID, so comparing with existing file is moot
|
||||
# always treat as changed, good enough for container builds
|
||||
self.connections_data_set_changed(idx)
|
||||
|
||||
def run_action_absent(self, idx):
|
||||
connection = self.connections[idx]
|
||||
# DEBUG, drop for final commit
|
||||
self.log_info(
|
||||
idx, "XXX nm_offline provider action_absent connection: %r" % connection
|
||||
)
|
||||
|
||||
try:
|
||||
os.unlink(self.profile_path(connection["name"]))
|
||||
self.connections_data_set_changed(idx)
|
||||
except FileNotFoundError:
|
||||
self.log_debug(
|
||||
idx, "nm_offline: profile '%s' already absent" % connection["name"]
|
||||
)
|
||||
|
||||
def run_action_up(self, idx):
|
||||
# no runtime ops in offline provider
|
||||
pass
|
||||
|
||||
def run_action_down(self, idx):
|
||||
# no runtime ops in offline provider
|
||||
pass
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
||||
class Cmd_initscripts(Cmd):
|
||||
def __init__(self, **kwargs):
|
||||
Cmd.__init__(self, **kwargs)
|
||||
|
|
@ -2763,7 +3279,7 @@ class Cmd_initscripts(Cmd):
|
|||
)
|
||||
|
||||
new_content = IfcfgUtil.content_from_dict(
|
||||
ifcfg_all, header=self.run_env.ifcfg_header
|
||||
ifcfg_all, header=self.run_env.managed_file_header
|
||||
)
|
||||
|
||||
if old_content == new_content:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ galaxy_info:
|
|||
- "9"
|
||||
galaxy_tags:
|
||||
- centos
|
||||
- containerbuild
|
||||
- el6
|
||||
- el7
|
||||
- el8
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@
|
|||
- name: Ensure ansible_facts used by role
|
||||
include_tasks: tasks/set_facts.yml
|
||||
|
||||
- name: Switch to offline NM backend if host is not booted
|
||||
set_fact:
|
||||
network_provider: "nm_offline"
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- not __network_is_booted
|
||||
|
||||
- name: Print network provider
|
||||
debug:
|
||||
msg: "Using network provider: {{ network_provider }}"
|
||||
|
|
@ -14,7 +21,7 @@
|
|||
msg: Only the `nm` provider supports using the `network_state` variable
|
||||
when:
|
||||
- network_state != {}
|
||||
- network_provider == "initscripts"
|
||||
- network_provider != "nm"
|
||||
|
||||
- name: Abort applying the network state configuration if the system version
|
||||
of the managed host is below 8
|
||||
|
|
@ -151,10 +158,10 @@
|
|||
- name: Enable and start NetworkManager
|
||||
service:
|
||||
name: "{{ network_service_name }}"
|
||||
state: started
|
||||
state: "{{ 'started' if __network_is_booted else omit }}"
|
||||
enabled: true
|
||||
when:
|
||||
- network_provider == "nm" or network_state != {}
|
||||
- network_provider in ["nm", "nm_offline"] or network_state != {}
|
||||
no_log: true
|
||||
|
||||
# If any 802.1x connections are used, the wpa_supplicant
|
||||
|
|
@ -162,10 +169,10 @@
|
|||
- name: Enable and start wpa_supplicant
|
||||
service:
|
||||
name: wpa_supplicant
|
||||
state: started
|
||||
state: "{{ 'started' if __network_is_booted else omit }}"
|
||||
enabled: true
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- network_provider in ["nm", "nm_offline"]
|
||||
- __network_wpa_supplicant_required
|
||||
|
||||
- name: Enable network service
|
||||
|
|
|
|||
|
|
@ -19,6 +19,27 @@
|
|||
set_fact:
|
||||
__network_is_ostree: "{{ __ostree_booted_stat.stat.exists }}"
|
||||
|
||||
- name: Determine if system is booted with systemd
|
||||
when: __network_is_booted is not defined
|
||||
block:
|
||||
- name: Run systemctl
|
||||
# noqa command-instead-of-module
|
||||
command: systemctl is-system-running
|
||||
register: __is_system_running
|
||||
changed_when: false
|
||||
check_mode: false
|
||||
failed_when: false
|
||||
|
||||
- name: Require installed systemd
|
||||
fail:
|
||||
msg: "Error: This role requires systemd to be installed."
|
||||
when: '"No such file or directory" in __is_system_running.msg | d("")'
|
||||
|
||||
- name: Set flag to indicate that systemd runtime operations are available
|
||||
set_fact:
|
||||
# see https://www.man7.org/linux/man-pages/man1/systemctl.1.html#:~:text=is-system-running%20output
|
||||
__network_is_booted: "{{ __is_system_running.stdout != 'offline' }}"
|
||||
|
||||
- name: Check which services are running
|
||||
service_facts:
|
||||
no_log: true
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
[defaults]
|
||||
task_timeout=480
|
||||
task_timeout=600
|
||||
|
|
|
|||
3
tests/collection-requirements.yml
Normal file
3
tests/collection-requirements.yml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
collections:
|
||||
- name: community.general
|
||||
|
|
@ -5,21 +5,14 @@
|
|||
vars:
|
||||
interface: 802-1x-test
|
||||
tasks:
|
||||
- name: "INIT: 802.1x tests"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Include the task 'setup_802.1x.yml'
|
||||
include_tasks: tasks/setup_802.1x.yml
|
||||
- name: Test configuring 802.1x authentication
|
||||
block:
|
||||
- name: "TEST: 802.1x profile with private key password and ca cert"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: Test setting 802.1x authentication
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
lsr_description: Test 802.1x authentication
|
||||
lsr_setup:
|
||||
- tasks/setup_802.1x.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: veth2
|
||||
state: up
|
||||
|
|
@ -38,28 +31,25 @@
|
|||
- none
|
||||
client_cert: /etc/pki/tls/client.pem
|
||||
ca_cert: /etc/pki/tls/cacert.pem
|
||||
- name: Ensure ping command is present
|
||||
package:
|
||||
name: iputils
|
||||
state: present
|
||||
use: "{{ (__network_is_ostree | d(false)) |
|
||||
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
|
||||
- name: "TEST: I can ping the EAP server"
|
||||
command: ping -c1 203.0.113.1
|
||||
changed_when: false
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
persistent_state: absent
|
||||
state: down
|
||||
- name: >-
|
||||
TEST: 802.1x profile with unencrypted private key,
|
||||
domain suffix match, and system ca certs
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
lsr_assert:
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_command: ping -c1 203.0.113.1
|
||||
lsr_packages: [iputils]
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted and not __bootc_validation | default(false) }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- tasks/check_network_dns.yml
|
||||
|
||||
- name: Stop test if building image or validation is enabled
|
||||
meta: end_host
|
||||
when: ansible_connection | d("") == "buildah" or __bootc_validation | default(false)
|
||||
|
||||
- name: >-
|
||||
Test 802.1x profile with unencrypted private key, domain suffix match, and system ca certs
|
||||
block:
|
||||
- name: Copy cacert to system truststore
|
||||
copy:
|
||||
src: cacert.pem
|
||||
|
|
|
|||
|
|
@ -6,145 +6,97 @@
|
|||
type: veth
|
||||
interface: veth0
|
||||
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
|
||||
- name: Test setting auto_gateway to true
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
state: present
|
||||
- name: Include the task 'assert_device_present.yml'
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
- name: >-
|
||||
TEST: I can configure an interface with auto_gateway enabled
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
lsr_description: Test auto_gateway setting to true
|
||||
lsr_setup:
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
auto_gateway: true
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
address:
|
||||
- "2001:db8::2/64"
|
||||
- "203.0.113.2/24"
|
||||
gateway6: "2001:db8::1"
|
||||
gateway4: "203.0.113.1"
|
||||
# change the default route metric to higher value so that it will
|
||||
# not take precedence over other routes or not ignore other
|
||||
# routes
|
||||
route_metric4: 65535
|
||||
lsr_assert:
|
||||
- tasks/assert_device_present.yml
|
||||
- what: tasks/assert_profile_present.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_command: ip route
|
||||
lsr_stdout: default via 203.0.113.1 dev {{ interface }}
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted and network_provider == 'nm' }}"
|
||||
lsr_command: ip -6 route
|
||||
lsr_stdout: default via 2001:db8::1 dev {{ interface }}
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: absent
|
||||
- tasks/check_network_dns.yml
|
||||
|
||||
- name: Stop test if building image or validation is enabled
|
||||
meta: end_host
|
||||
when: ansible_connection | d("") == "buildah" or __bootc_validation | default(false)
|
||||
|
||||
- name: Test setting auto_gateway to false
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
auto_gateway: true
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
address:
|
||||
- "2001:db8::2/64"
|
||||
- "203.0.113.2/24"
|
||||
gateway6: "2001:db8::1"
|
||||
gateway4: "203.0.113.1"
|
||||
# change the default route metric to higher value so that it will
|
||||
# not take precedence over other routes or not ignore other
|
||||
# routes
|
||||
route_metric4: 65535
|
||||
- name: Include the task 'assert_device_present.yml' again
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
- name: Include the task 'assert_profile_present.yml'
|
||||
include_tasks: tasks/assert_profile_present.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
- name: "Show ipv4 routes"
|
||||
command: "ip route"
|
||||
register: ipv4_routes
|
||||
changed_when: false
|
||||
- name: "Assert default ipv4 route is present"
|
||||
assert:
|
||||
that: __test_str in ipv4_routes.stdout
|
||||
vars:
|
||||
__test_str: default via 203.0.113.1 dev {{ interface }}
|
||||
- name: "Get ipv6 routes"
|
||||
command: "ip -6 route"
|
||||
register: ipv6_route
|
||||
changed_when: false
|
||||
- name: "Assert default ipv6 route is present"
|
||||
assert:
|
||||
that: __test_str in ipv6_route.stdout
|
||||
vars:
|
||||
__test_str: default via 2001:db8::1 dev {{ interface }}
|
||||
when: network_provider == "nm"
|
||||
- name: "TEARDOWN: remove profiles."
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role to remove interface
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
persistent_state: absent
|
||||
state: down
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
- name: Include the task 'manage_test_interface.yml' to remove interface
|
||||
include_tasks: tasks/manage_test_interface.yml
|
||||
vars:
|
||||
state: absent
|
||||
- name: >-
|
||||
TEST: I can configure an interface with auto_gateway disabled
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Include the task 'manage_test_interface.yml' to disable auto_gateway
|
||||
include_tasks: tasks/manage_test_interface.yml
|
||||
vars:
|
||||
state: present
|
||||
- name: Import network role to disable auto_gateway
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
auto_gateway: false
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
address:
|
||||
- "2001:db8::2/64"
|
||||
- "203.0.113.2/24"
|
||||
gateway6: "2001:db8::1"
|
||||
gateway4: "203.0.113.1"
|
||||
- name: Include the task 'assert_device_present.yml' - 3
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
- name: Include the task 'assert_profile_present.yml' again
|
||||
include_tasks: tasks/assert_profile_present.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
- name: "Show ipv4 routes again"
|
||||
command: "ip route"
|
||||
register: ipv4_routes
|
||||
changed_when: false
|
||||
- name: "Assert default ipv4 route is absent"
|
||||
assert:
|
||||
that: __test_str not in ipv4_routes.stdout
|
||||
vars:
|
||||
__test_str: default via 203.0.113.1 dev {{ interface }}
|
||||
- name: "Get ipv6 routes again"
|
||||
command: "ip -6 route"
|
||||
register: ipv6_route
|
||||
changed_when: false
|
||||
- name: "Assert default ipv6 route is absent"
|
||||
assert:
|
||||
that: __test_str not in ipv6_route.stdout
|
||||
vars:
|
||||
__test_str: default via 2001:db8::1 dev {{ interface }}
|
||||
when: network_provider == "nm"
|
||||
- name: "TEARDOWN: remove profiles. again"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role to remove interface again
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
persistent_state: absent
|
||||
state: down
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
- name: Include the task 'manage_test_interface.yml' to remove interface again
|
||||
include_tasks: tasks/manage_test_interface.yml
|
||||
vars:
|
||||
state: absent
|
||||
- name: Verify network state restored to default
|
||||
include_tasks: tasks/check_network_dns.yml
|
||||
lsr_description: Test auto_gateway setting to false
|
||||
lsr_setup:
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
auto_gateway: false
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
address:
|
||||
- "2001:db8::2/64"
|
||||
- "203.0.113.2/24"
|
||||
gateway6: "2001:db8::1"
|
||||
gateway4: "203.0.113.1"
|
||||
lsr_assert:
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_assert_when:
|
||||
- what: tasks/assert_profile_present.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_command: ip route
|
||||
lsr_not_stdout: default via 203.0.113.1 dev {{ interface }}
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted and network_provider == 'nm' }}"
|
||||
lsr_command: ip -6 route
|
||||
lsr_not_stdout: default via 2001:db8::1 dev {{ interface }}
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: absent
|
||||
- tasks/check_network_dns.yml
|
||||
|
|
|
|||
|
|
@ -72,26 +72,85 @@
|
|||
- "{{ controller_profile }}"
|
||||
- "{{ port1_profile }}"
|
||||
- "{{ port2_profile }}"
|
||||
- name: "** TEST check polling interval"
|
||||
command: grep 'Polling Interval'
|
||||
/proc/net/bonding/{{ controller_device }}
|
||||
register: result
|
||||
until: "'110' in result.stdout"
|
||||
changed_when: false
|
||||
- name: "** TEST check IPv4"
|
||||
command: ip -4 a s {{ controller_device }}
|
||||
register: result
|
||||
until: "'192.0.2' in result.stdout"
|
||||
retries: 20
|
||||
delay: 2
|
||||
changed_when: false
|
||||
- name: "** TEST check IPv6"
|
||||
command: ip -6 a s {{ controller_device }}
|
||||
register: result
|
||||
until: "'2001' in result.stdout"
|
||||
retries: 20
|
||||
delay: 2
|
||||
changed_when: false
|
||||
|
||||
- name: Runtime checks for booted systems
|
||||
when: __network_is_booted | bool
|
||||
block:
|
||||
- name: "** TEST check polling interval"
|
||||
command: grep 'Polling Interval'
|
||||
/proc/net/bonding/{{ controller_device }}
|
||||
register: result
|
||||
until: "'110' in result.stdout"
|
||||
changed_when: false
|
||||
- name: "** TEST check IPv4"
|
||||
command: ip -4 a s {{ controller_device }}
|
||||
register: result
|
||||
until: "'192.0.2' in result.stdout"
|
||||
retries: 20
|
||||
delay: 2
|
||||
changed_when: false
|
||||
- name: "** TEST check IPv6"
|
||||
command: ip -6 a s {{ controller_device }}
|
||||
register: result
|
||||
until: "'2001' in result.stdout"
|
||||
retries: 20
|
||||
delay: 2
|
||||
changed_when: false
|
||||
|
||||
# These are primarily interesting for non-booted systems; but let's
|
||||
# check on booted systems too, to ensure the assertions are valid
|
||||
- name: NM Config file checks
|
||||
when:
|
||||
- network_provider != "initscripts"
|
||||
- ansible_distribution_major_version | int >= 9
|
||||
block:
|
||||
- name: Read controller config
|
||||
slurp:
|
||||
src: "/etc/NetworkManager/system-connections/{{ controller_profile }}.nmconnection"
|
||||
register: controller_config_b64
|
||||
|
||||
- name: Check controller config
|
||||
assert:
|
||||
that:
|
||||
# [connection]
|
||||
- "'id=' + controller_profile in controller_config"
|
||||
- "'type=bond' in controller_config"
|
||||
- "'interface-name=' + controller_device in controller_config"
|
||||
# [bond]
|
||||
- "'mode=active-backup' in controller_config"
|
||||
- "'miimon=110' in controller_config"
|
||||
# [ipv4]
|
||||
- "'method=auto' in controller_config"
|
||||
- "'route-metric=65535' in controller_config"
|
||||
fail_msg: "{{ controller_profile }} is bad: {{ controller_config }}"
|
||||
vars:
|
||||
controller_config: "{{ controller_config_b64.content | b64decode }}"
|
||||
|
||||
- name: Read port configs
|
||||
loop:
|
||||
- { name: "{{ port1_profile }}", iface_name: "{{ dhcp_interface1 }}" }
|
||||
- { name: "{{ port2_profile }}", iface_name: "{{ dhcp_interface2 }}" }
|
||||
slurp:
|
||||
src: "/etc/NetworkManager/system-connections/{{ item.name }}.nmconnection"
|
||||
register: port1_config_b64
|
||||
|
||||
- name: Check port configs
|
||||
loop: "{{ port1_config_b64.results }}"
|
||||
vars:
|
||||
port_config: "{{ item.content | b64decode }}"
|
||||
assert:
|
||||
that:
|
||||
# [connection]
|
||||
- "'id=' + item.item.name in port_config"
|
||||
- "'type=ethernet' in port_config"
|
||||
# that points to UUID of controller, a bit cumbersome to match; but let's assume nmcli DTRT
|
||||
- "'controller=' in port_config"
|
||||
- "'interface-name=' + item.item.iface_name in port_config"
|
||||
- "'port-type=bond' in port_config"
|
||||
- "'[ipv4]' not in port_config"
|
||||
- "'[ipv6]' not in port_config"
|
||||
fail_msg: "{{ item.item.name }} is bad: {{ port_config }}"
|
||||
|
||||
always:
|
||||
- name: Clean up the test devices and the connection profiles
|
||||
tags:
|
||||
|
|
@ -116,6 +175,7 @@
|
|||
command: ip link del {{ controller_device }}
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: __network_is_booted | bool
|
||||
- name: Import the task 'remove_test_interfaces_with_dhcp.yml'
|
||||
import_tasks: tasks/remove_test_interfaces_with_dhcp.yml
|
||||
- name: "Restore the /etc/resolv.conf for initscript"
|
||||
|
|
@ -125,3 +185,4 @@
|
|||
changed_when: false
|
||||
- name: Verify network state restored to default
|
||||
include_tasks: tasks/check_network_dns.yml
|
||||
when: __network_is_booted | bool
|
||||
|
|
|
|||
|
|
@ -54,54 +54,80 @@
|
|||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
|
||||
- name: Verify nmcli cloned-mac-address entry
|
||||
command: >-
|
||||
nmcli -f 802-3-ethernet.cloned-mac-address con show {{ item.name }}
|
||||
register: cloned_mac_address
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
loop:
|
||||
- {name: "{{ controller_profile }}", mac: "12:23:34:45:56:60"}
|
||||
- {name: "{{ port1_profile }}", mac: "12:23:34:45:56:61"}
|
||||
- {name: "{{ port2_profile }}", mac: "--"}
|
||||
- name: Verify nm provider
|
||||
when: network_provider == 'nm'
|
||||
block:
|
||||
- name: Verify nmcli cloned-mac-address entry
|
||||
command: >-
|
||||
nmcli -f 802-3-ethernet.cloned-mac-address con show {{ item.name }}
|
||||
register: cloned_mac_address
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
loop:
|
||||
- {name: "{{ controller_profile }}", mac: "12:23:34:45:56:60"}
|
||||
- {name: "{{ port1_profile }}", mac: "12:23:34:45:56:61"}
|
||||
- {name: "{{ port2_profile }}", mac: "--"}
|
||||
|
||||
- name: >
|
||||
Assert that cloned-mac-address addresses are configured correctly
|
||||
assert:
|
||||
that:
|
||||
- item.stdout.endswith(item.item.mac)
|
||||
msg: cloned-mac-address is configured incorrectly
|
||||
loop: "{{ cloned_mac_address.results }}"
|
||||
when: network_provider == 'nm'
|
||||
- name: >
|
||||
Assert that cloned-mac-address addresses are configured correctly
|
||||
assert:
|
||||
that:
|
||||
- item.stdout.endswith(item.item.mac)
|
||||
msg: cloned-mac-address is configured incorrectly
|
||||
loop: "{{ cloned_mac_address.results }}"
|
||||
|
||||
- name: Verify the MAC address in {{ controller_profile }}
|
||||
command: >-
|
||||
grep 'MACADDR'
|
||||
/etc/sysconfig/network-scripts/ifcfg-{{ controller_profile }}
|
||||
register: mac_address_controller
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
# mostly interesting for offline provider, but let's cross-check with
|
||||
# online NM to ensure the conditions are valid - except that on some
|
||||
# older versions of NM, the connection files are not created, so we
|
||||
# skip this test on those versions.
|
||||
- name: Verify NM config files
|
||||
when:
|
||||
- network_provider.startswith('nm')
|
||||
- ansible_facts['distribution_major_version'] | int >= 9
|
||||
block:
|
||||
- name: Read profile config files
|
||||
slurp:
|
||||
src: "/etc/NetworkManager/system-connections/{{ item }}.nmconnection"
|
||||
register: config_b64
|
||||
loop:
|
||||
- "{{ controller_profile }}"
|
||||
- "{{ port1_profile }}"
|
||||
- "{{ port2_profile }}"
|
||||
|
||||
- name: Check profile config files
|
||||
assert:
|
||||
that:
|
||||
- "'cloned-mac-address=12:23:34:45:56:60' in config_b64.results[0].content | b64decode"
|
||||
- "'cloned-mac-address=12:23:34:45:56:61' in config_b64.results[1].content | b64decode"
|
||||
- "'cloned-mac-adress=' not in config_b64.results[2].content | b64decode"
|
||||
|
||||
- name: Verify initscripts provider
|
||||
when: network_provider == 'initscripts'
|
||||
block:
|
||||
- name: Verify the MAC address in {{ controller_profile }}
|
||||
command: >-
|
||||
grep 'MACADDR'
|
||||
/etc/sysconfig/network-scripts/ifcfg-{{ controller_profile }}
|
||||
register: mac_address_controller
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Verify the MAC address in {{ port1_profile }}
|
||||
command: >-
|
||||
grep 'MACADDR'
|
||||
/etc/sysconfig/network-scripts/ifcfg-{{ port1_profile }}
|
||||
register: mac_address_port1
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
when: network_provider == 'initscripts'
|
||||
- name: Verify the MAC address in {{ port1_profile }}
|
||||
command: >-
|
||||
grep 'MACADDR'
|
||||
/etc/sysconfig/network-scripts/ifcfg-{{ port1_profile }}
|
||||
register: mac_address_port1
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Assert that MAC addresses are configured correctly for bonding
|
||||
interface
|
||||
assert:
|
||||
that:
|
||||
- mac_address_controller.stdout is search("12:23:34:45:56:60")
|
||||
- mac_address_port1.stdout is search("12:23:34:45:56:61")
|
||||
msg: the MAC addresses are configured incorrectly for bonding
|
||||
interface
|
||||
when: network_provider == 'initscripts'
|
||||
- name: Assert that MAC addresses are configured correctly for bonding
|
||||
interface
|
||||
assert:
|
||||
that:
|
||||
- mac_address_controller.stdout is search("12:23:34:45:56:60")
|
||||
- mac_address_port1.stdout is search("12:23:34:45:56:61")
|
||||
msg: the MAC addresses are configured incorrectly for bonding
|
||||
interface
|
||||
|
||||
always:
|
||||
- name: Clean up the test devices and the connection profiles
|
||||
|
|
@ -127,8 +153,10 @@
|
|||
command: ip link del {{ controller_device }}
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
when: __network_is_booted | bool
|
||||
- name: Import the task 'remove_test_interfaces_with_dhcp.yml'
|
||||
import_tasks: tasks/remove_test_interfaces_with_dhcp.yml
|
||||
when: __network_is_booted | bool
|
||||
- name: Restore the /etc/resolv.conf for initscript
|
||||
command: mv -vf /etc/resolv.conf.bak /etc/resolv.conf
|
||||
when:
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
dhcp_interface2: test2
|
||||
lsr_fail_debug:
|
||||
- __network_connections_result
|
||||
- __install_status
|
||||
bond_options_to_assert:
|
||||
- {key: 'mode', value: '802.3ad'}
|
||||
- {key: 'ad_actor_sys_prio', value: '65535'}
|
||||
|
|
@ -50,7 +51,44 @@
|
|||
- tasks/create_test_interfaces_with_dhcp.yml
|
||||
- tasks/assert_dhcp_device_present.yml
|
||||
lsr_test:
|
||||
- tasks/create_bond_profile.yml
|
||||
- network_connections:
|
||||
# Create a bond controller
|
||||
- name: "{{ controller_profile }}"
|
||||
state: up
|
||||
type: bond
|
||||
interface_name: "{{ controller_device }}"
|
||||
bond:
|
||||
mode: 802.3ad
|
||||
ad_actor_sys_prio: 65535
|
||||
ad_actor_system: 00:00:5e:00:53:5d
|
||||
ad_select: stable
|
||||
ad_user_port_key: 1023
|
||||
all_ports_active: true
|
||||
downdelay: 0
|
||||
lacp_rate: slow
|
||||
lp_interval: 128
|
||||
miimon: 110
|
||||
min_links: 0
|
||||
num_grat_arp: 64
|
||||
primary_reselect: better
|
||||
resend_igmp: 225
|
||||
updelay: 0
|
||||
use_carrier: true
|
||||
xmit_hash_policy: encap2+3
|
||||
ip:
|
||||
route_metric4: 65535
|
||||
# add an ethernet to the bond
|
||||
- name: "{{ port1_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface1 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
# add a second ethernet to the bond
|
||||
- name: "{{ port2_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
lsr_assert:
|
||||
- tasks/assert_controller_device_present.yml
|
||||
- tasks/assert_bond_port_profile_present.yml
|
||||
|
|
@ -59,6 +97,10 @@
|
|||
- tasks/cleanup_bond_profile+device.yml
|
||||
- tasks/remove_test_interfaces_with_dhcp.yml
|
||||
|
||||
- name: Stop test if building image or validation is enabled
|
||||
meta: end_host
|
||||
when: ansible_connection | d("") == "buildah" or __bootc_validation | default(false)
|
||||
|
||||
- name: "Reset bond options to assert"
|
||||
set_fact:
|
||||
bond_options_to_assert:
|
||||
|
|
@ -83,7 +125,32 @@
|
|||
- tasks/create_test_interfaces_with_dhcp.yml
|
||||
- tasks/assert_dhcp_device_present.yml
|
||||
lsr_test:
|
||||
- tasks/create_bond_profile_reconfigure.yml
|
||||
- network_connections:
|
||||
# Create a bond controller
|
||||
- name: "{{ controller_profile }}"
|
||||
state: up
|
||||
type: bond
|
||||
interface_name: "{{ controller_device }}"
|
||||
bond:
|
||||
mode: active-backup
|
||||
arp_interval: 60
|
||||
arp_ip_target: 192.0.2.128
|
||||
arp_validate: none
|
||||
primary: "{{ dhcp_interface1 }}"
|
||||
ip:
|
||||
route_metric4: 65535
|
||||
# add an ethernet to the bond
|
||||
- name: "{{ port1_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface1 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
# add a second ethernet to the bond
|
||||
- name: "{{ port2_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
lsr_assert:
|
||||
- tasks/assert_bond_options.yml
|
||||
lsr_cleanup:
|
||||
|
|
|
|||
|
|
@ -29,7 +29,44 @@
|
|||
- tasks/create_test_interfaces_with_dhcp.yml
|
||||
- tasks/assert_dhcp_device_present.yml
|
||||
lsr_test:
|
||||
- tasks/create_bond_profile.yml
|
||||
- network_connections:
|
||||
# Create a bond controller
|
||||
- name: "{{ controller_profile }}"
|
||||
state: up
|
||||
type: bond
|
||||
interface_name: "{{ controller_device }}"
|
||||
bond:
|
||||
mode: 802.3ad
|
||||
ad_actor_sys_prio: 65535
|
||||
ad_actor_system: 00:00:5e:00:53:5d
|
||||
ad_select: stable
|
||||
ad_user_port_key: 1023
|
||||
all_ports_active: true
|
||||
downdelay: 0
|
||||
lacp_rate: slow
|
||||
lp_interval: 128
|
||||
miimon: 110
|
||||
min_links: 0
|
||||
num_grat_arp: 64
|
||||
primary_reselect: better
|
||||
resend_igmp: 225
|
||||
updelay: 0
|
||||
use_carrier: true
|
||||
xmit_hash_policy: encap2+3
|
||||
ip:
|
||||
route_metric4: 65535
|
||||
# add an ethernet to the bond
|
||||
- name: "{{ port1_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface1 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
# add a second ethernet to the bond
|
||||
- name: "{{ port2_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
- tasks/create_bond_port_match_by_mac.yml
|
||||
lsr_assert:
|
||||
- tasks/assert_controller_device_present.yml
|
||||
|
|
|
|||
|
|
@ -5,51 +5,36 @@
|
|||
vars:
|
||||
interface: LSR-TST-br31
|
||||
tasks:
|
||||
- name: Include the task 'show_interfaces.yml'
|
||||
include_tasks: tasks/show_interfaces.yml
|
||||
|
||||
- name: Include the task 'assert_device_absent.yml'
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
|
||||
- name: Add test bridge
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Include the task 'run_test.yml'
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: bridge
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: true
|
||||
|
||||
- name: Assert device present
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
|
||||
- name: Assert profile present
|
||||
include_tasks: tasks/assert_profile_present.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Include the task 'down_profile+delete_interface.yml'
|
||||
include_tasks: tasks/down_profile+delete_interface.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
# FIXME: assert profile/device down
|
||||
|
||||
- name: Include the task 'remove_profile.yml'
|
||||
include_tasks: tasks/remove_profile.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Assert profile absent
|
||||
include_tasks: tasks/assert_profile_absent.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Assert device absent
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
|
||||
- name: Verify network state restored to default
|
||||
include_tasks: tasks/check_network_dns.yml
|
||||
lsr_description: Test configuring bridges
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/assert_device_absent.yml
|
||||
condition: "{{ not __bootc_validation | d(false) }}"
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: bridge
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: true
|
||||
lsr_assert:
|
||||
- tasks/assert_device_present.yml
|
||||
- what: tasks/assert_profile_present.yml
|
||||
profile: "{{ interface }}"
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- what: tasks/remove_profile.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_profile_absent.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_device_absent.yml
|
||||
profile: "{{ interface }}"
|
||||
- tasks/check_network_dns.yml
|
||||
|
|
|
|||
|
|
@ -6,134 +6,154 @@
|
|||
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
|
||||
- name: Test dns support
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
state: present
|
||||
|
||||
- name: Include the task 'assert_device_present.yml'
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
|
||||
- name: Include network role
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: true
|
||||
ip:
|
||||
route_metric4: 100
|
||||
dhcp4: false
|
||||
gateway4: 192.0.2.1
|
||||
dns_priority: 9999
|
||||
dns:
|
||||
- 192.0.2.2
|
||||
- 198.51.100.5
|
||||
- 2001:db8::20
|
||||
dns_search:
|
||||
- example.com
|
||||
- example.org
|
||||
dns_options:
|
||||
- no-aaaa
|
||||
- rotate
|
||||
- timeout:1
|
||||
|
||||
route_metric6: -1
|
||||
auto6: false
|
||||
gateway6: 2001:db8::1
|
||||
|
||||
address:
|
||||
- 192.0.2.3/24
|
||||
- 198.51.100.3/26
|
||||
- 2001:db8::80/7
|
||||
|
||||
route:
|
||||
- network: 198.51.100.128
|
||||
prefix: 26
|
||||
gateway: 198.51.100.1
|
||||
metric: 2
|
||||
- network: 198.51.100.64
|
||||
prefix: 26
|
||||
gateway: 198.51.100.6
|
||||
metric: 4
|
||||
route_append_only: false
|
||||
rule_append_only: true
|
||||
|
||||
- name: Verify nmcli connection DNS entry for IPv4
|
||||
shell: |
|
||||
set -euxo pipefail
|
||||
nmcli connection show {{ interface }} | grep ipv4.dns
|
||||
register: ipv4_dns
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Verify nmcli connection DNS entry for IPv6
|
||||
shell: |
|
||||
set -euxo pipefail
|
||||
nmcli connection show {{ interface }} | grep ipv6.dns
|
||||
register: ipv6_dns
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: "Assert that DNS addresses are configured correctly"
|
||||
assert:
|
||||
that:
|
||||
- "'192.0.2.2' in ipv4_dns.stdout"
|
||||
- "'198.51.100.5' in ipv4_dns.stdout"
|
||||
- "'2001:db8::20' in ipv6_dns.stdout"
|
||||
msg: "DNS addresses are configured incorrectly"
|
||||
|
||||
- name: "Assert that DNS search domains are configured correctly"
|
||||
assert:
|
||||
that:
|
||||
- "'example.com' in ipv4_dns.stdout"
|
||||
- "'example.org' in ipv4_dns.stdout"
|
||||
- "'example.com' in ipv6_dns.stdout"
|
||||
- "'example.org' in ipv6_dns.stdout"
|
||||
msg: "DNS search domains are configured incorrectly"
|
||||
|
||||
- name: "Assert that DNS options are configured correctly"
|
||||
assert:
|
||||
that:
|
||||
- "'no-aaaa' in ipv4_dns.stdout"
|
||||
- "'rotate' in ipv4_dns.stdout"
|
||||
- "'timeout:1' in ipv4_dns.stdout"
|
||||
- "'no-aaaa' in ipv6_dns.stdout"
|
||||
- "'rotate' in ipv6_dns.stdout"
|
||||
- "'timeout:1' in ipv6_dns.stdout"
|
||||
msg: "DNS options are configured incorrectly"
|
||||
|
||||
- name: "Assert that DNS priority is configured correctly"
|
||||
assert:
|
||||
that:
|
||||
- "'9999' in ipv4_dns.stdout"
|
||||
- "'9999' in ipv6_dns.stdout"
|
||||
msg: "DNS priority is configured incorrectly"
|
||||
|
||||
- name: Include the tasks 'down_profile+delete_interface.yml'
|
||||
include_tasks: tasks/down_profile+delete_interface.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
# FIXME: assert profile/device down
|
||||
- name: Include the task 'remove_profile.yml'
|
||||
include_tasks: tasks/remove_profile.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Include the task 'assert_profile_absent.yml'
|
||||
include_tasks: tasks/assert_profile_absent.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Include the task 'assert_device_absent.yml'
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
|
||||
- name: Verify network state restored to default
|
||||
include_tasks: tasks/check_network_dns.yml
|
||||
lsr_description: Test dns support
|
||||
lsr_setup:
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: true
|
||||
ip:
|
||||
route_metric4: 100
|
||||
dhcp4: false
|
||||
gateway4: 192.0.2.1
|
||||
dns_priority: 9999
|
||||
dns:
|
||||
- 192.0.2.2
|
||||
- 198.51.100.5
|
||||
- 2001:db8::20
|
||||
dns_search:
|
||||
- example.com
|
||||
- example.org
|
||||
dns_options:
|
||||
- no-aaaa
|
||||
- rotate
|
||||
- timeout:1
|
||||
route_metric6: -1
|
||||
auto6: false
|
||||
gateway6: 2001:db8::1
|
||||
address:
|
||||
- 192.0.2.3/24
|
||||
- 198.51.100.3/26
|
||||
- 2001:db8::80/7
|
||||
route:
|
||||
- network: 198.51.100.128
|
||||
prefix: 26
|
||||
gateway: 198.51.100.1
|
||||
metric: 2
|
||||
- network: 198.51.100.64
|
||||
prefix: 26
|
||||
gateway: 198.51.100.6
|
||||
metric: 4
|
||||
route_append_only: false
|
||||
rule_append_only: true
|
||||
lsr_assert:
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- section: connection
|
||||
option: id
|
||||
value: "{{ interface }}"
|
||||
- section: connection
|
||||
option: interface-name
|
||||
value: "{{ interface }}"
|
||||
- section: connection
|
||||
option: type
|
||||
value: ethernet
|
||||
nmvalue: 802-3-ethernet
|
||||
- section: ipv4
|
||||
option: route-metric
|
||||
value: "100"
|
||||
- section: ipv4
|
||||
option: dns
|
||||
value: 192.0.2.2;198.51.100.5;
|
||||
nmvalue: 192.0.2.2,198.51.100.5
|
||||
- section: ipv4
|
||||
option: dns-search
|
||||
value: example.com;example.org;
|
||||
nmvalue: example.com,example.org
|
||||
- section: ipv6
|
||||
option: dns
|
||||
value: 2001:db8::20;
|
||||
nmvalue: 2001:db8::20
|
||||
- section: ipv6
|
||||
option: dns-search
|
||||
value: example.com;example.org;
|
||||
nmvalue: example.com,example.org
|
||||
- section: ipv4
|
||||
option: dns-options
|
||||
value: no-aaaa;rotate;timeout:1;
|
||||
nmvalue: no-aaaa,rotate,timeout:1
|
||||
- section: ipv6
|
||||
option: dns-options
|
||||
value: no-aaaa;rotate;timeout:1;
|
||||
nmvalue: no-aaaa,rotate,timeout:1
|
||||
- section: ipv4
|
||||
option: dns-priority
|
||||
value: 9999
|
||||
- section: ipv6
|
||||
option: dns-priority
|
||||
value: 9999
|
||||
- section: ipv4
|
||||
option: method
|
||||
value: manual
|
||||
- section: ipv6
|
||||
option: method
|
||||
value: manual
|
||||
- section: ipv4
|
||||
option: address1
|
||||
value: 192.0.2.3/24
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: address2
|
||||
value: 198.51.100.3/26
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: addresses
|
||||
nmvalue: 192.0.2.3/24, 198.51.100.3/26
|
||||
- section: ipv6
|
||||
option: address1
|
||||
value: 2001:db8::80/7
|
||||
nmvalue: false
|
||||
- section: ipv6
|
||||
option: addresses
|
||||
nmvalue: 2001:db8::80/7
|
||||
- section: ipv4
|
||||
option: gateway
|
||||
value: 192.0.2.1
|
||||
- section: ipv6
|
||||
option: gateway
|
||||
value: 2001:db8::1
|
||||
- section: ipv4
|
||||
option: route1
|
||||
value: 198.51.100.128/26,198.51.100.1,2
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: route2
|
||||
value: 198.51.100.64/26,198.51.100.6,4
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: routes
|
||||
nmvalue: 198.51.100.128/26 198.51.100.1 2, 198.51.100.64/26 198.51.100.6 4
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- what: tasks/remove_profile.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_profile_absent.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_device_absent.yml
|
||||
profile: "{{ interface }}"
|
||||
- tasks/check_network_dns.yml
|
||||
|
|
|
|||
|
|
@ -10,106 +10,79 @@
|
|||
debug:
|
||||
msg: Inside ethernet tests
|
||||
|
||||
- name: Show network_provider
|
||||
debug:
|
||||
var: network_provider
|
||||
|
||||
- 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 static interface up
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: true
|
||||
ip:
|
||||
address: 192.0.2.1/24
|
||||
|
||||
- name: Include the task 'assert_output_in_stderr_without_warnings.yml'
|
||||
include_tasks: tasks/assert_output_in_stderr_without_warnings.yml
|
||||
|
||||
- name: Show network_provider after running role
|
||||
debug:
|
||||
var: network_provider
|
||||
|
||||
- name: Get NM connection file
|
||||
slurp:
|
||||
src: "/etc/NetworkManager/system-connections/{{ interface }}.nmconnection"
|
||||
register: nm_connection_file
|
||||
when:
|
||||
- network_provider == 'nm'
|
||||
# RHEL up to 8 uses initscripts backend
|
||||
- ansible_distribution_major_version | int >= 9
|
||||
|
||||
- name: Assert settings in NM connection file
|
||||
assert:
|
||||
that:
|
||||
- "('interface-name=' + interface) in nm_connection_file.content | b64decode"
|
||||
- "'type=ethernet' in nm_connection_file.content | b64decode"
|
||||
- "'address1=192.0.2.1/24' in nm_connection_file.content | b64decode"
|
||||
- "'method=manual' in nm_connection_file.content | b64decode"
|
||||
when:
|
||||
- network_provider == 'nm'
|
||||
# RHEL up to 8 uses initscripts backend
|
||||
- ansible_distribution_major_version | int >= 9
|
||||
|
||||
- name: Get NM connection status
|
||||
command: "nmcli connection show {{ interface }}"
|
||||
changed_when: false
|
||||
register: nm_connection_status
|
||||
when: network_provider == 'nm'
|
||||
|
||||
- name: Assert NM connection status
|
||||
assert:
|
||||
that:
|
||||
- nm_connection_status.stdout is search("ipv4.addresses:\s+192.0.2.1/24")
|
||||
when: network_provider == 'nm'
|
||||
|
||||
- name: Get initscripts connection file
|
||||
slurp:
|
||||
src: "/etc/sysconfig/network-scripts/ifcfg-{{ interface }}"
|
||||
register: initscripts_connection_file
|
||||
when: network_provider == 'initscripts' or ansible_distribution_major_version | int < 9
|
||||
|
||||
- name: Assert settings in initscripts connection file
|
||||
assert:
|
||||
that:
|
||||
- "'TYPE=Ethernet' in initscripts_connection_file.content | b64decode"
|
||||
- "'DEVICE={{ interface }}' in initscripts_connection_file.content | b64decode"
|
||||
- "'IPADDR=192.0.2.1' in initscripts_connection_file.content | b64decode"
|
||||
- "'PREFIX=24' in initscripts_connection_file.content | b64decode"
|
||||
when: network_provider == 'initscripts' or ansible_distribution_major_version | int < 9
|
||||
|
||||
- name: Include the tasks 'down_profile+delete_interface.yml'
|
||||
include_tasks: tasks/down_profile+delete_interface.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
# FIXME: assert profile/device down
|
||||
- name: Include the task 'remove_profile.yml'
|
||||
include_tasks: tasks/remove_profile.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
|
||||
- name: Include the task 'assert_profile_absent.yml'
|
||||
include_tasks: tasks/assert_profile_absent.yml
|
||||
vars:
|
||||
profile: "{{ interface }}"
|
||||
- name: Include the task 'assert_device_absent.yml'
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
|
||||
- name: Verify network state restored to default
|
||||
include_tasks: tasks/check_network_dns.yml
|
||||
- name: Test creating the bridge connection
|
||||
tags:
|
||||
- tests::states:create
|
||||
block:
|
||||
- name: Include the task 'run_test.yml'
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
lsr_description: I can create a profile
|
||||
lsr_setup:
|
||||
- what: tasks/delete_interface.yml
|
||||
condition: "{{ not __bootc_validation | default(false) }}"
|
||||
- what: tasks/assert_device_absent.yml
|
||||
condition: "{{ not __bootc_validation | default(false) }}"
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
interface_name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: true
|
||||
ip:
|
||||
address: 192.0.2.1/24
|
||||
lsr_assert:
|
||||
- tasks/assert_output_in_stderr_without_warnings.yml
|
||||
- tasks/assert_device_present.yml
|
||||
# Device should be present because of autoconnect: true by
|
||||
# default for NM (this might be considered a bug)
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- section: connection
|
||||
option: interface-name
|
||||
value: "{{ interface }}"
|
||||
- section: connection
|
||||
option: type
|
||||
value: ethernet
|
||||
nmvalue: 802-3-ethernet
|
||||
- section: ipv4
|
||||
option: address1
|
||||
value: 192.0.2.1/24
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: addresses
|
||||
nmvalue: 192.0.2.1/24
|
||||
- section: ipv4
|
||||
option: method
|
||||
value: manual
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'initscripts' or ansible_distribution_major_version | int < 9 }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- TYPE=Ethernet
|
||||
- DEVICE={{ interface }}
|
||||
- IPADDR=192.0.2.1
|
||||
- PREFIX=24
|
||||
- what: tasks/assert_nm_connection_status.yml
|
||||
condition: "{{ network_provider == 'nm' and __network_is_booted }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_output: 'ipv4.addresses:\s+192.0.2.1/24'
|
||||
lsr_cleanup:
|
||||
- what: tasks/down_profile+delete_interface.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
lsr_persistent_state: absent
|
||||
- what: tasks/remove_profile.yml
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_profile_absent.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
profile: "{{ interface }}"
|
||||
- what: tasks/assert_device_absent.yml
|
||||
profile: "{{ interface }}"
|
||||
- tasks/check_network_dns.yml
|
||||
|
|
|
|||
|
|
@ -12,153 +12,117 @@
|
|||
tags:
|
||||
- always
|
||||
|
||||
- name: "INIT: Ethtool coalesce tests"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- 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: Install ethtool (test dependency)
|
||||
package:
|
||||
name: ethtool
|
||||
state: present
|
||||
use: "{{ (__network_is_ostree | d(false)) |
|
||||
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
|
||||
- name: Include network role vars used by tests
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
tasks_from: set_facts.yml
|
||||
public: true
|
||||
|
||||
- name: Test ethtool coalesce settings
|
||||
- name: Run tests
|
||||
block:
|
||||
- name: >-
|
||||
TEST: I can create a profile without any coalescing option.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Test creating profile without changing ethtool coalesce settings
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_description: Test creating profile without changing ethtool coalesce
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_assert: # NOTE: Cleanup is done in always at very end of file
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface | quote }}
|
||||
lsr_not_stdout: coalesce
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: cat /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_not_stdout: ETHTOOL
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: Get profile's coalescing options
|
||||
command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface }}
|
||||
register: no_coalesce_nm
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does not contain coalescing options"
|
||||
assert:
|
||||
that: no_coalesce_nm.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's coalescing options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: no_coalesce_initscripts
|
||||
ignore_errors: true
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does not contain coalescing options"
|
||||
assert:
|
||||
that: no_coalesce_initscripts.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
|
||||
- name: >-
|
||||
TEST: I can set rx-frames.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: "TEST: I can set rx-frames."
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
ethtool:
|
||||
coalesce:
|
||||
rx_frames: 128
|
||||
- name: Get profile's coalescing options
|
||||
command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface }}
|
||||
register: with_coalesce_nm
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: Assert coalesce options set in profile
|
||||
assert:
|
||||
that: with_coalesce_nm.stdout == '128'
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
lsr_description: Test setting coalesce option
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
ethtool:
|
||||
coalesce:
|
||||
rx_frames: 128
|
||||
lsr_assert:
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- section: ethtool
|
||||
option: coalesce-rx-frames
|
||||
value: "128"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface | quote }}
|
||||
lsr_stdout: "128"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_stdout: rx-frames 128
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: Get profile's coalescing options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: with_coalesce_initscripts
|
||||
ignore_errors: true
|
||||
- name: Test clearing ethtool coalesce settings
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: Assert coalesce options set in profile
|
||||
assert:
|
||||
that: '"rx-frames 128" in with_coalesce_initscripts.stdout'
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
|
||||
- name: "TEST: I can clear coalescing options"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
|
||||
- name: Get profile's coalescing options
|
||||
command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface }}
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
register: clear_coalesce_nm
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does reset coalescing options"
|
||||
assert:
|
||||
that: clear_coalesce_nm.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's coalescing options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: clear_coalesce_initscripts
|
||||
ignore_errors: true
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does reset coalescing options"
|
||||
assert:
|
||||
that: clear_coalesce_initscripts.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
lsr_description: Test creating profile without changing ethtool features
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_assert: # NOTE: Cleanup is done in always at very end of file
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_command: nmcli -g ethtool.coalesce-rx-frames c show {{ interface | quote }}
|
||||
lsr_not_stdout: coalesce
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: cat /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_not_stdout: ETHTOOL
|
||||
lsr_cleanup: []
|
||||
|
||||
always:
|
||||
- name: Clean up the test device and the connection profile
|
||||
when: ansible_connection != "buildah"
|
||||
tags:
|
||||
- "tests::cleanup"
|
||||
block:
|
||||
|
|
|
|||
|
|
@ -12,137 +12,66 @@
|
|||
tags:
|
||||
- always
|
||||
|
||||
- name: "INIT: Ethtool feeatures tests"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- 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: Install ethtool (test dependency)
|
||||
package:
|
||||
name: ethtool
|
||||
state: present
|
||||
use: "{{ (__network_is_ostree | d(false)) |
|
||||
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
|
||||
- name: Include network role vars used by tests
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
tasks_from: set_facts.yml
|
||||
public: true
|
||||
|
||||
- name: Test ethtool features settings
|
||||
- name: Run tests
|
||||
block:
|
||||
- name: >-
|
||||
TEST: I can create a profile without changing the ethtool features.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Get current device features
|
||||
command: "ethtool --show-features {{ interface }}"
|
||||
register: original_ethtool_features
|
||||
changed_when: false
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Test creating profile without changing ethtool features
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
- name: Get current device features
|
||||
command: "ethtool --show-features {{ interface }}"
|
||||
register: ethtool_features
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does not change the ethtool features"
|
||||
assert:
|
||||
that:
|
||||
- original_ethtool_features.stdout == ethtool_features.stdout
|
||||
lsr_description: Test creating profile without changing ethtool features
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
- what: tasks/assert_command_output.yml
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
lsr_assert: # NOTE: Cleanup is done in always at very end of file
|
||||
- what: tasks/assert_command_output.yml
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_stdout: "{{ __previous_command_output.stdout }}"
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: >-
|
||||
TEST: I can disable gro and tx-tcp-segmentation and enable gso.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Set original ethtool features
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
set_fact:
|
||||
original_ethtool_features: "{{ __previous_command_output }}"
|
||||
|
||||
- name: "TEST: I can disable gro and tx-tcp-segmentation and enable gso."
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
ethtool:
|
||||
features:
|
||||
gro: "no"
|
||||
gso: "yes"
|
||||
tx-tcp-segmentation: "no"
|
||||
- name: Get current device features
|
||||
command: "ethtool --show-features {{ interface }}"
|
||||
register: ethtool_features
|
||||
changed_when: false
|
||||
- name: Show ethtool_features
|
||||
debug:
|
||||
var: ethtool_features.stdout_lines
|
||||
- name: Assert device features
|
||||
assert:
|
||||
that:
|
||||
- >-
|
||||
'generic-receive-offload: off' in
|
||||
ethtool_features.stdout_lines
|
||||
- >-
|
||||
'generic-segmentation-offload: on' in
|
||||
ethtool_features.stdout_lines
|
||||
- >-
|
||||
'tx-tcp-segmentation: off' in
|
||||
ethtool_features.stdout_lines | map('trim')
|
||||
|
||||
- name: >-
|
||||
TEST: I can enable tx_tcp_segmentation (using underscores).
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
ethtool:
|
||||
features:
|
||||
tx_tcp_segmentation: "yes"
|
||||
- name: Get current device features
|
||||
command: "ethtool --show-features {{ interface }}"
|
||||
register: ethtool_features
|
||||
changed_when: false
|
||||
- name: Show ethtool_features
|
||||
debug:
|
||||
var: ethtool_features.stdout_lines
|
||||
- name: Assert device features
|
||||
assert:
|
||||
that:
|
||||
- >-
|
||||
'tx-tcp-segmentation: on' in
|
||||
ethtool_features.stdout_lines | map('trim')
|
||||
|
||||
- name: I cannot change tx_tcp_segmentation and tx-tcp-segmentation at
|
||||
the same time.
|
||||
block:
|
||||
- name: >-
|
||||
TEST: Change feature with both underscores and dashes.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Configure ethtool features setting
|
||||
network_connections:
|
||||
provider: "{{ network_provider | mandatory }}"
|
||||
connections:
|
||||
lsr_description: Test creating profile without changing ethtool features
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
|
|
@ -151,10 +80,90 @@
|
|||
auto6: "no"
|
||||
ethtool:
|
||||
features:
|
||||
tx_tcp_segmentation: "no"
|
||||
gro: "no"
|
||||
gso: "yes"
|
||||
tx-tcp-segmentation: "no"
|
||||
__header: "# Ansible managed test header"
|
||||
register: __network_connections_result
|
||||
lsr_assert:
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- section: ethtool
|
||||
option: feature-gro
|
||||
value: "false"
|
||||
nmvalue: "off"
|
||||
- section: ethtool
|
||||
option: feature-gso
|
||||
value: "true"
|
||||
nmvalue: "on"
|
||||
- section: ethtool
|
||||
option: feature-tx-tcp-segmentation
|
||||
value: "false"
|
||||
nmvalue: "off"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_stdout_lines:
|
||||
- "generic-receive-offload: off"
|
||||
- "generic-segmentation-offload: on"
|
||||
- "\ttx-tcp-segmentation: off" # noqa no-tabs
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: >-
|
||||
TEST: I can enable tx_tcp_segmentation (using underscores).
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
lsr_description: Test enabling tx_tcp_segmentation (using underscores)
|
||||
lsr_setup: []
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
ethtool:
|
||||
features:
|
||||
tx_tcp_segmentation: "yes"
|
||||
lsr_assert:
|
||||
- what: tasks/assert_command_output.yml
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_stdout_lines:
|
||||
- "\ttx-tcp-segmentation: on" # noqa no-tabs
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: I cannot change tx_tcp_segmentation and tx-tcp-segmentation at
|
||||
the same time.
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
block:
|
||||
- name: >-
|
||||
TEST: Change feature with both underscores and dashes.
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
lsr_description: Test changing feature with both underscores and dashes
|
||||
lsr_setup: []
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
ethtool:
|
||||
features:
|
||||
tx_tcp_segmentation: "no"
|
||||
tx-tcp-segmentation: "no"
|
||||
lsr_assert: []
|
||||
lsr_cleanup: []
|
||||
rescue:
|
||||
- name: Show network_connections result
|
||||
debug:
|
||||
|
|
@ -168,7 +177,6 @@
|
|||
fatal error: configuration error:
|
||||
connections[0].ethtool.features: duplicate key
|
||||
'tx_tcp_segmentation'
|
||||
|
||||
always:
|
||||
- name: Check failure
|
||||
debug:
|
||||
|
|
@ -178,32 +186,30 @@
|
|||
that: __network_connections_result.failed
|
||||
|
||||
- name: "TEST: I can reset features to their original value."
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
- name: Get current device features
|
||||
command: "ethtool --show-features {{ interface }}"
|
||||
register: ethtool_features
|
||||
changed_when: false
|
||||
# Resetting the ethtools only works with NetworkManager
|
||||
- name: "ASSERT: The profile does not change the ethtool features"
|
||||
assert:
|
||||
that:
|
||||
- original_ethtool_features.stdout == ethtool_features.stdout
|
||||
when:
|
||||
network_provider == 'nm'
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
lsr_description: Test resetting features to their original value
|
||||
lsr_setup: []
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
ip:
|
||||
dhcp4: "no"
|
||||
auto6: "no"
|
||||
lsr_assert:
|
||||
- what: tasks/assert_command_output.yml
|
||||
lsr_packages: [ethtool]
|
||||
lsr_command: ethtool --show-features {{ interface | quote }}
|
||||
lsr_stdout: "{{ original_ethtool_features.stdout }}"
|
||||
lsr_cleanup: []
|
||||
always:
|
||||
- name: Clean up the test device and the connection profile
|
||||
when: ansible_connection != "buildah"
|
||||
tags:
|
||||
- "tests::cleanup"
|
||||
block:
|
||||
|
|
|
|||
|
|
@ -12,194 +12,129 @@
|
|||
tags:
|
||||
- always
|
||||
|
||||
- name: "INIT: Ethtool ring tests"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- 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: Install ethtool (test dependency)
|
||||
package:
|
||||
name: ethtool
|
||||
state: present
|
||||
use: "{{ (__network_is_ostree | d(false)) |
|
||||
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
|
||||
- name: Include network role vars used by tests
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
tasks_from: set_facts.yml
|
||||
public: true
|
||||
|
||||
- name: Test ethtool ring settings
|
||||
- name: Run tests
|
||||
block:
|
||||
- name: >-
|
||||
TEST: I can create a profile without any ring option.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Test creating profile without changing ethtool ring settings
|
||||
when:
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_description: Test creating profile without changing ethtool ring settings
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_assert: # NOTE: Cleanup is done in always at very end of file
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_command: nmcli -g ethtool.ring-rx c show {{ interface | quote }}
|
||||
lsr_not_stdout: ring-rx
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: cat /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_not_stdout: ETHTOOL
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: Get profile's ring options
|
||||
command: nmcli -g ethtool.ring-rx c show {{ interface }}
|
||||
register: no_ring_nm
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does not contain ring options"
|
||||
assert:
|
||||
that: no_ring_nm.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's ring options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: no_ring_initscripts
|
||||
ignore_errors: true
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does not contain ring options"
|
||||
assert:
|
||||
that: no_ring_initscripts.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
|
||||
- name: >-
|
||||
TEST: I can set rx.
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: "TEST: I can set rx ring settings."
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
ethtool:
|
||||
ring:
|
||||
rx: 128
|
||||
rx_jumbo: 128
|
||||
rx_mini: 128
|
||||
tx: 128
|
||||
lsr_description: Test setting rx ring settings
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
ethtool:
|
||||
ring:
|
||||
rx: 128
|
||||
rx_jumbo: 128
|
||||
rx_mini: 128
|
||||
tx: 128
|
||||
lsr_assert:
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface }}"
|
||||
lsr_connection_settings:
|
||||
- section: ethtool
|
||||
option: ring-rx
|
||||
value: "128"
|
||||
- section: ethtool
|
||||
option: ring-rx-jumbo
|
||||
value: "128"
|
||||
- section: ethtool
|
||||
option: ring-rx-mini
|
||||
value: "128"
|
||||
- section: ethtool
|
||||
option: ring-tx
|
||||
value: "128"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_stdout_lines:
|
||||
- rx 128
|
||||
- rx-jumbo 128
|
||||
- rx-mini 128
|
||||
- tx 128
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: Get profile's ethtool.ring-rx options
|
||||
command: nmcli -g ethtool.ring-rx c show {{ interface }}
|
||||
register: with_ring_rx
|
||||
- name: Test clearing ethtool ring settings
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: Assert ethtool.ring-rx option set in profile
|
||||
assert:
|
||||
that: with_ring_rx.stdout == '128'
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's ethtool.ring-rx-jumbo options
|
||||
command: nmcli -g ethtool.ring-rx-jumbo c show {{ interface }}
|
||||
register: with_ring_rx_jumbo
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: Assert ethtool.ring-rx-jumbo option set in profile
|
||||
assert:
|
||||
that: with_ring_rx_jumbo.stdout == '128'
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's ethtool.ring-rx-mini options
|
||||
command: nmcli -g ethtool.ring-rx-mini c show {{ interface }}
|
||||
register: with_ring_rx_mini
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: Assert ethtool.ring-rx-mini option set in profile
|
||||
assert:
|
||||
that: with_ring_rx_mini.stdout == '128'
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's ethtool.ring-tx options
|
||||
command: nmcli -g ethtool.ring-tx c show {{ interface }}
|
||||
register: with_ring_tx
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: Assert ethtool.ring-tx option set in profile
|
||||
assert:
|
||||
that: with_ring_tx.stdout == '128'
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
|
||||
- name: Get profile's ethtool.ring options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: with_ring
|
||||
ignore_errors: true
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: Assert ethtool.ring option set in profile
|
||||
assert:
|
||||
that:
|
||||
- '"rx 128" in with_ring.stdout'
|
||||
- '"rx-jumbo 128" in with_ring.stdout'
|
||||
- '"rx-mini 128" in with_ring.stdout'
|
||||
- '"tx 128" in with_ring.stdout'
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
|
||||
- name: "TEST: I can clear ring options"
|
||||
debug:
|
||||
msg: "##################################################"
|
||||
- name: Import network role
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
|
||||
- name: Get profile's ring options
|
||||
command: nmcli -g ethtool.ring-rx c show {{ interface }}
|
||||
register: clear_ring_nm
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does reset ring options"
|
||||
assert:
|
||||
that: clear_ring_nm.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- name: Get profile's ring options
|
||||
command:
|
||||
grep ETHTOOL /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
register: clear_ring_initscripts
|
||||
ignore_errors: true
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
changed_when: false
|
||||
- name: "ASSERT: The profile does reset ring options"
|
||||
assert:
|
||||
that: clear_ring_initscripts.stdout | length == 0
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
lsr_description: Test clearing ethtool ring settings
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
- tasks/assert_device_present.yml
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface }}"
|
||||
type: ethernet
|
||||
state: up
|
||||
ip:
|
||||
dhcp4: false
|
||||
auto6: false
|
||||
lsr_assert: # NOTE: Cleanup is done in always at very end of file
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_command: nmcli -g ethtool.ring-rx c show {{ interface | quote }}
|
||||
lsr_not_stdout: ring-rx
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ network_provider == 'initscripts' }}"
|
||||
lsr_command: cat /etc/sysconfig/network-scripts/ifcfg-{{ interface | quote }}
|
||||
lsr_not_stdout: ETHTOOL
|
||||
lsr_cleanup: []
|
||||
|
||||
always:
|
||||
- name: Clean up the test device and the connection profile
|
||||
when: ansible_connection != "buildah"
|
||||
tags:
|
||||
- "tests::cleanup"
|
||||
block:
|
||||
|
|
|
|||
|
|
@ -36,27 +36,52 @@
|
|||
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
|
||||
# the nmcli and .nmconnection file formats are very different, so we
|
||||
# need to do online and offline checks in different code paths
|
||||
- name: Online check
|
||||
when: __network_is_booted | bool
|
||||
block:
|
||||
- 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: 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: 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 ipv6.ignore-auto-dns is 'yes'
|
||||
assert:
|
||||
that:
|
||||
- "'yes' in ipv6_ignore_auto_dns.stdout"
|
||||
msg: "the setting ipv6.ignore-auto-dns is 'no'"
|
||||
- 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'"
|
||||
|
||||
- name: Offline check
|
||||
when: not __network_is_booted | bool
|
||||
block:
|
||||
# noqa command-instead-of-module
|
||||
- name: Check that .nmconnection file has no ipv4.ignore-auto-dns setting
|
||||
command: >
|
||||
sed -n '/^\[ipv4\]/,/^$/ {/ignore-auto-dns=/p}' /etc/NetworkManager/system-connections/{{ interface }}.nmconnection
|
||||
changed_when: false
|
||||
register: ipv4_ignore_auto_dns_file
|
||||
failed_when: ipv4_ignore_auto_dns_file.stdout | trim != ""
|
||||
|
||||
# noqa command-instead-of-module
|
||||
- name: Check that .nmconnection file has ipv6.ignore-auto-dns setting
|
||||
command: >
|
||||
sed -n '/^\[ipv6\]/,/^$/ {/ignore-auto-dns=/p}' /etc/NetworkManager/system-connections/{{ interface }}.nmconnection
|
||||
changed_when: false
|
||||
register: ipv6_ignore_auto_dns_file
|
||||
failed_when: ipv6_ignore_auto_dns_file.stdout | trim != "ignore-auto-dns=true"
|
||||
|
||||
always:
|
||||
- name: Remove test configuration
|
||||
|
|
|
|||
|
|
@ -44,10 +44,13 @@
|
|||
vars:
|
||||
errmsg: ip.ipv6_disabled is not supported by the running version of NetworkManager
|
||||
|
||||
- name: Verify nmcli connection ipv6.method
|
||||
shell: |
|
||||
set -euxo pipefail
|
||||
nmcli connection show {{ interface }} | grep ipv6.method
|
||||
- name: Verify NM connection ipv6.method
|
||||
command: >-
|
||||
{{
|
||||
("nmcli -f ipv6.method connection show " ~ interface)
|
||||
if __network_is_booted else
|
||||
("sed -n '/^\[ipv6\]/,/^$/ {/method=/p}' /etc/NetworkManager/system-connections/" ~ interface ~ ".nmconnection")
|
||||
}}
|
||||
register: ipv6_method
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
|
|
|||
|
|
@ -21,13 +21,23 @@
|
|||
- 192.0.2.1/24
|
||||
state: up
|
||||
- name: Get DNS search entry for IPv4
|
||||
command: nmcli -f ipv4.dns-search connection show br-example
|
||||
command: >-
|
||||
{{
|
||||
"nmcli -f ipv4.dns-search connection show br-example"
|
||||
if __network_is_booted else
|
||||
"sed -n '/^\[ipv4\]/,/^$/ {/dns-search=/p}' /etc/NetworkManager/system-connections/br-example.nmconnection"
|
||||
}}
|
||||
register: ipv4_dns_search
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
||||
- name: Get DNS search entry for IPv6
|
||||
command: nmcli -f ipv6.dns-search connection show br-example
|
||||
command: >-
|
||||
{{
|
||||
"nmcli -f ipv6.dns-search connection show br-example"
|
||||
if __network_is_booted else
|
||||
"sed -n '/^\[ipv6\]/,/^$/ {/dns-search=/p}' /etc/NetworkManager/system-connections/br-example.nmconnection"
|
||||
}}
|
||||
register: ipv6_dns_search
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
|
@ -67,7 +77,12 @@
|
|||
state: up
|
||||
|
||||
- name: Get DNS search entry for IPv6
|
||||
command: nmcli -f ipv6.dns-search connection show br-example
|
||||
command: >-
|
||||
{{
|
||||
"nmcli -f ipv6.dns-search connection show br-example"
|
||||
if __network_is_booted else
|
||||
"sed -n '/^\[ipv6\]/,/^$/ {/dns-search=/p}' /etc/NetworkManager/system-connections/br-example.nmconnection"
|
||||
}}
|
||||
register: ipv6_dns_search_static
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
|
@ -99,7 +114,12 @@
|
|||
state: up
|
||||
|
||||
- name: Get DNS search entry for IPv6
|
||||
command: nmcli -f ipv6.dns-search connection show br-example
|
||||
command: >-
|
||||
{{
|
||||
"nmcli -f ipv6.dns-search connection show br-example"
|
||||
if __network_is_booted else
|
||||
"sed -n '/^\[ipv6\]/,/^$/ {/dns-search=/p}' /etc/NetworkManager/system-connections/br-example.nmconnection"
|
||||
}}
|
||||
register: ipv6_dns_search_static_only
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
|
|
|||
|
|
@ -2,6 +2,9 @@
|
|||
---
|
||||
- name: Play for configuring network using network state variable
|
||||
hosts: all
|
||||
tags:
|
||||
# this is runtime configuration and checks
|
||||
- tests::booted
|
||||
vars:
|
||||
type: veth
|
||||
interface0: ethtest0
|
||||
|
|
|
|||
|
|
@ -8,111 +8,121 @@
|
|||
interface1: ethtest1
|
||||
|
||||
tasks:
|
||||
- name: Set type and interface0
|
||||
set_fact:
|
||||
type: "{{ type }}"
|
||||
interface: "{{ interface0 }}"
|
||||
- name: Show interfaces
|
||||
include_tasks: tasks/show_interfaces.yml
|
||||
- name: Manage test interface
|
||||
include_tasks: tasks/manage_test_interface.yml
|
||||
vars:
|
||||
state: present
|
||||
- name: Assert device is present
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
- name: Set interface1
|
||||
set_fact:
|
||||
interface: "{{ interface1 }}"
|
||||
- name: Show interfaces again
|
||||
include_tasks: tasks/show_interfaces.yml
|
||||
- name: Manage test interface with second interface
|
||||
include_tasks: tasks/manage_test_interface.yml
|
||||
vars:
|
||||
state: present
|
||||
- name: Assert device is present with second interface
|
||||
include_tasks: tasks/assert_device_present.yml
|
||||
- name: Test the route or the warning log when configuring the route with
|
||||
or without the interface name
|
||||
block:
|
||||
- name: Configure the IP addresses and the route with interface name
|
||||
specified
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
- name: Test the route or the warning log when configuring the route with
|
||||
or without the interface name
|
||||
include_tasks: tasks/run_test.yml
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface0 }}"
|
||||
interface_name: "{{ interface0 }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: false
|
||||
ip:
|
||||
address:
|
||||
- 198.51.100.3/24
|
||||
- 2001:db8::2/32
|
||||
route:
|
||||
- network: 198.51.10.64
|
||||
prefix: 26
|
||||
gateway: 198.51.100.6
|
||||
metric: 4
|
||||
- network: 2001:db6::4
|
||||
prefix: 128
|
||||
gateway: 2001:db8::1
|
||||
metric: 2
|
||||
- name: "{{ interface1 }}"
|
||||
interface_name: "{{ interface1 }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
autoconnect: false
|
||||
ip:
|
||||
address:
|
||||
- 198.51.100.6/24
|
||||
- 2001:db8::4/32
|
||||
route:
|
||||
- network: 198.51.12.128
|
||||
prefix: 26
|
||||
gateway: 198.51.100.1
|
||||
metric: 2
|
||||
- name: Get the IPv4 routes from the route table main
|
||||
command: ip -4 route
|
||||
register: route_table_main_ipv4
|
||||
changed_when: false
|
||||
lsr_description: Test the route or the warning log when configuring the route with
|
||||
or without the interface name
|
||||
lsr_setup:
|
||||
- tasks/show_interfaces.yml
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
lsr_interface: "{{ interface0 }}"
|
||||
- what: tasks/assert_device_present.yml
|
||||
lsr_interface: "{{ interface0 }}"
|
||||
- what: tasks/manage_test_interface.yml
|
||||
state: present
|
||||
lsr_interface: "{{ interface1 }}"
|
||||
- what: tasks/assert_device_present.yml
|
||||
lsr_interface: "{{ interface1 }}"
|
||||
lsr_test:
|
||||
- network_connections:
|
||||
- name: "{{ interface0 }}"
|
||||
interface_name: "{{ interface0 }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
# Set autoconnect to true for buildah connection, otherwise,
|
||||
# the test will need to start the connection manually
|
||||
autoconnect: "{{ ansible_connection | d('') == 'buildah'}}"
|
||||
ip:
|
||||
address:
|
||||
- 198.51.100.3/24
|
||||
- 2001:db8::2/32
|
||||
route:
|
||||
- network: 198.51.10.64
|
||||
prefix: 26
|
||||
gateway: 198.51.100.6
|
||||
metric: 4
|
||||
- network: 2001:db6::4
|
||||
prefix: 128
|
||||
gateway: 2001:db8::1
|
||||
metric: 2
|
||||
- name: "{{ interface1 }}"
|
||||
interface_name: "{{ interface1 }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
# Set autoconnect to true for buildah connection, otherwise,
|
||||
# the test will need to start the connection manually
|
||||
autoconnect: "{{ ansible_connection | d('') == 'buildah'}}"
|
||||
ip:
|
||||
address:
|
||||
- 198.51.100.6/24
|
||||
- 2001:db8::4/32
|
||||
route:
|
||||
- network: 198.51.12.128
|
||||
prefix: 26
|
||||
gateway: 198.51.100.1
|
||||
metric: 2
|
||||
lsr_assert:
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface0 }}"
|
||||
lsr_connection_settings:
|
||||
- section: ipv4
|
||||
option: route1
|
||||
value: 198.51.10.64/26,198.51.100.6,4
|
||||
nmvalue: false
|
||||
ifcfg_route_value: ADDRESS0=198.51.10.64
|
||||
- section: ipv4
|
||||
option: routes
|
||||
nmvalue: 198.51.10.64/26 198.51.100.6 4
|
||||
- section: ipv6
|
||||
option: route1
|
||||
value: 2001:db6::4/128,2001:db8::1,2
|
||||
nmvalue: false
|
||||
ifcfg_route6_value: 2001:db6::4/128 via 2001:db8::1 metric 2
|
||||
- section: ipv6
|
||||
option: routes
|
||||
nmvalue: 2001:db6::4/128 2001:db8::1 2
|
||||
- what: tasks/assert_connection_settings.yml
|
||||
condition: "{{ network_provider == 'nm' }}"
|
||||
lsr_connection_name: "{{ interface1 }}"
|
||||
lsr_connection_settings:
|
||||
- section: ipv4
|
||||
option: route1
|
||||
value: 198.51.12.128/26,198.51.100.1,2
|
||||
nmvalue: false
|
||||
- section: ipv4
|
||||
option: routes
|
||||
nmvalue: 198.51.12.128/26 198.51.100.1 2
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_command: ip -4 route
|
||||
lsr_stdout_regex_list:
|
||||
- "198.51.10.64/26 via 198.51.100.6 dev ethtest0\\s+(proto static )?metric 4"
|
||||
- "198.51.12.128/26 via 198.51.100.1 dev ethtest1\\s+(proto static )?metric 2"
|
||||
- what: tasks/assert_command_output.yml
|
||||
condition: "{{ __network_is_booted }}"
|
||||
lsr_command: ip -6 route
|
||||
lsr_stdout_regex_list:
|
||||
- "2001:db6::4 via 2001:db8::1 dev ethtest0\\s+(proto static )?metric 2"
|
||||
lsr_cleanup: []
|
||||
|
||||
- name: Assert that the route table main contains the specified IPv4
|
||||
routes
|
||||
assert:
|
||||
that:
|
||||
# When running with nm provider, the route will be configured
|
||||
# with `proto static`
|
||||
# In RHEL-6.10 managed host, the attribute in the route is not
|
||||
# equally spaced
|
||||
- route_table_main_ipv4.stdout is search("198.51.10.64/26 via
|
||||
198.51.100.6 dev ethtest0\s+(proto static )?metric 4")
|
||||
- route_table_main_ipv4.stdout is search("198.51.12.128/26 via
|
||||
198.51.100.1 dev ethtest1\s+(proto static )?metric 2")
|
||||
msg: "the route table main does not contain the specified IPv4
|
||||
route"
|
||||
|
||||
- name: Get the IPv6 routes from the route table main
|
||||
command: ip -6 route
|
||||
register: route_table_main_ipv6
|
||||
changed_when: false
|
||||
|
||||
- name: Assert that the route table main contains the specified IPv6
|
||||
routes
|
||||
assert:
|
||||
that:
|
||||
- route_table_main_ipv6.stdout is search("2001:db6::4 via
|
||||
2001:db8::1 dev ethtest0\s+(proto static )?metric 2")
|
||||
msg: "the route table main does not contain the specified IPv6
|
||||
route"
|
||||
- name: Get the interface1 MAC address
|
||||
command: cat /sys/class/net/{{ interface1 }}/address
|
||||
register: interface1_mac
|
||||
changed_when: false
|
||||
when: __network_is_booted and not __bootc_validation | d(false)
|
||||
|
||||
- name: Configure the IP addresses and the route with only the MAC
|
||||
address specified
|
||||
import_role:
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
when: __network_is_booted and not __bootc_validation | d(false)
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface1 }}"
|
||||
|
|
@ -133,28 +143,37 @@
|
|||
the output device is logged for initscripts provider
|
||||
assert:
|
||||
that:
|
||||
- __network_connections_result.stderr is search("\[003\]
|
||||
<warn> .0, state.None persistent_state.present,
|
||||
'{{ interface1 }}'. The connection {{ interface1 }} does not
|
||||
specify an interface name. Therefore, the route to
|
||||
198.58.10.64/26 will be configured without the output device
|
||||
and the kernel will choose it automatically which might result
|
||||
in an unwanted device being used. To avoid this, specify
|
||||
`interface_name` in the connection appropriately.")
|
||||
- __network_connections_result.stderr is search(__stderr_str)
|
||||
msg: The warning about specifying the route without the output
|
||||
device is not logged for initscripts provider
|
||||
when: network_provider == "initscripts"
|
||||
when:
|
||||
- network_provider == "initscripts"
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
vars:
|
||||
__stderr_str: >-
|
||||
\[003\] <warn> .0, state.None persistent_state.present, '{{ interface1 }}'.
|
||||
The connection {{ interface1 }} does not
|
||||
specify an interface name. Therefore, the route to
|
||||
198.58.10.64/26 will be configured without the output device
|
||||
and the kernel will choose it automatically which might result
|
||||
in an unwanted device being used. To avoid this, specify
|
||||
`interface_name` in the connection appropriately.
|
||||
|
||||
- name: Assert that no warning is logged for nm provider
|
||||
assert:
|
||||
that:
|
||||
- __network_connections_result.stderr is not search("<warn>")
|
||||
msg: The warning is logged for nm provider
|
||||
when: network_provider == "nm"
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- __network_is_booted
|
||||
- not __bootc_validation | d(false)
|
||||
always:
|
||||
- name: Remove test configuration
|
||||
tags:
|
||||
- "tests::cleanup"
|
||||
when: ansible_connection != "buildah"
|
||||
block:
|
||||
- name: Bring down test devices and profiles
|
||||
include_role:
|
||||
|
|
@ -169,15 +188,20 @@
|
|||
state: down
|
||||
- name: Delete interface1
|
||||
include_tasks: tasks/delete_interface.yml
|
||||
vars:
|
||||
lsr_interface: "{{ interface1 }}"
|
||||
- name: Assert interface1 is absent
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
- name: Set interface0
|
||||
set_fact:
|
||||
interface: "{{ interface0 }}"
|
||||
vars:
|
||||
lsr_interface: "{{ interface1 }}"
|
||||
- name: Delete interface0
|
||||
include_tasks: tasks/delete_interface.yml
|
||||
vars:
|
||||
lsr_interface: "{{ interface0 }}"
|
||||
- name: Assert interface0 is absent
|
||||
include_tasks: tasks/assert_device_absent.yml
|
||||
vars:
|
||||
lsr_interface: "{{ interface0 }}"
|
||||
- name: Assert interface0 profile and interface1 profile are absent
|
||||
include_tasks: tasks/assert_profile_absent.yml
|
||||
vars:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,6 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
state: up
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: "** TEST check IPv4"
|
||||
command: ip -4 a s {{ interface | quote }}
|
||||
command: ip -4 a s {{ lsr_interface | d(interface) | quote }}
|
||||
register: result
|
||||
until: address in result.stdout
|
||||
retries: 20
|
||||
|
|
|
|||
|
|
@ -9,13 +9,18 @@
|
|||
loop_control:
|
||||
loop_var: bond_opt
|
||||
changed_when: false
|
||||
when: __network_is_booted | bool
|
||||
|
||||
- name: Include the task 'assert_IPv4_present.yml'
|
||||
include_tasks: assert_IPv4_present.yml
|
||||
vars:
|
||||
interface: "{{ controller_device }}"
|
||||
lsr_interface: "{{ controller_device }}"
|
||||
address: '192.0.2'
|
||||
when: __network_is_booted | bool
|
||||
|
||||
- name: Include the task 'assert_IPv6_present.yml'
|
||||
include_tasks: assert_IPv6_present.yml
|
||||
vars:
|
||||
interface: "{{ controller_device }}"
|
||||
lsr_interface: "{{ controller_device }}"
|
||||
address: '2001'
|
||||
when: __network_is_booted | bool
|
||||
|
|
|
|||
78
tests/tasks/assert_command_output.yml
Normal file
78
tests/tasks/assert_command_output.yml
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Inputs:
|
||||
# lsr_command: The command to run with the "command" module
|
||||
# command can be either a string or a list
|
||||
# lsr_shell: The command to run with the "shell" module
|
||||
# lsr_packages: Any packages that need to be installed first
|
||||
# to provide the command, if any
|
||||
# lsr_stdout: The string to look for in the stdout of the command
|
||||
# lsr_stderr: The string to look for in the stderr of the command
|
||||
# lsr_not_stdout: This string must not be present in the stdout of the command
|
||||
# lsr_not_stderr: This string must not be present in the stderr of the command
|
||||
# Output:
|
||||
# Will raise an error if command fails
|
||||
# Will raise an error if stdout/stderr do not match given strings
|
||||
---
|
||||
- name: Ensure test packages are present
|
||||
package:
|
||||
name: "{{ lsr_packages }}"
|
||||
state: present
|
||||
use: "{{ (__network_is_ostree | d(false)) |
|
||||
ternary('ansible.posix.rhel_rpm_ostree', omit) }}"
|
||||
when: lsr_packages | d([]) | length > 0
|
||||
|
||||
- name: Run command and collect output
|
||||
command:
|
||||
cmd: "{{ lsr_command if lsr_command is string else omit }}"
|
||||
argv: "{{ lsr_command if lsr_command is not string else omit }}"
|
||||
when: lsr_command | d("") | length > 0
|
||||
changed_when: false
|
||||
register: __cmd_output
|
||||
|
||||
# noqa command-instead-of-shell
|
||||
- name: Run command and collect output with shell
|
||||
shell: "{{ lsr_shell }}"
|
||||
when: lsr_shell | d("") | length > 0
|
||||
changed_when: false
|
||||
register: __shell_output
|
||||
|
||||
- name: Set command output
|
||||
set_fact:
|
||||
__command_output: "{{ __cmd_output if lsr_command | d('') | length > 0 else __shell_output }}"
|
||||
|
||||
- name: Set previous command output for before/after comparisons
|
||||
set_fact:
|
||||
__previous_command_output: "{{ __command_output }}"
|
||||
|
||||
- name: Assert lsr_stdout is in stdout
|
||||
assert:
|
||||
that: lsr_stdout in __command_output.stdout
|
||||
when: lsr_stdout | d("") | length > 0
|
||||
|
||||
- name: Assert lsr_stdout_lines is in stdout
|
||||
assert:
|
||||
that: lsr_stdout_lines is subset(__command_output.stdout_lines)
|
||||
when: lsr_stdout_lines | d([]) | length > 0
|
||||
|
||||
# assert that each regex in the list is in the stdout
|
||||
- name: Assert lsr_stdout_regex_list is in stdout
|
||||
assert:
|
||||
that: __command_output.stdout is search(lsr_stdout_regex_list_item)
|
||||
loop: "{{ lsr_stdout_regex_list | d([]) }}"
|
||||
loop_control:
|
||||
loop_var: lsr_stdout_regex_list_item
|
||||
|
||||
- name: Assert lsr_not_stdout is not in stdout
|
||||
assert:
|
||||
that: lsr_not_stdout not in __command_output.stdout
|
||||
when: lsr_not_stdout | d("") | length > 0
|
||||
|
||||
- name: Assert lsr_stderr is in stderr
|
||||
assert:
|
||||
that: lsr_stderr in __command_output.stderr
|
||||
when: lsr_stderr | d("") | length > 0
|
||||
|
||||
- name: Assert lsr_not_stderr is not in stderr
|
||||
assert:
|
||||
that: lsr_not_stderr not in __command_output.stderr
|
||||
when: lsr_not_stderr | d("") | length > 0
|
||||
127
tests/tasks/assert_connection_settings.yml
Normal file
127
tests/tasks/assert_connection_settings.yml
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Inputs
|
||||
# - lsr_connection_name: the connection name
|
||||
# - network_provider: the network provider
|
||||
# - lsr_connection_settings: the connection file settings for NM files
|
||||
---
|
||||
- name: Assert NM connection settings
|
||||
when:
|
||||
- lsr_connection_name is defined
|
||||
- lsr_connection_settings | d({}) | length > 0
|
||||
- network_provider == "nm"
|
||||
- ansible_distribution_major_version | int >= 9
|
||||
vars:
|
||||
__nm_connection_file_path: /etc/NetworkManager/system-connections/{{ lsr_connection_name }}.nmconnection
|
||||
block:
|
||||
- name: Show connection file
|
||||
command: cat {{ __nm_connection_file_path | quote }}
|
||||
changed_when: false
|
||||
when: ansible_verbosity | int >= 2
|
||||
|
||||
- name: Stat connection file
|
||||
stat:
|
||||
path: "{{ __nm_connection_file_path }}"
|
||||
register: __nm_connection_file_stat
|
||||
|
||||
- name: Assert settings in NM connection file
|
||||
community.general.ini_file:
|
||||
path: "{{ __nm_connection_file_path }}"
|
||||
section: "{{ __nm_connection_file_item.section }}"
|
||||
option: "{{ __nm_connection_file_item.option }}"
|
||||
value: "{{ __nm_connection_file_item.value }}"
|
||||
state: present
|
||||
ignore_spaces: true
|
||||
owner: "{{ __nm_connection_file_stat.stat.pw_name }}"
|
||||
group: "{{ __nm_connection_file_stat.stat.gr_name }}"
|
||||
mode: "{{ __nm_connection_file_stat.stat.mode }}"
|
||||
register: __nm_connection_file
|
||||
# nm only values do not define value
|
||||
loop: "{{ lsr_connection_settings | selectattr('value', 'defined') | list }}"
|
||||
loop_control:
|
||||
loop_var: __nm_connection_file_item
|
||||
failed_when: __nm_connection_file is changed
|
||||
|
||||
- name: Get nmcli connection settings
|
||||
command: nmcli --fields all --terse connection show {{ lsr_connection_name | quote }}
|
||||
register: __nm_connection_settings
|
||||
changed_when: false
|
||||
when: __network_is_booted
|
||||
|
||||
- name: Assert nmcli connection settings
|
||||
assert:
|
||||
that: setting in __nm_connection_settings.stdout_lines
|
||||
loop: "{{ nmitems + items }}"
|
||||
loop_control:
|
||||
loop_var: __nm_connection_item
|
||||
when: __network_is_booted
|
||||
vars:
|
||||
nmitems: "{{ lsr_connection_settings | selectattr('nmvalue', 'defined') | selectattr('nmvalue') | list }}"
|
||||
items: "{{ lsr_connection_settings | rejectattr('nmvalue', 'defined') | list }}"
|
||||
section: "{{ __nm_connection_item.section }}"
|
||||
option: "{{ 'addresses' if __nm_connection_item.option == 'address1' else __nm_connection_item.option }}"
|
||||
value: "{{ __nm_connection_item.nmvalue
|
||||
if __nm_connection_item.nmvalue is defined and __nm_connection_item.nmvalue
|
||||
else __nm_connection_item.value }}"
|
||||
setting: "{{ section ~ '.' ~ option ~ ':' ~ value }}"
|
||||
|
||||
- name: Assert initscripts file settings
|
||||
when:
|
||||
- lsr_connection_name is defined
|
||||
- lsr_connection_settings | d({}) | length > 0
|
||||
- network_provider == "initscripts" or ansible_distribution_major_version | int < 9
|
||||
vars:
|
||||
__initscripts_connection_file_path: /etc/sysconfig/network-scripts/ifcfg-{{ lsr_connection_name }}
|
||||
__initscripts_route_file_path: /etc/sysconfig/network-scripts/route-{{ lsr_connection_name }}
|
||||
__initscripts_route6_file_path: /etc/sysconfig/network-scripts/route6-{{ lsr_connection_name }}
|
||||
__check_route: "{{ lsr_connection_settings | selectattr('ifcfg_route_value', 'defined') | selectattr('ifcfg_route_value') |
|
||||
map(attribute='ifcfg_route_value') | list | length > 0 }}"
|
||||
__check_route6: "{{ lsr_connection_settings | selectattr('ifcfg_route6_value', 'defined') | selectattr('ifcfg_route6_value') |
|
||||
map(attribute='ifcfg_route6_value') | list | length > 0 }}"
|
||||
block:
|
||||
- name: Show connection file
|
||||
command: cat {{ __initscripts_connection_file_path | quote }}
|
||||
changed_when: false
|
||||
when: ansible_verbosity | int >= 2
|
||||
|
||||
- name: Slurp connection file
|
||||
slurp:
|
||||
src: "{{ __initscripts_connection_file_path }}"
|
||||
register: __initscripts_connection_file
|
||||
|
||||
- name: Assert settings in initscripts connection file
|
||||
assert:
|
||||
that: __initscripts_connection_item in __initscripts_connection_file.content | b64decode
|
||||
loop: "{{ lsr_connection_settings | selectattr('ifcfg_value', 'defined') | selectattr('ifcfg_value') |
|
||||
map(attribute='ifcfg_value') | list }}"
|
||||
loop_control:
|
||||
loop_var: __initscripts_connection_item
|
||||
|
||||
- name: Slurp route file
|
||||
when: __check_route
|
||||
slurp:
|
||||
src: "{{ __initscripts_route_file_path }}"
|
||||
register: __initscripts_route_file
|
||||
|
||||
- name: Assert settings in initscripts route file
|
||||
when: __check_route
|
||||
assert:
|
||||
that: __initscripts_route_item in __initscripts_route_file.content | b64decode
|
||||
loop: "{{ lsr_connection_settings | selectattr('ifcfg_route_value', 'defined') | selectattr('ifcfg_route_value') |
|
||||
map(attribute='ifcfg_route_value') | list }}"
|
||||
loop_control:
|
||||
loop_var: __initscripts_route_item
|
||||
|
||||
- name: Slurp route6 file
|
||||
when: __check_route6
|
||||
slurp:
|
||||
src: "{{ __initscripts_route6_file_path }}"
|
||||
register: __initscripts_route6_file
|
||||
|
||||
- name: Assert settings in initscripts route6 file
|
||||
when: __check_route6
|
||||
assert:
|
||||
that: __initscripts_route6_item in __initscripts_route6_file.content | b64decode
|
||||
loop: "{{ lsr_connection_settings | selectattr('ifcfg_route6_value', 'defined') | selectattr('ifcfg_route6_value') |
|
||||
map(attribute='ifcfg_route6_value') | list }}"
|
||||
loop_control:
|
||||
loop_var: __initscripts_route6_item
|
||||
|
|
@ -3,4 +3,4 @@
|
|||
- name: Import the task 'assert_device_present.yml'
|
||||
import_tasks: tasks/assert_device_present.yml
|
||||
vars:
|
||||
interface: "{{ controller_device }}"
|
||||
lsr_interface: "{{ controller_device }}"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
---
|
||||
- name: Include the task 'get_interface_stat.yml'
|
||||
include_tasks: get_interface_stat.yml
|
||||
- name: "Assert that the interface is absent - '{{ interface }}'"
|
||||
- name: "Assert that the interface is absent - '{{ lsr_interface | d(interface) }}'"
|
||||
assert:
|
||||
that: not interface_stat.stat.exists
|
||||
msg: "{{ interface }} exists"
|
||||
msg: "{{ lsr_interface | d(interface) }} exists"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
---
|
||||
- name: Include the task 'get_interface_stat.yml'
|
||||
include_tasks: get_interface_stat.yml
|
||||
- name: "Assert that the interface is present - '{{ interface }}'"
|
||||
when: ansible_connection != 'buildah'
|
||||
- name: "Assert that the interface is present - '{{ lsr_interface | d(interface) }}'"
|
||||
assert:
|
||||
that: interface_stat.stat.exists
|
||||
msg: "{{ interface }} does not exist"
|
||||
msg: "{{ lsr_interface | d(interface) }} does not exist"
|
||||
when: ansible_connection != 'buildah'
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
- name: Import the task 'assert_device_present.yml'
|
||||
import_tasks: tasks/assert_device_present.yml
|
||||
vars:
|
||||
interface: "{{ dhcp_interface1 }}"
|
||||
lsr_interface: "{{ dhcp_interface1 }}"
|
||||
- name: Import the task 'assert_device_present.yml'
|
||||
import_tasks: tasks/assert_device_present.yml
|
||||
vars:
|
||||
interface: "{{ dhcp_interface2 }}"
|
||||
lsr_interface: "{{ dhcp_interface2 }}"
|
||||
|
|
|
|||
21
tests/tasks/assert_nm_connection_status.yml
Normal file
21
tests/tasks/assert_nm_connection_status.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
# Inputs
|
||||
# - lsr_connection_name: the connection name
|
||||
# - lsr_connection_output: the output pattern to search for
|
||||
# - network_provider: the network provider
|
||||
---
|
||||
- name: Assert NM connection status
|
||||
when:
|
||||
- lsr_connection_name is defined
|
||||
- lsr_connection_output is defined
|
||||
- network_provider == "nm"
|
||||
- __network_is_booted
|
||||
block:
|
||||
- name: Show connection status
|
||||
command: nmcli connection show {{ lsr_connection_name | quote }}
|
||||
changed_when: false
|
||||
register: __lsr_nm_connection_status
|
||||
|
||||
- name: Assert connection status
|
||||
assert:
|
||||
that: __lsr_nm_connection_status.stdout is search(lsr_connection_output)
|
||||
|
|
@ -20,6 +20,7 @@
|
|||
ls -alrtF /etc/resolv.* || :
|
||||
fi
|
||||
changed_when: false
|
||||
when: __network_is_booted | d(true) | bool
|
||||
|
||||
- name: Verify DNS and network connectivity
|
||||
shell: |
|
||||
|
|
@ -35,5 +36,7 @@
|
|||
exit 1
|
||||
fi
|
||||
done
|
||||
when: ansible_facts["distribution"] == "CentOS"
|
||||
changed_when: false
|
||||
when:
|
||||
- ansible_facts["distribution"] == "CentOS"
|
||||
- __network_is_booted | d(true) | bool
|
||||
|
|
|
|||
|
|
@ -2,10 +2,10 @@
|
|||
---
|
||||
- name: Cleanup profile and device
|
||||
shell: |
|
||||
nmcli con delete {{ interface }}
|
||||
nmcli con load /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
rm -f /etc/sysconfig/network-scripts/ifcfg-{{ interface }}
|
||||
ip link del {{ interface }}
|
||||
nmcli con delete {{ lsr_interface | d(interface) }}
|
||||
nmcli con load /etc/sysconfig/network-scripts/ifcfg-{{ lsr_interface | d(interface) }}
|
||||
rm -f /etc/sysconfig/network-scripts/ifcfg-{{ lsr_interface | d(interface) }}
|
||||
ip link del {{ lsr_interface | d(interface) }}
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
changed_when: false
|
||||
...
|
||||
|
|
|
|||
|
|
@ -19,8 +19,8 @@
|
|||
persistent_state: absent
|
||||
state: down
|
||||
failed_when: false
|
||||
- name: Delete the device '{{ interface }}'
|
||||
command: ip link del {{ interface }}
|
||||
- name: Delete the device '{{ lsr_interface | d(interface) }}'
|
||||
command: ip link del {{ lsr_interface | d(interface) }}
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
...
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
---
|
||||
- name: Retrieve perm_hwaddr using ethtool
|
||||
# wokeignore:rule=slave
|
||||
command: cat /sys/class/net/{{ interface }}/bonding_slave/perm_hwaddr
|
||||
command: cat /sys/class/net/{{ lsr_interface | d(interface) }}/bonding_slave/perm_hwaddr
|
||||
register: mac_address_result
|
||||
changed_when: false
|
||||
failed_when: mac_address_result.rc != 0
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
mac: "{{ mac_address_result.stdout_lines[-1].split(' ')[-1] }}"
|
||||
- name: Display the retrieved MAC address
|
||||
debug:
|
||||
msg: "Retrieved MAC address for {{ interface }}: {{ mac }}"
|
||||
msg: "Retrieved MAC address for {{ lsr_interface | d(interface) }}: {{ mac }}"
|
||||
- name: Test matching the port device based on the perm_hwaddr
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
|
|
@ -20,6 +20,6 @@
|
|||
- name: "{{ profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ interface }}"
|
||||
interface_name: "{{ lsr_interface | d(interface) }}"
|
||||
mac: "{{ mac }}"
|
||||
...
|
||||
|
|
|
|||
|
|
@ -1,49 +0,0 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Include network role
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
# Create a bond controller
|
||||
- name: "{{ controller_profile }}"
|
||||
state: up
|
||||
type: bond
|
||||
interface_name: "{{ controller_device }}"
|
||||
bond:
|
||||
mode: 802.3ad
|
||||
ad_actor_sys_prio: 65535
|
||||
ad_actor_system: 00:00:5e:00:53:5d
|
||||
ad_select: stable
|
||||
ad_user_port_key: 1023
|
||||
all_ports_active: true
|
||||
downdelay: 0
|
||||
lacp_rate: slow
|
||||
lp_interval: 128
|
||||
miimon: 110
|
||||
min_links: 0
|
||||
num_grat_arp: 64
|
||||
primary_reselect: better
|
||||
resend_igmp: 225
|
||||
updelay: 0
|
||||
use_carrier: true
|
||||
xmit_hash_policy: encap2+3
|
||||
ip:
|
||||
route_metric4: 65535
|
||||
|
||||
# add an ethernet to the bond
|
||||
- name: "{{ port1_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface1 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
# add a second ethernet to the bond
|
||||
- name: "{{ port2_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
- name: Show result
|
||||
debug:
|
||||
var: __network_connections_result
|
||||
...
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Reconfigure the bond options
|
||||
import_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
# Create a bond controller
|
||||
- name: "{{ controller_profile }}"
|
||||
state: up
|
||||
type: bond
|
||||
interface_name: "{{ controller_device }}"
|
||||
bond:
|
||||
mode: active-backup
|
||||
arp_interval: 60
|
||||
arp_ip_target: 192.0.2.128
|
||||
arp_validate: none
|
||||
primary: "{{ dhcp_interface1 }}"
|
||||
ip:
|
||||
route_metric4: 65535
|
||||
# add an ethernet to the bond
|
||||
- name: "{{ port1_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface1 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
# add a second ethernet to the bond
|
||||
- name: "{{ port2_profile }}"
|
||||
state: up
|
||||
type: ethernet
|
||||
interface_name: "{{ dhcp_interface2 }}"
|
||||
controller: "{{ controller_profile }}"
|
||||
- name: Show result
|
||||
debug:
|
||||
var: __network_connections_result
|
||||
...
|
||||
|
|
@ -5,7 +5,7 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
persistent_state: present
|
||||
type: bridge
|
||||
ip:
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
autoconnect: false
|
||||
persistent_state: present
|
||||
type: bridge
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
autoconnect_retries: "{{ autocon_retries }}"
|
||||
state: up
|
||||
type: dummy
|
||||
|
|
|
|||
|
|
@ -5,12 +5,12 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
state: up
|
||||
persistent_state: present
|
||||
autoconnect: true
|
||||
type: ethernet
|
||||
interface_name: "{{ interface }}"
|
||||
interface_name: "{{ lsr_interface | d(interface) }}"
|
||||
mac: "{{ mac }}"
|
||||
ip:
|
||||
dhcp4: false
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
state: up
|
||||
persistent_state: present
|
||||
type: vlan
|
||||
parent: "{{ interface }}"
|
||||
parent: "{{ lsr_interface | d(interface) }}"
|
||||
vlan:
|
||||
id: 3732
|
||||
autoconnect: true
|
||||
|
|
@ -35,7 +35,7 @@
|
|||
state: up
|
||||
persistent_state: present
|
||||
type: vlan
|
||||
parent: "{{ interface }}"
|
||||
parent: "{{ lsr_interface | d(interface) }}"
|
||||
vlan:
|
||||
id: 120
|
||||
autoconnect: true
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
vars:
|
||||
network_allow_restart: true
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
persistent_state: present
|
||||
type: team
|
||||
ip:
|
||||
|
|
|
|||
|
|
@ -143,3 +143,17 @@
|
|||
--dhcp-host 52:54:00:12:34:56,ignore --dhcp-host 52:54:00:12:34:57,ignore
|
||||
fi
|
||||
changed_when: false
|
||||
when: ansible_connection != "buildah"
|
||||
|
||||
# When doing bootc validation, have to restart NetworkManager services
|
||||
# to pick up newly created devices
|
||||
- name: Restart NetworkManager services for testing
|
||||
service:
|
||||
name: "{{ item }}"
|
||||
state: restarted
|
||||
loop:
|
||||
- NetworkManager.service
|
||||
- NetworkManager-wait-online.service
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- __bootc_validation | d(false)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
vars:
|
||||
network_allow_restart: '{{ wifi_restart_network }}'
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
type: wireless
|
||||
wireless:
|
||||
ssid: "My WPA2-PSK Network"
|
||||
|
|
|
|||
|
|
@ -1,7 +1,10 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Remove test interface if necessary
|
||||
command: "ip link del {{ interface }}"
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
changed_when: false
|
||||
command: ip link del {{ lsr_interface | d(interface) | quote }}
|
||||
changed_when: true
|
||||
register: __delete_interface_result
|
||||
failed_when:
|
||||
- __delete_interface_result.rc != 0
|
||||
- __delete_interface_result.stderr is not search("Cannot find device")
|
||||
...
|
||||
|
|
|
|||
|
|
@ -7,3 +7,4 @@
|
|||
network_connections:
|
||||
- name: "{{ profile }}"
|
||||
state: down
|
||||
persistent_state: "{{ lsr_persistent_state | d('present') }}"
|
||||
|
|
|
|||
|
|
@ -1,15 +1,15 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Get connection profile for '{{ interface }}'
|
||||
- name: Get connection profile for '{{ lsr_interface | d(interface) }}'
|
||||
shell:
|
||||
executable: /bin/bash
|
||||
cmd: |
|
||||
set -euo pipefail
|
||||
connection="$(nmcli -g GENERAL.CONNECTION device show {{ interface | quote }})" || :
|
||||
connection="$(nmcli -g GENERAL.CONNECTION device show {{ lsr_interface | d(interface) | quote }})" || :
|
||||
if [ -z "$connection" ]; then
|
||||
nmcli device connect {{ interface | quote }} 1>&2
|
||||
nmcli device connect {{ lsr_interface | d(interface) | quote }} 1>&2
|
||||
fi
|
||||
nmcli -g GENERAL.CONNECTION device show {{ interface | quote }}
|
||||
nmcli -g GENERAL.CONNECTION device show {{ lsr_interface | d(interface) | quote }}
|
||||
register: connection_name
|
||||
changed_when: false
|
||||
|
||||
|
|
@ -22,7 +22,7 @@
|
|||
nmcli device status || :
|
||||
nmcli device show || :
|
||||
nmcli connection show || :
|
||||
nmcli connection show '{{ interface }}' || :
|
||||
nmcli connection show '{{ lsr_interface | d(interface) }}' || :
|
||||
ip a
|
||||
echo connection_name: {{ connection_name | to_nice_json | quote }} || :
|
||||
ls -alrtF /etc/sysconfig/network-scripts || :
|
||||
|
|
@ -59,7 +59,7 @@
|
|||
when: connection_name is failed or connection_name.stdout | length == 0
|
||||
failed_when: connection_name is failed or connection_name.stdout | length == 0
|
||||
|
||||
- name: Bring down and delete the connection profile for '{{ interface }}'
|
||||
- name: Bring down and delete the connection profile for '{{ lsr_interface | d(interface) }}'
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: "Get stat for interface {{ interface }}"
|
||||
- name: "Get stat for interface {{ lsr_interface | d(interface) }}"
|
||||
stat:
|
||||
get_attributes: false
|
||||
get_checksum: false
|
||||
get_mime: false
|
||||
path: "/sys/class/net/{{ interface }}"
|
||||
path: "/sys/class/net/{{ lsr_interface | d(interface) }}"
|
||||
register: interface_stat
|
||||
|
|
|
|||
|
|
@ -22,8 +22,15 @@
|
|||
# When certain profile is marked as absent but still up, the `nmcli connection`
|
||||
# still show it with FILENAME starting with /run. Only consider profile exists
|
||||
# when its FILENAME is in /etc folder
|
||||
# in the non-booted case, we can predict the profile path from nm_offline backend
|
||||
- name: Get NM profile info
|
||||
shell: nmcli -f NAME,FILENAME connection show |grep {{ profile }} | grep /etc
|
||||
vars:
|
||||
nm_profile_cmd: >-
|
||||
{{ "nmcli -f NAME,FILENAME connection show | grep " ~ profile ~ " | grep /etc"
|
||||
if __network_is_booted
|
||||
else "test -s /etc/NetworkManager/system-connections/" ~ profile ~ ".nmconnection" }}
|
||||
# noqa command-instead-of-shell
|
||||
shell: "{{ nm_profile_cmd }}"
|
||||
register: nm_profile_exists
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
|
|
|
|||
25
tests/tasks/handle_assert_task.yml
Normal file
25
tests/tasks/handle_assert_task.yml
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Handle assert task file
|
||||
include_tasks: "{{ lsr_assert_item }}"
|
||||
when: lsr_assert_item is string
|
||||
|
||||
- name: Handle assert task with condition and variables
|
||||
include_tasks: "{{ lsr_assert_item['what'] }}"
|
||||
when:
|
||||
- lsr_assert_item is mapping
|
||||
- lsr_assert_item.get("condition", true)
|
||||
vars:
|
||||
lsr_connection_name: "{{ lsr_assert_item.get('lsr_connection_name', '') }}"
|
||||
lsr_connection_settings: "{{ lsr_assert_item.get('lsr_connection_settings', []) }}"
|
||||
lsr_connection_output: "{{ lsr_assert_item.get('lsr_connection_output', '') }}"
|
||||
lsr_packages: "{{ lsr_assert_item.get('lsr_packages', []) }}"
|
||||
lsr_command: "{{ lsr_assert_item.get('lsr_command', '') }}"
|
||||
lsr_shell: "{{ lsr_assert_item.get('lsr_shell', '') }}"
|
||||
lsr_stdout: "{{ lsr_assert_item.get('lsr_stdout', '') }}"
|
||||
lsr_stdout_lines: "{{ lsr_assert_item.get('lsr_stdout_lines', []) }}"
|
||||
lsr_stdout_regex_list: "{{ lsr_assert_item.get('lsr_stdout_regex_list', []) }}"
|
||||
lsr_stderr: "{{ lsr_assert_item.get('lsr_stderr', '') }}"
|
||||
lsr_not_stdout: "{{ lsr_assert_item.get('lsr_not_stdout', '') }}"
|
||||
lsr_not_stderr: "{{ lsr_assert_item.get('lsr_not_stderr', '') }}"
|
||||
profile: "{{ lsr_assert_item.get('profile', '') }}"
|
||||
15
tests/tasks/handle_cleanup_task.yml
Normal file
15
tests/tasks/handle_cleanup_task.yml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Handle cleanup task file
|
||||
include_tasks: "{{ lsr_cleanup_item }}"
|
||||
when: lsr_cleanup_item is string
|
||||
|
||||
- name: Handle cleanup task with condition and variables
|
||||
include_tasks: "{{ lsr_cleanup_item['what'] }}"
|
||||
when:
|
||||
- lsr_cleanup_item is mapping
|
||||
- lsr_cleanup_item.get("condition", true)
|
||||
vars:
|
||||
profile: "{{ lsr_cleanup_item.get('profile', interface | d('')) }}"
|
||||
state: "{{ lsr_cleanup_item.get('state', 'present') }}"
|
||||
lsr_persistent_state: "{{ lsr_cleanup_item.get('lsr_persistent_state', '') }}"
|
||||
23
tests/tasks/handle_setup_task.yml
Normal file
23
tests/tasks/handle_setup_task.yml
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Handle setup task file
|
||||
include_tasks: "{{ lsr_setup_item }}"
|
||||
when: lsr_setup_item is string
|
||||
|
||||
- name: Handle setup task with condition and variables
|
||||
include_tasks: "{{ lsr_setup_item['what'] }}"
|
||||
when:
|
||||
- lsr_setup_item is mapping
|
||||
- lsr_setup_item.get("condition", true)
|
||||
vars:
|
||||
state: "{{ lsr_setup_item.get('state', 'present') }}"
|
||||
lsr_interface: "{{ lsr_setup_item.get('lsr_interface', interface | d('')) }}"
|
||||
lsr_packages: "{{ lsr_setup_item.get('lsr_packages', []) }}"
|
||||
lsr_command: "{{ lsr_setup_item.get('lsr_command', '') }}"
|
||||
lsr_shell: "{{ lsr_setup_item.get('lsr_shell', '') }}"
|
||||
lsr_stdout: "{{ lsr_setup_item.get('lsr_stdout', '') }}"
|
||||
lsr_stdout_lines: "{{ lsr_setup_item.get('lsr_stdout_lines', []) }}"
|
||||
lsr_stdout_regex_list: "{{ lsr_setup_item.get('lsr_stdout_regex_list', []) }}"
|
||||
lsr_stderr: "{{ lsr_setup_item.get('lsr_stderr', '') }}"
|
||||
lsr_not_stdout: "{{ lsr_setup_item.get('lsr_not_stdout', '') }}"
|
||||
lsr_not_stderr: "{{ lsr_setup_item.get('lsr_not_stderr', '') }}"
|
||||
21
tests/tasks/handle_test_task.yml
Normal file
21
tests/tasks/handle_test_task.yml
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
# SPDX-License-Identifier: BSD-3-Clause
|
||||
---
|
||||
- name: Handle test task file
|
||||
include_tasks: "{{ lsr_test_item }}"
|
||||
when: lsr_test_item is string
|
||||
|
||||
- name: Handle test task with network role
|
||||
when:
|
||||
- lsr_test_item is mapping
|
||||
- lsr_test_item.get("network_connections") is not none
|
||||
- lsr_test_item.get("condition", true)
|
||||
block:
|
||||
- name: Include network role
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections: "{{ lsr_test_item['network_connections'] }}"
|
||||
|
||||
- name: Show result
|
||||
debug:
|
||||
var: __network_connections_result
|
||||
|
|
@ -25,51 +25,73 @@
|
|||
delay: 10
|
||||
|
||||
# veth
|
||||
- name: Create veth interface {{ interface }}
|
||||
- name: Create veth interface {{ lsr_interface | d(interface) }}
|
||||
command: "{{ item }}"
|
||||
with_items:
|
||||
- ip link add {{ interface }} type veth peer name peer{{ interface }}
|
||||
- ip link set peer{{ interface }} up
|
||||
- ip link set {{ interface }} up
|
||||
when: "type == 'veth' and state == 'present' and
|
||||
interface not in current_interfaces"
|
||||
- ip link add {{ lsr_interface | d(interface) }} type veth peer name peer{{ lsr_interface | d(interface) }}
|
||||
- ip link set peer{{ lsr_interface | d(interface) }} up
|
||||
- ip link set {{ lsr_interface | d(interface) }} up
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'veth'
|
||||
- state == 'present'
|
||||
- lsr_interface | d(interface) not in current_interfaces
|
||||
changed_when: false
|
||||
|
||||
- name: Set up veth as managed by NetworkManager
|
||||
command: nmcli d set {{ interface }} managed true
|
||||
command: nmcli d set {{ lsr_interface | d(interface) }} managed true
|
||||
# The variable for `network_provider` is not exists yet,
|
||||
# just ignore error for initscripts
|
||||
ignore_errors: true # noqa ignore-errors
|
||||
when: "type == 'veth' and state == 'present'"
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'veth'
|
||||
- state == 'present'
|
||||
changed_when: false
|
||||
|
||||
- name: Delete veth interface {{ interface }}
|
||||
command: ip link del {{ interface }} type veth
|
||||
when: "type == 'veth' and state == 'absent' and
|
||||
interface in current_interfaces"
|
||||
- name: Delete veth interface {{ lsr_interface | d(interface) }}
|
||||
command: ip link del {{ lsr_interface | d(interface) }} type veth
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'veth'
|
||||
- state == 'absent'
|
||||
- lsr_interface | d(interface) in current_interfaces
|
||||
changed_when: false
|
||||
|
||||
# dummy
|
||||
- name: Create dummy interface {{ interface }}
|
||||
command: ip link add "{{ interface }}" type dummy
|
||||
when: "type == 'dummy' and state == 'present' and
|
||||
interface not in current_interfaces"
|
||||
- name: Create dummy interface {{ lsr_interface | d(interface) }}
|
||||
command: ip link add "{{ lsr_interface | d(interface) }}" type dummy
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'dummy'
|
||||
- state == 'present'
|
||||
- lsr_interface | d(interface) not in current_interfaces
|
||||
changed_when: false
|
||||
|
||||
- name: Delete dummy interface {{ interface }}
|
||||
command: ip link del "{{ interface }}" type dummy
|
||||
when: "type == 'dummy' and state == 'absent' and
|
||||
interface in current_interfaces"
|
||||
- name: Delete dummy interface {{ lsr_interface | d(interface) }}
|
||||
command: ip link del "{{ lsr_interface | d(interface) }}" type dummy
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'dummy'
|
||||
- state == 'absent'
|
||||
- lsr_interface | d(interface) in current_interfaces
|
||||
changed_when: false
|
||||
|
||||
# tap
|
||||
- name: Create tap interface {{ interface }}
|
||||
command: ip tuntap add dev {{ interface }} mode tap
|
||||
when: "type == 'tap' and state == 'present'
|
||||
and interface not in current_interfaces"
|
||||
- name: Create tap interface {{ lsr_interface | d(interface) }}
|
||||
command: ip tuntap add dev {{ lsr_interface | d(interface) }} mode tap
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'tap'
|
||||
- state == 'present'
|
||||
- lsr_interface | d(interface) not in current_interfaces
|
||||
changed_when: false
|
||||
|
||||
- name: Delete tap interface {{ interface }}
|
||||
command: ip tuntap del dev {{ interface }} mode tap
|
||||
when: "type == 'tap' and state == 'absent' and
|
||||
interface in current_interfaces"
|
||||
- name: Delete tap interface {{ lsr_interface | d(interface) }}
|
||||
command: ip tuntap del dev {{ lsr_interface | d(interface) }} mode tap
|
||||
when:
|
||||
- ansible_connection != 'buildah'
|
||||
- type == 'tap'
|
||||
- state == 'absent'
|
||||
- lsr_interface | d(interface) in current_interfaces
|
||||
changed_when: false
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface }}"
|
||||
- name: "{{ lsr_interface | d(interface) }}"
|
||||
persistent_state: absent
|
||||
state: down
|
||||
...
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
package:
|
||||
name: "{{ package }}"
|
||||
state: absent
|
||||
when: not __network_is_ostree | d(false)
|
||||
|
|
|
|||
|
|
@ -6,9 +6,16 @@
|
|||
debug:
|
||||
msg: "########## {{ lsr_description }} ##########"
|
||||
|
||||
- name: Include network role vars used by tests
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
tasks_from: set_facts.yml
|
||||
public: true
|
||||
when: __network_is_booted is not defined
|
||||
|
||||
- name: Show item
|
||||
debug:
|
||||
var: "{{ item }}"
|
||||
msg: item {{ item | default("UNDEFINED") | to_nice_json }}
|
||||
loop:
|
||||
- lsr_description
|
||||
- lsr_setup
|
||||
|
|
@ -22,27 +29,50 @@
|
|||
include_tasks: tasks/show_interfaces.yml
|
||||
|
||||
- name: Setup
|
||||
include_tasks: "{{ item }}"
|
||||
include_tasks: tasks/handle_setup_task.yml
|
||||
loop: "{{ lsr_setup }}"
|
||||
loop_control:
|
||||
loop_var: lsr_setup_item
|
||||
tags:
|
||||
- "tests::setup"
|
||||
|
||||
- name: Test
|
||||
include_tasks: "{{ item }}"
|
||||
include_tasks: tasks/handle_test_task.yml
|
||||
loop: "{{ lsr_test }}"
|
||||
loop_control:
|
||||
loop_var: lsr_test_item
|
||||
when: not __bootc_validation | default(false)
|
||||
tags:
|
||||
- "tests::test"
|
||||
|
||||
- name: Asserts
|
||||
include_tasks: "{{ item }}"
|
||||
loop: "{{ lsr_assert }}"
|
||||
tags:
|
||||
- "tests::assert"
|
||||
# When validation is enabled, we need to load the role variables
|
||||
# and set the result because we aren't running the role to set
|
||||
# the network connections - that was already done at build time
|
||||
- name: Handle case where validation is enabled
|
||||
when: __bootc_validation | default(false)
|
||||
block:
|
||||
- name: Load role variables
|
||||
include_role:
|
||||
name: linux-system-roles.network
|
||||
tasks_from: set_facts.yml
|
||||
public: true
|
||||
|
||||
- name: Conditional asserts
|
||||
include_tasks: "{{ item['what'] }}"
|
||||
when: item['condition']
|
||||
loop: "{{ lsr_assert_when | default([]) }}"
|
||||
- name: Set result
|
||||
set_fact:
|
||||
__network_connections_result:
|
||||
failed: false
|
||||
stderr: ""
|
||||
stdout: ""
|
||||
changed: true
|
||||
stdout_lines: []
|
||||
stderr_lines: []
|
||||
|
||||
# You can use either lsr_assert or lsr_assert_when - but not both
|
||||
- name: Asserts
|
||||
include_tasks: tasks/handle_assert_task.yml
|
||||
loop: "{{ (lsr_assert | default([])) + (lsr_assert_when | default([])) }}"
|
||||
loop_control:
|
||||
loop_var: lsr_assert_item
|
||||
|
||||
- name: "Success in test '{{ lsr_description }}'"
|
||||
debug:
|
||||
|
|
@ -55,7 +85,7 @@
|
|||
|
||||
- name: Show item that failed
|
||||
debug:
|
||||
var: "{{ item }}"
|
||||
var: "{{ item | d('UNDEFINED') }}"
|
||||
loop: "{{ lsr_fail_debug | default([]) }}"
|
||||
|
||||
- name: Issue failed message
|
||||
|
|
@ -63,9 +93,19 @@
|
|||
msg: "!!!!! Failure in test '{{ lsr_description }}' !!!!!"
|
||||
|
||||
always:
|
||||
- name: Create QEMU deployment during bootc end-to-end test
|
||||
delegate_to: localhost
|
||||
command: "{{ lsr_scriptdir | quote }}/bootc-buildah-qcow.sh {{ ansible_host | quote }}"
|
||||
changed_when: true
|
||||
when: ansible_connection == "buildah"
|
||||
|
||||
# skip cleanup if building with buildah
|
||||
- name: Cleanup
|
||||
include_tasks: "{{ item }}"
|
||||
include_tasks: tasks/handle_cleanup_task.yml
|
||||
loop: "{{ lsr_cleanup }}"
|
||||
loop_control:
|
||||
loop_var: lsr_cleanup_item
|
||||
when: ansible_connection != "buildah"
|
||||
tags:
|
||||
- "tests::cleanup"
|
||||
...
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
- name: Debug
|
||||
debug:
|
||||
msg: facts {{ ansible_facts | to_nice_json }}
|
||||
when: ansible_verbosity | default(0) >= 3
|
||||
|
||||
# This task can be removed once the RHEL-8.5 is not tested anymore
|
||||
- name: Install hostapd via CentOS Stream
|
||||
|
|
@ -66,6 +67,7 @@
|
|||
# Enable forwarding of EAP 802.1x messages through software bridge "br1".
|
||||
echo 8 > /sys/class/net/br1/bridge/group_fwd_mask
|
||||
changed_when: false
|
||||
when: __network_is_booted
|
||||
|
||||
- name: Create hostapd config
|
||||
copy:
|
||||
|
|
@ -98,3 +100,20 @@
|
|||
- name: Run hostapd in namespace
|
||||
shell: ip netns exec ns1 hostapd -B /etc/hostapd/wired.conf && sleep 5
|
||||
changed_when: false
|
||||
when: __network_is_booted
|
||||
|
||||
# Reload test connection - nm tries to start the connection at boot
|
||||
# but fails because the devices are not created yet - so restart the connection
|
||||
# here after the devices are created and hostapd is running
|
||||
- name: Reload test connection
|
||||
shell:
|
||||
executable: /bin/bash
|
||||
cmd: |
|
||||
set -euo pipefail
|
||||
exec 1>&2
|
||||
nmcli connection down {{ lsr_interface | d(interface) }} || :
|
||||
nmcli connection up {{ lsr_interface | d(interface) }}
|
||||
changed_when: false
|
||||
when:
|
||||
- network_provider == "nm"
|
||||
- __bootc_validation | default(false)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@
|
|||
---
|
||||
- name: Include the task 'get_current_interfaces.yml'
|
||||
include_tasks: get_current_interfaces.yml
|
||||
when: ansible_connection != 'buildah'
|
||||
- name: Show current_interfaces
|
||||
debug:
|
||||
msg: "current_interfaces: {{ current_interfaces }}"
|
||||
when: ansible_connection != 'buildah'
|
||||
|
|
|
|||
|
|
@ -55,7 +55,7 @@
|
|||
name: linux-system-roles.network
|
||||
vars:
|
||||
network_connections:
|
||||
- name: "{{ interface | default('802-1x-test') }}"
|
||||
- name: "{{ lsr_interface | d(interface | d('802-1x-test')) }}"
|
||||
interface_name: veth2
|
||||
state: up
|
||||
type: ethernet
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue