mirror of
https://github.com/linux-system-roles/network.git
synced 2026-01-23 18:35:13 +00:00
feat: support this role in container builds
Feature: Support running the timesync role during container builds. Reason: This is particularly useful for building bootc derivative OSes. Result: These flags enable running the bootc container scenarios in CI, which ensures that the role works in buildah build environment. This allows us to officially support this role for image mode builds. Signed-off-by: Rich Megginson <rmeggins@redhat.com>
This commit is contained in:
parent
3df2be4e86
commit
e8a3ff4881
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