Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP1:Update
salt.20523
include-aliases-in-the-fqdns-grains.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File include-aliases-in-the-fqdns-grains.patch of Package salt.20523
From 3c956a1cf1de17c5c49f0856051cabe2ffb4d0f2 Mon Sep 17 00:00:00 2001 From: Bo Maryniuk <bo@suse.de> Date: Tue, 29 Jan 2019 11:11:38 +0100 Subject: [PATCH] Include aliases in the fqdns grains 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. --- salt/grains/core.py | 69 +++++++++++++++++++++----------- salt/utils/network.py | 16 ++++++++ tests/unit/grains/test_core.py | 45 ++++++++++++++++++--- tests/unit/utils/test_network.py | 37 +++++++++++++++++ 4 files changed, 138 insertions(+), 29 deletions(-) diff --git a/salt/grains/core.py b/salt/grains/core.py index bc3cf129cd..006878f806 100644 --- a/salt/grains/core.py +++ b/salt/grains/core.py @@ -1733,29 +1733,31 @@ def _parse_cpe_name(cpe): def _parse_cpe_name(cpe): - ''' + """ Parse CPE_NAME data from the os-release Info: https://csrc.nist.gov/projects/security-content-automation-protocol/scap-specifications/cpe :param cpe: :return: - ''' + """ part = { - 'o': 'operating system', - 'h': 'hardware', - 'a': 'application', + "o": "operating system", + "h": "hardware", + "a": "application", } ret = {} - cpe = (cpe or '').split(':') - if len(cpe) > 4 and cpe[0] == 'cpe': - if cpe[1].startswith('/'): # WFN to URI - ret['vendor'], ret['product'], ret['version'] = cpe[2:5] - ret['phase'] = cpe[5] if len(cpe) > 5 else None - ret['part'] = part.get(cpe[1][1:]) - elif len(cpe) == 13 and cpe[1] == '2.3': # WFN to a string - ret['vendor'], ret['product'], ret['version'], ret['phase'] = [x if x != '*' else None for x in cpe[3:7]] - ret['part'] = part.get(cpe[2]) + cpe = (cpe or "").split(":") + if len(cpe) > 4 and cpe[0] == "cpe": + if cpe[1].startswith("/"): # WFN to URI + ret["vendor"], ret["product"], ret["version"] = cpe[2:5] + ret["phase"] = cpe[5] if len(cpe) > 5 else None + ret["part"] = part.get(cpe[1][1:]) + elif len(cpe) == 13 and cpe[1] == "2.3": # WFN to a string + ret["vendor"], ret["product"], ret["version"], ret["phase"] = [ + x if x != "*" else None for x in cpe[3:7] + ] + ret["part"] = part.get(cpe[2]) return ret @@ -2396,15 +2398,36 @@ def fqdns(): """ # Provides: # fqdns - opt = {"fqdns": []} - if __opts__.get( - "enable_fqdns_grains", - False - if salt.utils.platform.is_windows() or salt.utils.platform.is_proxy() - else True, - ): - opt = __salt__["network.fqdns"]() - return opt + + grains = {} + fqdns = set() + + 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: + 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 in (0, HOST_NOT_FOUND, NO_DATA): + # No FQDN for this IP address, so we don't need to know this all the time. + log.debug("Unable to resolve address %s: %s", ip, err) + else: + log.error(err_message, ip, err) + except (OSError, socket.gaierror, socket.timeout) as err: + log.error(err_message, ip, err) + + return {"fqdns": sorted(list(fqdns))} def ip_fqdn(): diff --git a/salt/utils/network.py b/salt/utils/network.py index b3e8db3886..dd7fceb91a 100644 --- a/salt/utils/network.py +++ b/salt/utils/network.py @@ -2208,3 +2208,19 @@ def filter_by_networks(values, networks): raise ValueError("Do not know how to filter a {}".format(type(values))) else: return values + + +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(".")) + ) diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py index 7dbf34deac..d760e57a54 100644 --- a/tests/unit/grains/test_core.py +++ b/tests/unit/grains/test_core.py @@ -1367,12 +1367,11 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): ("bluesniff.foo.bar", [], ["fe80::a8b2:93ff:dead:beef"]), ] ret = {"fqdns": ["bluesniff.foo.bar", "foo.bar.baz", "rinzler.evil-corp.com"]} - with patch.dict(core.__salt__, {"network.fqdns": salt.modules.network.fqdns}): - with patch.object(socket, "gethostbyaddr", side_effect=reverse_resolv_mock): - fqdns = core.fqdns() - assert "fqdns" in fqdns - assert len(fqdns["fqdns"]) == len(ret["fqdns"]) - assert set(fqdns["fqdns"]) == set(ret["fqdns"]) + with patch.object(socket, "gethostbyaddr", side_effect=reverse_resolv_mock): + fqdns = core.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("salt.utils.network.ip_addrs", MagicMock(return_value=["1.2.3.4"])) @@ -1413,6 +1412,40 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin): mock_log.debug.assert_called_once() mock_log.error.assert_called() + @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 diff --git a/tests/unit/utils/test_network.py b/tests/unit/utils/test_network.py index 779fc0fc34..9a37a94d8f 100644 --- a/tests/unit/utils/test_network.py +++ b/tests/unit/utils/test_network.py @@ -1274,3 +1274,40 @@ class NetworkTestCase(TestCase): ), ): self.assertEqual(network.get_fqhostname(), host) + + def test_netlink_tool_remote_on(self): + with patch("subprocess.check_output", return_value=NETLINK_SS): + remotes = network._netlink_tool_remote_on("4505", "remote") + self.assertEqual(remotes, {"127.0.0.1", "::ffff:1.2.3.4"}) + + 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) -- 2.29.2
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor