diff --git a/leapp/utils/workarounds/__init__.py b/leapp/utils/workarounds/__init__.py index 21627caa8..192cd75ac 100644 --- a/leapp/utils/workarounds/__init__.py +++ b/leapp/utils/workarounds/__init__.py @@ -1,5 +1,7 @@ import leapp.utils.workarounds.mp +import leapp.utils.workarounds.fqdn def apply_workarounds(): leapp.utils.workarounds.mp.apply_workaround() + leapp.utils.workarounds.fqdn.apply_workaround() diff --git a/leapp/utils/workarounds/fqdn.py b/leapp/utils/workarounds/fqdn.py new file mode 100644 index 000000000..1788e1ecc --- /dev/null +++ b/leapp/utils/workarounds/fqdn.py @@ -0,0 +1,18 @@ +import re +import socket + + +def decorate_getfqdn(fn): + def wrap(*args, **kwargs): + result = fn(*args, **kwargs) + # check whether FQDN conforms to standard, see HOSTNAME(7) + pattern = r"^(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])$" + if re.match(pattern, result, re.IGNORECASE): + return result + return 'invalid.hostname' + + return wrap + + +def apply_workaround(): + setattr(socket, 'getfqdn', decorate_getfqdn(socket.getfqdn)) diff --git a/tests/scripts/test_workarounds_application.py b/tests/scripts/test_workarounds_application.py index e6b5221ff..14149da55 100644 --- a/tests/scripts/test_workarounds_application.py +++ b/tests/scripts/test_workarounds_application.py @@ -2,8 +2,10 @@ from multiprocessing import util, Process, Manager import os +import pytest import leapp # noqa: F401; pylint: disable=unused-import +from leapp.utils.workarounds import fqdn def test_mp_is_patched(): @@ -29,3 +31,26 @@ def child_fun(_lst): def test_mp_workaround_applied(): if getattr(util, 'os', None) is None: assert util.Finalize.__name__ == 'FixedFinalize' + + +@pytest.mark.parametrize( + ('input_fqdn', 'valid'), + [ + ('foo.bar.com', True), + ('foo\xa0bar.foo.com', False), + ('-foo.bar', False), + ('foo.bar-', False), + ('foo.-bar.1234', False), + ('a1.b2.c3', True), + ('123.foo.bar', True), + ('123.f-o-o.b-a-r', True), + ] +) +def test_fqdn_is_patched(input_fqdn, valid): + + def getfqdn(): + return input_fqdn + + fn = fqdn.decorate_getfqdn(getfqdn) + expected_fqdn = input_fqdn if valid else 'invalid.hostname' + assert fn() == expected_fqdn