Skip to content

Commit

Permalink
Include aliases in the fqdns grains
Browse files Browse the repository at this point in the history
Add UT for "is_fqdn"

Add "is_fqdn" check to the network utils

Bugfix: include FQDNs aliases

Deprecate UnitTest assertion in favour of built-in assert keyword

Add UT for fqdns aliases

Leverage cached interfaces, if any.
  • Loading branch information
Bo Maryniuk authored and brejoc committed Feb 21, 2019
1 parent 2536ee5 commit 99b56e6
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 10 deletions.
12 changes: 5 additions & 7 deletions salt/grains/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -2191,14 +2191,13 @@ def fqdns():
grains = {}
fqdns = set()

addresses = salt.utils.network.ip_addrs(include_loopback=False,
interface_data=_INTERFACES)
addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False,
interface_data=_INTERFACES))
addresses = salt.utils.network.ip_addrs(include_loopback=False, interface_data=_get_interfaces())
addresses.extend(salt.utils.network.ip_addrs6(include_loopback=False, interface_data=_get_interfaces()))
err_message = 'Exception during resolving address: %s'
for ip in addresses:
try:
fqdns.add(socket.getfqdn(socket.gethostbyaddr(ip)[0]))
name, aliaslist, addresslist = socket.gethostbyaddr(ip)
fqdns.update([socket.getfqdn(name)] + [als for als in aliaslist if salt.utils.network.is_fqdn(als)])
except socket.herror as err:
if err.errno == 0:
# No FQDN for this IP address, so we don't need to know this all the time.
Expand All @@ -2208,8 +2207,7 @@ def fqdns():
except (socket.error, socket.gaierror, socket.timeout) as err:
log.error(err_message, err)

grains['fqdns'] = sorted(list(fqdns))
return grains
return {"fqdns": sorted(list(fqdns))}


def ip_fqdn():
Expand Down
12 changes: 12 additions & 0 deletions salt/utils/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -1904,3 +1904,15 @@ def dns_check(addr, port, safe=False, ipv6=None):
raise SaltClientError()
raise SaltSystemExit(code=42, msg=err)
return resolved


def is_fqdn(hostname):
"""
Verify if hostname conforms to be a FQDN.
:param hostname: text string with the name of the host
:return: bool, True if hostname is correct FQDN, False otherwise
"""

compliant = re.compile(r"(?!-)[A-Z\d\-\_]{1,63}(?<!-)$", re.IGNORECASE)
return "." in hostname and len(hostname) < 0xff and all(compliant.match(x) for x in hostname.rstrip(".").split("."))
28 changes: 25 additions & 3 deletions tests/unit/grains/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -863,10 +863,32 @@ def test_fqdns_return(self):
ret = {'fqdns': ['bluesniff.foo.bar', 'foo.bar.baz', 'rinzler.evil-corp.com']}
with patch.object(socket, 'gethostbyaddr', side_effect=reverse_resolv_mock):
fqdns = core.fqdns()
self.assertIn('fqdns', fqdns)
self.assertEqual(len(fqdns['fqdns']), len(ret['fqdns']))
self.assertEqual(set(fqdns['fqdns']), set(ret['fqdns']))
assert "fqdns" in fqdns
assert len(fqdns['fqdns']) == len(ret['fqdns'])
assert set(fqdns['fqdns']) == set(ret['fqdns'])

@skipIf(not salt.utils.platform.is_linux(), 'System is not Linux')
@patch.object(salt.utils.platform, 'is_windows', MagicMock(return_value=False))
@patch('salt.utils.network.ip_addrs', MagicMock(return_value=['1.2.3.4', '5.6.7.8']))
@patch('salt.utils.network.ip_addrs6',
MagicMock(return_value=['fe80::a8b2:93ff:fe00:0', 'fe80::a8b2:93ff:dead:beef']))
@patch('salt.utils.network.socket.getfqdn', MagicMock(side_effect=lambda v: v)) # Just pass-through
def test_fqdns_aliases(self):
'''
FQDNs aliases
'''
reverse_resolv_mock = [('foo.bar.baz', ["throwmeaway", "this.is.valid.alias"], ['1.2.3.4']),
('rinzler.evil-corp.com', ["false-hostname", "badaliass"], ['5.6.7.8']),
('foo.bar.baz', [], ['fe80::a8b2:93ff:fe00:0']),
('bluesniff.foo.bar', ["alias.bluesniff.foo.bar"], ['fe80::a8b2:93ff:dead:beef'])]
with patch.object(socket, 'gethostbyaddr', side_effect=reverse_resolv_mock):
fqdns = core.fqdns()
assert "fqdns" in fqdns
for alias in ["this.is.valid.alias", "alias.bluesniff.foo.bar"]:
assert alias in fqdns["fqdns"]

for alias in ["throwmeaway", "false-hostname", "badaliass"]:
assert alias not in fqdns["fqdns"]
def test_core_virtual(self):
'''
test virtual grain with cmd virt-what
Expand Down
19 changes: 19 additions & 0 deletions tests/unit/utils/test_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -547,3 +547,22 @@ def test_mac_str_to_bytes(self):
self.assertRaises(ValueError, network.mac_str_to_bytes, 'a0:b0:c0:d0:e0:fg')
self.assertEqual(b'\x10\x08\x06\x04\x02\x00', network.mac_str_to_bytes('100806040200'))
self.assertEqual(b'\xf8\xe7\xd6\xc5\xb4\xa3', network.mac_str_to_bytes('f8e7d6c5b4a3'))

def test_is_fqdn(self):
"""
Test is_fqdn function passes possible FQDN names.
:return: None
"""
for fqdn in ["host.domain.com", "something.with.the.dots.still.ok", "UPPERCASE.ALSO.SHOULD.WORK",
"MiXeD.CaSe.AcCePtAbLe", "123.host.com", "host123.com", "some_underscore.com", "host-here.com"]:
assert network.is_fqdn(fqdn)

def test_is_not_fqdn(self):
"""
Test is_fqdn function rejects FQDN names.
:return: None
"""
for fqdn in ["hostname", "/some/path", "$variable.here", "verylonghostname.{}".format("domain" * 45)]:
assert not network.is_fqdn(fqdn)

0 comments on commit 99b56e6

Please sign in to comment.