Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CheckNetworkDeprecations9to10: Check for ifcfg artifacts #1332

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 102 additions & 2 deletions repos/system_upgrade/el9toel10/actors/networkdeprecations/actor.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import os

from leapp import reporting
from leapp.actors import Actor
from leapp.models import NetworkManagerConfig, Report
from leapp.models import IfCfg, NetworkManagerConfig, Report
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


Expand All @@ -15,7 +17,7 @@ class CheckNetworkDeprecations9to10(Actor):
"""

name = "network_deprecations"
consumes = (NetworkManagerConfig,)
consumes = (NetworkManagerConfig, IfCfg,)
produces = (Report,)
tags = (ChecksPhaseTag, IPUWorkflowTag,)

Expand All @@ -39,8 +41,106 @@ def report_dhclient():
reporting.RelatedResource('package', 'NetworkManager'),
])

@staticmethod
def report_ifcfg_rules(conn):
reporting.create_report([
reporting.Title('Legacy network configuration with policy routing rules found'),
reporting.Summary('Network configuration files in "ifcfg" format is present accompanied'
' by legacy routing rules. In Red Hat Enterprise Linux 10, support'
' for these files is no longer enabled and the configuration will be'
' ignored. Legacy routing rules are not supported by NetworkManager'
' natively and therefore can not be migrated automatically.'),
reporting.Remediation(hint='Replace the routing rules with equivalent'
' "ipv4.routing-rules" or "ipv6.routing-rules" properties,'
' then migrate the connection with "nmcli conn migrate"'),
reporting.ExternalLink(
url='https://access.redhat.com/solutions/7083803',
title='How to migrate the connection from ifcfg to NetworkManager keyfile plugin?'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nmcli.html',
title='nmcli(1) manual, describes "connection migrate" sub-command.'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nm-settings-ifcfg-rh.html',
title='nm-settings-ifcfg-rh(5), description of the "ifcfg" format'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nm-settings-keyfile.html',
title='nm-settings-keyfile(5), description of the "keyfile" format'),
reporting.Severity(reporting.Severity.HIGH),
reporting.Groups([reporting.Groups.NETWORK, reporting.Groups.SERVICES]),
reporting.Groups([reporting.Groups.INHIBITOR]),
reporting.RelatedResource('package', 'NetworkManager'),
reporting.RelatedResource('package', 'NetworkManager-dispatcher-routing-rules'),
] + [reporting.RelatedResource('file', file) for file in conn.values()])
pass

@staticmethod
def report_ifcfg_leftover(conn):
reporting.create_report([
reporting.Title('Unused legacy network configuration found'),
reporting.Summary('Files that used to accompany legacy network configuration in "ifcfg"'
' format are present, even though the configuration itself is not'
' longer there. These files will be ignored.'),
reporting.Remediation(hint='Verify that the files were not left behind by incomplete'
' migration, fix up configuration if necessary, and remove'
' them.'),
reporting.ExternalLink(
url='https://access.redhat.com/solutions/7083803',
title='How to migrate the connection from ifcfg to NetworkManager keyfile plugin?'),
reporting.Severity(reporting.Severity.HIGH),
reporting.Groups([reporting.Groups.NETWORK, reporting.Groups.SERVICES]),
reporting.Groups([reporting.Groups.INHIBITOR]),
] + [reporting.RelatedResource('file', file) for file in conn.values()])

@staticmethod
def report_ifcfg(conn):
reporting.create_report([
reporting.Title('Legacy network configuration found'),
reporting.Summary('Network configuration file in legacy "ifcfg" format is present.'
' In Red Hat Enterprise Linux 10, support for these files is no longer'
' enabled and the configuration will be ignored.'),
reporting.Remediation(
hint='Convert the configuration into NetworkManager native "keyfile" format.',
commands=[['nmcli', 'connection', 'migrate', conn['ifcfg']]]),
reporting.ExternalLink(
url='https://access.redhat.com/solutions/7083803',
title='How to migrate the connection from ifcfg to NetworkManager keyfile plugin?'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nmcli.html',
title='nmcli(1) manual, describes "connection migrate" sub-command.'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nm-settings-ifcfg-rh.html',
title='nm-settings-ifcfg-rh(5), description of the "ifcfg" format'),
reporting.ExternalLink(
url='https://networkmanager.dev/docs/api/latest/nm-settings-keyfile.html',
title='nm-settings-keyfile(5), description of the "keyfile" format'),
reporting.Severity(reporting.Severity.HIGH),
reporting.Groups([reporting.Groups.NETWORK, reporting.Groups.SERVICES]),
reporting.Groups([reporting.Groups.INHIBITOR]),
reporting.RelatedResource('package', 'NetworkManager'),
] + [reporting.RelatedResource('file', file) for file in conn.values()])

def process(self):
for nm_config in self.consume(NetworkManagerConfig):
self.log.info('Consuming dhcp={}'.format(nm_config.dhcp))
if nm_config.dhcp == 'dhclient':
CheckNetworkDeprecations9to10.report_dhclient()

conns = {}

for ifcfg in self.consume(IfCfg):
self.log.info('Consuming ifcfg={}'.format(ifcfg.filename))
rule_basename = os.path.basename(ifcfg.filename)
(kind, name) = rule_basename.split('-', 1)
if name not in conns:
conns[name] = {}
conns[name][kind] = ifcfg.filename

for name in conns:
conn = conns[name]
if 'ifcfg' in conn:
if 'rule' in conn or 'rule6' in conn:
CheckNetworkDeprecations9to10.report_ifcfg_rules(conn)
else:
CheckNetworkDeprecations9to10.report_ifcfg(conn)
else:
CheckNetworkDeprecations9to10.report_ifcfg_leftover(conn)
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
from leapp.models import NetworkManagerConfig, Report
import pytest

from leapp.models import IfCfg, NetworkManagerConfig, Report
from leapp.utils.report import is_inhibitor

def test_dhcp_dhclient(current_actor_context):
current_actor_context.feed(NetworkManagerConfig(dhcp='dhclient'))
Expand All @@ -23,3 +25,71 @@ def test_dhcp_default(current_actor_context):
current_actor_context.run()
reports = list(current_actor_context.consume(Report))
assert not reports

def test_ifcfg(current_actor_context):
"""
Report when a file ready for migration is present.
"""

current_actor_context.feed(IfCfg(filename='/NM/ifcfg-eth-dev'))
current_actor_context.run()
reports = current_actor_context.consume(Report)
assert len(reports) == 1
report_fields = reports[0].report
assert is_inhibitor(report_fields)
assert report_fields['title'] == 'Legacy network configuration found'
resources = report_fields['detail']['related_resources']
assert len(resources) == 2
assert resources[0]['scheme'] == 'package'
assert resources[0]['title'] == 'NetworkManager'
assert resources[1]['scheme'] == 'file'
assert resources[1]['title'] == '/NM/ifcfg-eth-dev'

@pytest.mark.parametrize('files',
[('/NM/rule-lost',),
('/NM/route6-eth-dev', '/NM/rule-eth-dev')])
def test_leftovers(current_actor_context, files):
"""
Report when what appears like artifacts from unsuccessful migration are present.
"""

for file in files:
current_actor_context.feed(IfCfg(filename=file))
current_actor_context.run()
reports = current_actor_context.consume(Report)
assert len(reports) == 1
report_fields = reports[0].report
assert is_inhibitor(report_fields)
assert report_fields['title'] == 'Unused legacy network configuration found'
resources = report_fields['detail']['related_resources']
assert len(resources) == len(files)
for i in range(len(files)):
assert resources[i]['scheme'] == 'file'
assert resources[i]['title'] == files[i]

@pytest.mark.parametrize('files',
[('/NM/ifcfg-old', '/NM/rule-old'),
('/NM/ifcfg-old', '/NM/rule6-old'),
('/NM/ifcfg-old', '/NM/rule6-old', '/NM/rule-old')])
def test_rules(current_actor_context, files):
"""
Report when configuration that requires manual migration is present.
"""

for file in files:
current_actor_context.feed(IfCfg(filename=file))
current_actor_context.run()
reports = current_actor_context.consume(Report)
assert len(reports) == 1
report_fields = reports[0].report
assert is_inhibitor(report_fields)
assert report_fields['title'] == 'Legacy network configuration with policy routing rules found'
resources = report_fields['detail']['related_resources']
assert len(resources) == 2 + len(files)
assert resources[0]['scheme'] == 'package'
assert resources[0]['title'] == 'NetworkManager'
assert resources[1]['scheme'] == 'package'
assert resources[1]['title'] == 'NetworkManager-dispatcher-routing-rules'
for i in range(len(files)):
assert resources[2 + i]['scheme'] == 'file'
assert resources[2 + i]['title'] == files[i]
Loading