mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #39289 from bobrik/autodetect-ipv6
Autodetect IPv6 connectivity from minion to master
This commit is contained in:
commit
c10965833a
6 changed files with 37 additions and 17 deletions
|
@ -81,9 +81,10 @@ The option can can also be set to a list of masters, enabling
|
|||
``ipv6``
|
||||
--------
|
||||
|
||||
Default: ``False``
|
||||
Default: ``None``
|
||||
|
||||
Whether the master should be connected over IPv6.
|
||||
Whether the master should be connected over IPv6. By default salt minion
|
||||
will try to automatically detect IPv6 connectivity to master.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
|
|
@ -990,7 +990,7 @@ DEFAULT_MINION_OPTS = {
|
|||
'mine_interval': 60,
|
||||
'ipc_mode': _DFLT_IPC_MODE,
|
||||
'ipc_write_buffer': _DFLT_IPC_WBUFFER,
|
||||
'ipv6': False,
|
||||
'ipv6': None,
|
||||
'file_buffer_size': 262144,
|
||||
'tcp_pub_port': 4510,
|
||||
'tcp_pull_port': 4511,
|
||||
|
|
|
@ -132,7 +132,7 @@ log = logging.getLogger(__name__)
|
|||
# 6. Handle publications
|
||||
|
||||
|
||||
def resolve_dns(opts, fallback=True):
|
||||
def resolve_dns(opts, fallback=True, connect=True):
|
||||
'''
|
||||
Resolves the master_ip and master_uri options
|
||||
'''
|
||||
|
@ -149,13 +149,13 @@ def resolve_dns(opts, fallback=True):
|
|||
if opts['master'] == '':
|
||||
raise SaltSystemExit
|
||||
ret['master_ip'] = \
|
||||
salt.utils.dns_check(opts['master'], True, opts['ipv6'])
|
||||
salt.utils.dns_check(opts['master'], opts['master_port'], True, opts['ipv6'], connect)
|
||||
except SaltClientError:
|
||||
if opts['retry_dns']:
|
||||
while True:
|
||||
import salt.log
|
||||
msg = ('Master hostname: \'{0}\' not found. Retrying in {1} '
|
||||
'seconds').format(opts['master'], opts['retry_dns'])
|
||||
msg = ('Master hostname: \'{0}\' not found or not responsive. '
|
||||
'Retrying in {1} seconds').format(opts['master'], opts['retry_dns'])
|
||||
if salt.log.setup.is_console_configured():
|
||||
log.error(msg)
|
||||
else:
|
||||
|
@ -163,7 +163,7 @@ def resolve_dns(opts, fallback=True):
|
|||
time.sleep(opts['retry_dns'])
|
||||
try:
|
||||
ret['master_ip'] = salt.utils.dns_check(
|
||||
opts['master'], True, opts['ipv6']
|
||||
opts['master'], opts['master_port'], True, opts['ipv6'], connect
|
||||
)
|
||||
break
|
||||
except SaltClientError:
|
||||
|
|
|
@ -346,7 +346,7 @@ class AsyncZeroMQPubChannel(salt.transport.mixins.auth.AESPubClientMixin, salt.t
|
|||
zmq.RECONNECT_IVL_MAX, self.opts['recon_max']
|
||||
)
|
||||
|
||||
if self.opts['ipv6'] is True and hasattr(zmq, 'IPV4ONLY'):
|
||||
if (self.opts['ipv6'] is True or ':' in self.opts['master_ip']) and hasattr(zmq, 'IPV4ONLY'):
|
||||
# IPv6 sockets work for both IPv6 and IPv4 addresses
|
||||
self._socket.setsockopt(zmq.IPV4ONLY, 0)
|
||||
|
||||
|
|
|
@ -716,10 +716,11 @@ def ip_bracket(addr):
|
|||
return addr
|
||||
|
||||
|
||||
def dns_check(addr, safe=False, ipv6=False):
|
||||
def dns_check(addr, port, safe=False, ipv6=None, connect=True):
|
||||
'''
|
||||
Return the ip resolved by dns, but do not exit on failure, only raise an
|
||||
exception. Obeys system preference for IPv4/6 address resolution.
|
||||
Tries to connect to the address before considering it useful.
|
||||
'''
|
||||
error = False
|
||||
try:
|
||||
|
@ -732,12 +733,30 @@ def dns_check(addr, safe=False, ipv6=False):
|
|||
if not hostnames:
|
||||
error = True
|
||||
else:
|
||||
addr = False
|
||||
resolved = False
|
||||
for h in hostnames:
|
||||
if h[0] == socket.AF_INET or (h[0] == socket.AF_INET6 and ipv6):
|
||||
addr = ip_bracket(h[4][0])
|
||||
if h[0] == socket.AF_INET and ipv6 is True:
|
||||
continue
|
||||
if h[0] == socket.AF_INET6 and ipv6 is False:
|
||||
continue
|
||||
if h[0] == socket.AF_INET6 and connect is False and ipv6 is None:
|
||||
continue
|
||||
|
||||
candidate_addr = ip_bracket(h[4][0])
|
||||
|
||||
if not connect:
|
||||
resolved = candidate_addr
|
||||
|
||||
s = socket.socket(h[0], socket.SOCK_STREAM)
|
||||
try:
|
||||
s.connect((candidate_addr.strip('[]'), port))
|
||||
s.close()
|
||||
|
||||
resolved = candidate_addr
|
||||
break
|
||||
if not addr:
|
||||
except socket.error:
|
||||
pass
|
||||
if not resolved:
|
||||
error = True
|
||||
except TypeError:
|
||||
err = ('Attempt to resolve address \'{0}\' failed. Invalid or unresolveable address').format(addr)
|
||||
|
@ -746,7 +765,7 @@ def dns_check(addr, safe=False, ipv6=False):
|
|||
error = True
|
||||
|
||||
if error:
|
||||
err = ('DNS lookup of \'{0}\' failed.').format(addr)
|
||||
err = ('DNS lookup or connection check of \'{0}\' failed.').format(addr)
|
||||
if safe:
|
||||
if salt.log.is_console_configured():
|
||||
# If logging is not configured it also means that either
|
||||
|
@ -755,7 +774,7 @@ def dns_check(addr, safe=False, ipv6=False):
|
|||
log.error(err)
|
||||
raise SaltClientError()
|
||||
raise SaltSystemExit(code=42, msg=err)
|
||||
return addr
|
||||
return resolved
|
||||
|
||||
|
||||
def required_module_list(docstring=None):
|
||||
|
|
|
@ -364,7 +364,7 @@ class ConfigTestCase(TestCase, integration.AdaptedConfigurationTestCaseMixIn):
|
|||
syndic_opts = sconfig.syndic_config(
|
||||
syndic_conf_path, minion_conf_path
|
||||
)
|
||||
syndic_opts.update(salt.minion.resolve_dns(syndic_opts))
|
||||
syndic_opts.update(salt.minion.resolve_dns(syndic_opts, connect=False))
|
||||
root_dir = syndic_opts['root_dir']
|
||||
# id & pki dir are shared & so configured on the minion side
|
||||
self.assertEqual(syndic_opts['id'], 'minion')
|
||||
|
|
Loading…
Add table
Reference in a new issue