65598582f5
OBS-URL: https://build.opensuse.org/package/show/systemsmanagement:saltstack/salt?expand=0&rev=179
282 lines
11 KiB
Diff
282 lines
11 KiB
Diff
From ac34a8d839f91285f4ced605250422a1ecf5cb55 Mon Sep 17 00:00:00 2001
|
|
From: EricS <54029547+ESiebigteroth@users.noreply.github.com>
|
|
Date: Tue, 3 Sep 2019 11:22:53 +0200
|
|
Subject: [PATCH] Implement network.fqdns module function (bsc#1134860)
|
|
(#172)
|
|
|
|
* Duplicate fqdns logic in module.network
|
|
* Move _get_interfaces to utils.network
|
|
* Reuse network.fqdns in grains.core.fqdns
|
|
* Return empty list when fqdns grains is disabled
|
|
|
|
Co-authored-by: Eric Siebigteroth <eric.siebigteroth@suse.de>
|
|
---
|
|
salt/grains/core.py | 58 +++-------------------------------
|
|
salt/modules/network.py | 12 +++----
|
|
salt/utils/network.py | 2 +-
|
|
tests/unit/grains/test_core.py | 55 ++++++++++++--------------------
|
|
4 files changed, 31 insertions(+), 96 deletions(-)
|
|
|
|
diff --git a/salt/grains/core.py b/salt/grains/core.py
|
|
index 5f18ba4a58..0dc1d97f97 100644
|
|
--- a/salt/grains/core.py
|
|
+++ b/salt/grains/core.py
|
|
@@ -23,7 +23,6 @@ import uuid
|
|
import warnings
|
|
import zlib
|
|
from errno import EACCES, EPERM
|
|
-from multiprocessing.pool import ThreadPool
|
|
|
|
import distro
|
|
import salt.exceptions
|
|
@@ -2406,59 +2405,10 @@ def fqdns():
|
|
then trying to reverse resolve them (excluding 'lo' interface).
|
|
To disable the fqdns grain, set enable_fqdns_grains: False in the minion configuration file.
|
|
"""
|
|
- # Provides:
|
|
- # fqdns
|
|
-
|
|
- grains = {}
|
|
- fqdns = set()
|
|
-
|
|
- def _lookup_fqdn(ip):
|
|
- try:
|
|
- name, aliaslist, addresslist = socket.gethostbyaddr(ip)
|
|
- return [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)
|
|
-
|
|
- start = time.time()
|
|
-
|
|
- 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"
|
|
-
|
|
- # Create a ThreadPool to process the underlying calls to 'socket.gethostbyaddr' in parallel.
|
|
- # This avoid blocking the execution when the "fqdn" is not defined for certains IP addresses, which was causing
|
|
- # that "socket.timeout" was reached multiple times secuencially, blocking execution for several seconds.
|
|
-
|
|
- try:
|
|
- pool = ThreadPool(8)
|
|
- results = pool.map(_lookup_fqdn, addresses)
|
|
- pool.close()
|
|
- pool.join()
|
|
- except Exception as exc:
|
|
- log.error("Exception while creating a ThreadPool for resolving FQDNs: %s", exc)
|
|
-
|
|
- for item in results:
|
|
- if item:
|
|
- fqdns.update(item)
|
|
-
|
|
- elapsed = time.time() - start
|
|
- log.debug("Elapsed time getting FQDNs: {} seconds".format(elapsed))
|
|
-
|
|
- return {"fqdns": sorted(list(fqdns))}
|
|
+ opt = {"fqdns": []}
|
|
+ if __opts__.get("enable_fqdns_grains", True) == True:
|
|
+ opt = __salt__["network.fqdns"]()
|
|
+ return opt
|
|
|
|
|
|
def ip_fqdn():
|
|
diff --git a/salt/modules/network.py b/salt/modules/network.py
|
|
index 2e1410c288..59ed43bba6 100644
|
|
--- a/salt/modules/network.py
|
|
+++ b/salt/modules/network.py
|
|
@@ -2,7 +2,6 @@
|
|
Module for gathering and managing network information
|
|
"""
|
|
|
|
-# Import python libs
|
|
import datetime
|
|
import hashlib
|
|
import logging
|
|
@@ -12,7 +11,6 @@ import socket
|
|
import time
|
|
from multiprocessing.pool import ThreadPool
|
|
|
|
-# Import salt libs
|
|
import salt.utils.decorators.path
|
|
import salt.utils.functools
|
|
import salt.utils.network
|
|
@@ -20,8 +18,6 @@ import salt.utils.platform
|
|
import salt.utils.validate.net
|
|
from salt._compat import ipaddress
|
|
from salt.exceptions import CommandExecutionError
|
|
-
|
|
-# Import 3rd-party libs
|
|
from salt.ext.six.moves import range
|
|
|
|
log = logging.getLogger(__name__)
|
|
@@ -2076,7 +2072,10 @@ def fqdns():
|
|
|
|
def _lookup_fqdn(ip):
|
|
try:
|
|
- return [socket.getfqdn(socket.gethostbyaddr(ip)[0])]
|
|
+ name, aliaslist, addresslist = socket.gethostbyaddr(ip)
|
|
+ return [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.
|
|
@@ -2102,13 +2101,12 @@ def fqdns():
|
|
# This avoid blocking the execution when the "fqdn" is not defined for certains IP addresses, which was causing
|
|
# that "socket.timeout" was reached multiple times secuencially, blocking execution for several seconds.
|
|
|
|
- results = []
|
|
try:
|
|
pool = ThreadPool(8)
|
|
results = pool.map(_lookup_fqdn, addresses)
|
|
pool.close()
|
|
pool.join()
|
|
- except Exception as exc: # pylint: disable=broad-except
|
|
+ except Exception as exc:
|
|
log.error("Exception while creating a ThreadPool for resolving FQDNs: %s", exc)
|
|
|
|
for item in results:
|
|
diff --git a/salt/utils/network.py b/salt/utils/network.py
|
|
index d253ded3ab..25b2d06758 100644
|
|
--- a/salt/utils/network.py
|
|
+++ b/salt/utils/network.py
|
|
@@ -49,7 +49,7 @@ except (ImportError, OSError, AttributeError, TypeError):
|
|
_INTERFACES = {}
|
|
|
|
|
|
-def _get_interfaces():
|
|
+def _get_interfaces(): #! function
|
|
"""
|
|
Provide a dict of the connected interfaces and their ip addresses
|
|
"""
|
|
diff --git a/tests/unit/grains/test_core.py b/tests/unit/grains/test_core.py
|
|
index d760e57a54..a5ceeb8317 100644
|
|
--- a/tests/unit/grains/test_core.py
|
|
+++ b/tests/unit/grains/test_core.py
|
|
@@ -18,6 +18,7 @@ import salt.utils.network
|
|
import salt.utils.path
|
|
import salt.utils.platform
|
|
from salt._compat import ipaddress
|
|
+from salt.ext import six
|
|
from tests.support.mixins import LoaderModuleMockMixin
|
|
from tests.support.mock import MagicMock, Mock, mock_open, patch
|
|
from tests.support.unit import TestCase, skipIf
|
|
@@ -1293,14 +1294,14 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
|
|
):
|
|
assert core.dns() == ret
|
|
|
|
- def test_enable_fqdns_false(self):
|
|
+ def test_enablefqdnsFalse(self):
|
|
"""
|
|
tests enable_fqdns_grains is set to False
|
|
"""
|
|
with patch.dict("salt.grains.core.__opts__", {"enable_fqdns_grains": False}):
|
|
assert core.fqdns() == {"fqdns": []}
|
|
|
|
- def test_enable_fqdns_true(self):
|
|
+ def test_enablefqdnsTrue(self):
|
|
"""
|
|
testing that grains uses network.fqdns module
|
|
"""
|
|
@@ -1311,14 +1312,14 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
|
|
with patch.dict("salt.grains.core.__opts__", {"enable_fqdns_grains": True}):
|
|
assert core.fqdns() == "my.fake.domain"
|
|
|
|
- def test_enable_fqdns_none(self):
|
|
+ def test_enablefqdnsNone(self):
|
|
"""
|
|
testing default fqdns grains is returned when enable_fqdns_grains is None
|
|
"""
|
|
with patch.dict("salt.grains.core.__opts__", {"enable_fqdns_grains": None}):
|
|
assert core.fqdns() == {"fqdns": []}
|
|
|
|
- def test_enable_fqdns_without_patching(self):
|
|
+ def test_enablefqdnswithoutpaching(self):
|
|
"""
|
|
testing fqdns grains is enabled by default
|
|
"""
|
|
@@ -1326,23 +1327,7 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
|
|
"salt.grains.core.__salt__",
|
|
{"network.fqdns": MagicMock(return_value="my.fake.domain")},
|
|
):
|
|
- # fqdns is disabled by default on Windows
|
|
- if salt.utils.platform.is_windows():
|
|
- assert core.fqdns() == {"fqdns": []}
|
|
- else:
|
|
- assert core.fqdns() == "my.fake.domain"
|
|
-
|
|
- def test_enable_fqdns_false_is_proxy(self):
|
|
- """
|
|
- testing fqdns grains is disabled by default for proxy minions
|
|
- """
|
|
- with patch("salt.utils.platform.is_proxy", return_value=True, autospec=True):
|
|
- with patch.dict(
|
|
- "salt.grains.core.__salt__",
|
|
- {"network.fqdns": MagicMock(return_value="my.fake.domain")},
|
|
- ):
|
|
- # fqdns is disabled by default on proxy minions
|
|
- assert core.fqdns() == {"fqdns": []}
|
|
+ assert core.fqdns() == "my.fake.domain"
|
|
|
|
@skipIf(not salt.utils.platform.is_linux(), "System is not Linux")
|
|
@patch(
|
|
@@ -1367,11 +1352,12 @@ 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.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.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"])
|
|
|
|
@skipIf(not salt.utils.platform.is_linux(), "System is not Linux")
|
|
@patch("salt.utils.network.ip_addrs", MagicMock(return_value=["1.2.3.4"]))
|
|
@@ -1437,14 +1423,15 @@ class CoreGrainsTestCase(TestCase, LoaderModuleMockMixin):
|
|
["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"]
|
|
+ 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
|
|
+ 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):
|
|
"""
|
|
--
|
|
2.29.2
|
|
|
|
|