Skip to content

Commit 1cbb4b9

Browse files
authored
Add a workaround around non-ascii and non-standard FQDNs (#790)
Add a wrapper around `socket.getfqdn()` which returns `invalid.hostname` in cases where hostname, or rather FQDN contains non-ascii and non-standard characters. This works around the issue that non-ascii characters can't be inserted into leapp database. For the standard for hostnames see `hostname(7)`. The current implementation doesn't check for length of hostname nor it's individual segments.
1 parent 649025b commit 1cbb4b9

File tree

3 files changed

+45
-0
lines changed

3 files changed

+45
-0
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import leapp.utils.workarounds.mp
2+
import leapp.utils.workarounds.fqdn
23

34

45
def apply_workarounds():
56
leapp.utils.workarounds.mp.apply_workaround()
7+
leapp.utils.workarounds.fqdn.apply_workaround()

leapp/utils/workarounds/fqdn.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import re
2+
import socket
3+
4+
5+
def decorate_getfqdn(fn):
6+
def wrap(*args, **kwargs):
7+
result = fn(*args, **kwargs)
8+
# check whether FQDN conforms to standard, see HOSTNAME(7)
9+
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])$"
10+
if re.match(pattern, result, re.IGNORECASE):
11+
return result
12+
return 'invalid.hostname'
13+
14+
return wrap
15+
16+
17+
def apply_workaround():
18+
setattr(socket, 'getfqdn', decorate_getfqdn(socket.getfqdn))

tests/scripts/test_workarounds_application.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
from multiprocessing import util, Process, Manager
33

44
import os
5+
import pytest
56

67
import leapp # noqa: F401; pylint: disable=unused-import
8+
from leapp.utils.workarounds import fqdn
79

810

911
def test_mp_is_patched():
@@ -29,3 +31,26 @@ def child_fun(_lst):
2931
def test_mp_workaround_applied():
3032
if getattr(util, 'os', None) is None:
3133
assert util.Finalize.__name__ == 'FixedFinalize'
34+
35+
36+
@pytest.mark.parametrize(
37+
('input_fqdn', 'valid'),
38+
[
39+
('foo.bar.com', True),
40+
('foo\xa0bar.foo.com', False),
41+
('-foo.bar', False),
42+
('foo.bar-', False),
43+
('foo.-bar.1234', False),
44+
('a1.b2.c3', True),
45+
('123.foo.bar', True),
46+
('123.f-o-o.b-a-r', True),
47+
]
48+
)
49+
def test_fqdn_is_patched(input_fqdn, valid):
50+
51+
def getfqdn():
52+
return input_fqdn
53+
54+
fn = fqdn.decorate_getfqdn(getfqdn)
55+
expected_fqdn = input_fqdn if valid else 'invalid.hostname'
56+
assert fn() == expected_fqdn

0 commit comments

Comments
 (0)